New Metadataplayer version V01.73
authorRaphael Velt <raph.velt@gmail.com>
Thu, 03 May 2012 17:52:07 +0200
changeset 598 d366aa22bd79
parent 597 07ab28bca482
child 599 42bce53bd476
New Metadataplayer version
web/common.php
web/polemicaltimeline.php
web/res/css/imgs/black.png
web/res/css/imgs/black_arrow.png
web/res/css/imgs/black_arrow_big.png
web/res/css/imgs/black_big.png
web/res/css/imgs/delicious.png
web/res/css/imgs/facebook.png
web/res/css/imgs/grey_arrow_Show.png
web/res/css/imgs/linkedin.png
web/res/css/imgs/loader.gif
web/res/css/imgs/loader_fc.gif
web/res/css/imgs/loader_fc2.gif
web/res/css/imgs/purple_arrow_Show.png
web/res/css/imgs/transBlack.png
web/res/css/imgs/twitter.png
web/res/css/imgs/white.png
web/res/css/imgs/white_arrow.png
web/res/css/imgs/white_arrow_big.png
web/res/css/imgs/white_arrow_mini.png
web/res/css/imgs/white_big.png
web/res/css/imgs/widget20.png
web/res/css/metadataplayer/LdtPlayer.css
web/res/css/metadataplayer/imgs/annotate_arrow.png
web/res/css/metadataplayer/imgs/arrow.png
web/res/css/metadataplayer/imgs/black.png
web/res/css/metadataplayer/imgs/black_arrow.png
web/res/css/metadataplayer/imgs/black_arrow_big.png
web/res/css/metadataplayer/imgs/black_big.png
web/res/css/metadataplayer/imgs/delicious.png
web/res/css/metadataplayer/imgs/facebook.png
web/res/css/metadataplayer/imgs/facebook_button.png
web/res/css/metadataplayer/imgs/google.png
web/res/css/metadataplayer/imgs/gplus_button.png
web/res/css/metadataplayer/imgs/grey_arrow_Show.png
web/res/css/metadataplayer/imgs/left_edge_arrow.png
web/res/css/metadataplayer/imgs/left_handle.gif
web/res/css/metadataplayer/imgs/linkedin.png
web/res/css/metadataplayer/imgs/loader.gif
web/res/css/metadataplayer/imgs/minimize.png
web/res/css/metadataplayer/imgs/player-sprites.png
web/res/css/metadataplayer/imgs/player_gradient.png
web/res/css/metadataplayer/imgs/polemic_buttons_sprite.png
web/res/css/metadataplayer/imgs/profile_arrow.png
web/res/css/metadataplayer/imgs/purple_arrow_Show.png
web/res/css/metadataplayer/imgs/reply_sprite.png
web/res/css/metadataplayer/imgs/retweet_sprite.png
web/res/css/metadataplayer/imgs/right_edge_arrow.png
web/res/css/metadataplayer/imgs/right_handle.gif
web/res/css/metadataplayer/imgs/spinner.gif
web/res/css/metadataplayer/imgs/submit_annotation.png
web/res/css/metadataplayer/imgs/transBlack.png
web/res/css/metadataplayer/imgs/tweet_button.png
web/res/css/metadataplayer/imgs/twitter.png
web/res/css/metadataplayer/imgs/user_default_icon.png
web/res/css/metadataplayer/imgs/video_sequence.png
web/res/css/metadataplayer/imgs/white.png
web/res/css/metadataplayer/imgs/white_arrow.png
web/res/css/metadataplayer/imgs/white_arrow_big.png
web/res/css/metadataplayer/imgs/white_arrow_long.png
web/res/css/metadataplayer/imgs/white_arrow_mini.png
web/res/css/metadataplayer/imgs/white_big.png
web/res/css/metadataplayer/imgs/widget20.png
web/res/css/metadataplayer/imgs/wire_pattern.png
web/res/css/tweetcast.css
web/res/js/LdtPlayer-release.js
web/res/js/mustache.js
web/res/js/raphael-min.js
web/res/js/raphael.js
web/res/metadataplayer/Annotation.css
web/res/metadataplayer/Annotation.js
web/res/metadataplayer/AnnotationsList.css
web/res/metadataplayer/AnnotationsList.js
web/res/metadataplayer/Arrow.js
web/res/metadataplayer/Controller.css
web/res/metadataplayer/Controller.js
web/res/metadataplayer/LdtPlayer-core.css
web/res/metadataplayer/LdtPlayer-core.js
web/res/metadataplayer/Mediafragment.js
web/res/metadataplayer/Polemic.css
web/res/metadataplayer/Polemic.js
web/res/metadataplayer/Segments.css
web/res/metadataplayer/Segments.js
web/res/metadataplayer/Slider.css
web/res/metadataplayer/Slider.js
web/res/metadataplayer/Tagcloud.css
web/res/metadataplayer/Tagcloud.js
web/res/metadataplayer/Tooltip.css
web/res/metadataplayer/Tooltip.js
web/res/metadataplayer/Trace.js
web/res/metadataplayer/Tweet.css
web/res/metadataplayer/Tweet.js
web/res/metadataplayer/img/loader.gif
web/res/metadataplayer/img/pinstripe-grey.png
web/res/metadataplayer/img/pinstripe.png
web/res/metadataplayer/img/player-sprites.png
web/res/metadataplayer/img/player_gradient.png
web/res/metadataplayer/img/slice-handles.png
web/res/metadataplayer/img/socialbuttons.png
web/res/metadataplayer/img/twitter_sprites.png
web/res/metadataplayer/img/white_arrow_long.png
web/res/metadataplayer/img/widget-control.png
--- a/web/common.php	Wed May 02 19:19:51 2012 +0200
+++ b/web/common.php	Thu May 03 17:52:07 2012 +0200
@@ -177,7 +177,7 @@
 	'local' => array(
 	    'libdir'        => URL_ROOT.'res/js/',
 	    'jquery' 		=> URL_ROOT.'res/js/jquery-1.4.3.min.js',
-	    'raphael' 		=> URL_ROOT.'res/js/raphael.js',
+	    'raphael' 		=> URL_ROOT.'res/js/raphael-min.js',
 	    'jquery-ui' 	=> URL_ROOT.'res/js/jquery-ui-1.8.13.min.js',
 	    'niceforms' 	=> URL_ROOT.'res/js/niceforms.js',
 	    'jquery-url' 	=> URL_ROOT.'res/js/jquery.url.js',
@@ -192,12 +192,13 @@
         'jquery-scrollto'=>URL_ROOT.'res/js/jquery.scrollTo-1.4.2-min.js' ,
         'twcx-main'     => URL_ROOT.'res/js/live-polemic.js' ,
         'semanticboard' => URL_ROOT.'res/js/semanticboard.js' ,
-        'metadataplayer'=> URL_ROOT.'res/js/LdtPlayer-release.js' ,
+        'metadataplayer'=> URL_ROOT.'res/metadataplayer/LdtPlayer-core.js' ,
+        'ldtwidgets'    => URL_ROOT.'res/metadataplayer/' ,
 	),
 	'cdn' => array(
         'libdir'        => URL_ROOT.'res/js/',
 	    'jquery' 		=> 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js',
-		'raphael' 		=> URL_ROOT.'res/js/raphael.js',
+		'raphael' 		=> URL_ROOT.'res/js/raphael-min.js',
 		'jquery-ui' 	=> 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js',
 		'niceforms' 	=> URL_ROOT.'res/js/niceforms.js',
 		'jquery-url' 	=> URL_ROOT.'res/js/jquery.url.js',
@@ -212,7 +213,8 @@
         'jquery-scrollto'=>URL_ROOT.'res/js/jquery.scrollTo-1.4.2-min.js' ,
         'twcx-main'     => URL_ROOT.'res/js/live-polemic.js' ,
         'semanticboard' => URL_ROOT.'res/js/semanticboard.js' ,
-        'metadataplayer'=> URL_ROOT.'res/js/LdtPlayer-release.js' ,
+        'metadataplayer'=> URL_ROOT.'res/metadataplayer/LdtPlayer-core.js' ,
+        'ldtwidgets'    => URL_ROOT.'res/metadataplayer/' ,
 		
 	)
 );
@@ -242,7 +244,7 @@
 		'tweetcast' => URL_ROOT.'res/css/tweetcast.css',
 		'semanticboard' =>  URL_ROOT.'res/css/semanticboard.css',
         'archives-iframe' => URL_ROOT.'res/css/archives-iframe.css',
-        'metadataplayer' => URL_ROOT.'res/css/metadataplayer/LdtPlayer.css',
+        'metadataplayer' => URL_ROOT.'res/metadataplayer/LdtPlayer-core.css',
 	),
 	'cdn' => array(
 		'blueprint-screen' => URL_ROOT.'res/css/blueprint-screen.css',
@@ -256,7 +258,7 @@
         'tweetcast' => URL_ROOT.'res/css/tweetcast.css',
         'semanticboard' =>  URL_ROOT.'res/css/semanticboard.css',
         'archives-iframe' => URL_ROOT.'res/css/archives-iframe.css',
-        'metadataplayer' => URL_ROOT.'res/css/metadataplayer/LdtPlayer.css',
+        'metadataplayer' => URL_ROOT.'res/metadataplayer/LdtPlayer-core.css',
 	)
 );
 
--- a/web/polemicaltimeline.php	Wed May 02 19:19:51 2012 +0200
+++ b/web/polemicaltimeline.php	Thu May 03 17:52:07 2012 +0200
@@ -60,102 +60,78 @@
 	
 	<script type="text/javascript">
   		// Configuration Polemical Timeline
-  		if (typeof jQuery == "undefined") {
-  		    jQuery = IriSP.jQuery;
-  		}
-  		<?php
-      		if(is_array($translate->_('config__metadata'))):
-  			reset($translate->_('config__metadata'));
-  		    $first_key = key($translate->_('config__metadata'));
-  		?>
-  		var metadatas = jQuery.parseJSON('<?php echo(json_encode($translate->_('config__metadata'))); ?>');
-  		var url = jQuery.url();
-  		var metadata_key = url.fparam('metadata');
-  		if(typeof metadata_key === "undefined" || metadata_key.length === 0) {
-  			metadata_key = "<?php echo($first_key);?>";
-  		}
-  		<?php else: ?>
-  		var metadatas = { metadata: {url: "<?php echo($translate->_('config__metadata'));?>"} };
-  		var metadata_key = "metadata";
-  		<?php endif;?>
+	if (typeof jQuery == "undefined") {
+	    jQuery = IriSP.jQuery;
+	}
+	<?php
+  		if(is_array($translate->_('config__metadata'))):
+		reset($translate->_('config__metadata'));
+	    $first_key = key($translate->_('config__metadata'));
+	?>
+	var metadatas = jQuery.parseJSON('<?php echo(json_encode($translate->_('config__metadata'))); ?>');
+	var url = jQuery.url();
+	var metadata_key = url.fparam('metadata');
+	if(typeof metadata_key === "undefined" || metadata_key.length === 0) {
+		metadata_key = "<?php echo($first_key);?>";
+	}
+	<?php else: ?>
+	var metadatas = { metadata: {url: "<?php echo($translate->_('config__metadata'));?>"} };
+	var metadata_key = "metadata";
+	<?php endif;?>
+  		
+	
     IriSP.libFiles.defaultDir = "<?php echo(registry_url('libdir','js'));?>";
+    IriSP.widgetsDir = "<?php echo(registry_url('ldtwidgets','js'));?>";
     IriSP.jwplayer_swf_path = "<?php echo(URL_ROOT); ?>res/mediaplayer/player.swf";
-    IriSP.language = "<?php echo($actual) ?>"
-    var json_url = metadatas[metadata_key].url;
-
-    var config = {            
-        gui:{
-            width:650,
-            height:800,              
-            container:'LdtPlayer',
+    IriSP.language = "<?php echo($actual) ?>";
+    
+    var _metadata = {
+        url: metadatas[metadata_key].url + '?callback=?',
+        format: 'ldt'
+    };
+    var _config = {            
+        gui: {
+            width: 600,
+            height: 800,
+            container: 'LdtPlayer',
+            default_options: {
+                metadata: _metadata
+            },
             css:'<?php echo(registry_url('metadataplayer','css'));?>',
-            default_options : {
-                metadata:{
-                format:'cinelab',
-                src: json_url,
-                type:'json'},
-                width: 650
-            },
             widgets: [
-            {
-                type: "PolemicWidget",
-                requires: [{
-                    type: "TooltipWidget",
-                    width: 180,
-                    height: 160,
-                    metadata : {
-                        type:'empty'
-                    }
-                }],
-                height: 5
-            },
-            {type: "SliderWidget"},        
-            {type: "PlayerWidget", // please note that type refers directly to the constructor of the widget.
-             mode: "radio",
-             disable_annotate_btn: true},
-            {type: "SegmentsWidget",
-             requires: [{
-              type: "TooltipWidget",
-              width: 180,
-              height: 160,
-              }],
-                width: 650
-            },                      
-            {type: "ArrowWidget"},
-            {type: "TweetsWidget"},
-            {type: "AnnotationsWidget"},
-            {type: "AnnotationsListWidget",
-             container: "AnnotationsListContainer",
-             ajax_mode: false},
-            {type: "TagCloudWidget",
-             container: "TagcloudContainer",
-        <?php if (isset($config['hashtag'])) echo "excludeWords: ".json_encode(array($config['hashtag'])).","; ?>
-            excludePattern: /^@/
-        },{
-            type: "TraceWidget",
-         //   js_console : true,
-            url: "http://traces.advene.org:5000/",
-            requestmode: 'GET',
-            syncmode: "sync"
+                { type: "Polemic" },
+                { type: "Slider" },
+                {
+                    type: "Controller",
+                    disable_annotate_btn: true
+                },
+                { type: "Segments" },
+                { type: "Arrow" },
+                { type: "Annotation" },
+                { type: "Tweet" },
+                {
+                    type: "Tagcloud",
+                    container: "TagcloudContainer",
+                    exclude_pattern: /^@/,
+                    custom_stopwords: <?php echo json_encode(array($config['hashtag'])) ?>
+                },
+                {
+                    type: "AnnotationsList",
+                    //ajax_url : "http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?", 
+                    //foreign_url : "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}",
+                    container: "AnnotationsListContainer"
+                },
+                { type: "Mediafragment"},
+            ]
+        },
+        player:{
+            type:'jwplayer', // player type
+            live: true, 
+            height: 360, 
+            width: 600, 
+            provider: "rtmp",
+            autostart: true
         }
-        ]
-        },
-      player:{
-          type:'jwplayer',
-          live: true, 
-          height: 400, 
-          width: 650, 
-          provider: "rtmp",
-          autostart: true
-      },
-      modules: [
-               { type: "MediaFragment",
-                         metadata:{
-                       format:'cinelab',
-                           src:json_url,
-                             type:'json'}
-                        }]
-
     };
 
 		jQuery(document).ready(function() {
@@ -293,7 +269,7 @@
                 <h3>Mots-clés</h3>
             </li>
             <li class="acctexte" style="display: none;">
-                <div class="tagcloud" id="TagcloudContainer"></div>
+                <div id="TagcloudContainer"></div>
             </li>
         </ul>
 		
@@ -314,7 +290,7 @@
 		<div id="LdtPlayer"></div>
 	  </div>
 <script type="text/javascript">
-    IriSP.initPlayer(config, json_url);
+    var _myPlayer = new IriSP.Metadataplayer(_config, _metadata);
 </script>
   </div>
  
Binary file web/res/css/imgs/black.png has changed
Binary file web/res/css/imgs/black_arrow.png has changed
Binary file web/res/css/imgs/black_arrow_big.png has changed
Binary file web/res/css/imgs/black_big.png has changed
Binary file web/res/css/imgs/delicious.png has changed
Binary file web/res/css/imgs/facebook.png has changed
Binary file web/res/css/imgs/grey_arrow_Show.png has changed
Binary file web/res/css/imgs/linkedin.png has changed
Binary file web/res/css/imgs/loader.gif has changed
Binary file web/res/css/imgs/loader_fc.gif has changed
Binary file web/res/css/imgs/loader_fc2.gif has changed
Binary file web/res/css/imgs/purple_arrow_Show.png has changed
Binary file web/res/css/imgs/transBlack.png has changed
Binary file web/res/css/imgs/twitter.png has changed
Binary file web/res/css/imgs/white.png has changed
Binary file web/res/css/imgs/white_arrow.png has changed
Binary file web/res/css/imgs/white_arrow_big.png has changed
Binary file web/res/css/imgs/white_arrow_mini.png has changed
Binary file web/res/css/imgs/white_big.png has changed
Binary file web/res/css/imgs/widget20.png has changed
--- a/web/res/css/metadataplayer/LdtPlayer.css	Wed May 02 19:19:51 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,968 +0,0 @@
-/* Some general styling classes */
-
-.Ldt-floatClear {
-    display: block; width: 100%; height: 0; clear: both;
-}
-
-ul.Ldt-floatList {
-    padding: 0; margin: 0; list-style: none;
-}
-
-.Ldt-floatList li {
-    float: left;
-}
-
-
-/* */
-
-#demo-frame > div.demo { padding: 5px !important; };
-
-button.ui-button-icon-only  {
-  height:1.5em;
-  width:1.5em;
-}
-
-#Ldt-loader {
-    background:url(imgs/loader.gif) center no-repeat;
-    text-indent: -9999px;
-    position: absolute;
-}
-
-/* general class for all buttons */
-.Ldt-button {
-
-}
-
-.Ldt-SegmentsWidget {
- /* overflow: auto; /* clear the floats */
-  margin-top: 1px;
-  padding-bottom: 8px; /* FIXME: only a temporary fix. This should be put into the layout manager. */
-}
-
-.Ldt-iri-chapter {
-  position: absolute;
-  height: 10px;
-  border-right: 1px solid white;
-}
-
-.Ldt-SegmentPositionMarker {
-  position: absolute;
-  z-index: 100;
-  width: 1px;
-  height: 10px;
-  background-color: white;
-}
-.tooltip {
-  display:none;
-  background:transparent url(imgs/white_arrow_mini.png);
-  font-size:12px;
-  height:55px;
-  width:180px;
-  padding:10px;
-  padding-left:15px;
-  padding-top:15px;
-  padding-right:15px;
-  color:#000;
-  font-family: "Trebuchet MS", "Helvetica", "Arial",  "Verdana", "sans-serif";
-}
-#Ldt-Root{
-  font-family: "Trebuchet MS", "Helvetica", "Arial",  "Verdana", "sans-serif";
-}
-#Ldt-Hat{
-  height:3px;
-}
-
-.Ldt-AnnotationsWidget {
-  font-size: 12px;
-  font-family: "Arial",  "Verdana", "sans-serif";
-  background-color:#eeeeee;
-  background:url('imgs/wire_pattern.png') repeat scroll transparent ;
-  border: 1px solid #b6b8b8;
-}
-
-.Ldt-Annotation-DoubleBorder {
-  border: 1px solid white;
-  overflow: auto;
-}
-
-.Ldt-AnnotationContent {
-  padding:5px;
-  padding-left: 12px;
-
-}
-
-.Ldt-fbShare {
-  display: block;
-  float: left;
-  width: 24px;
-  height: 24px;
-  background:url('imgs/facebook.png');
-}
-
-.Ldt-TwShare {
-  display: block;
-  float: left;
-  width: 24px;
-  height: 24px;
-  background:url('imgs/twitter.png');
-}
-
-.Ldt-GplusShare {
-  display: block;
-  float: left;
-  width: 24px;
-  height: 24px;
-  background:url('imgs/google.png');
-}
-
-.Ldt-SaTitle{
-  padding-top:2px;
-  padding-bottom:3px;
-  font-size: 12pt;
-  color : #0068c4;
-}
-
-.Ldt-SaDescription{
-  font-size:12px;
-}
-
-.Ldt-SaKeywords {  
-  font-weight:bold;  
-  font-size:10px;
-}
-
-.Ldt-AnnotationShareIcons {
-  float:right;
-  position: relative;
-}
-
-
-#Ldt-PlaceHolder{
-  position:absolue;
-  float:none;
-}
-
-.Ldt-Segments{
-  float:left;
-  font-size: 62.5%;
-}
-
-.Ldt-mode-radio{
-  visibility:hidden;
-  height:0px;
-  display:none
-}
-
-/* player */
-.Ldt-controler {
-  font-size: 10px;
-  font-family: "Trebuchet MS", "Helvetica", "Arial",  "Verdana", "sans-serif";
-  background:url('imgs/player_gradient.png') repeat-x transparent ;
-  height: 25px;
-  border: 1px solid #b6b8b8;
-  position: relative;
-}
-
-
-.Ldt-LeftPlayerControls {
-  float:left;
-}
-
-.Ldt-RightPlayerControls {
-  float: right;
-}
-
-.Ldt-Ctrl-button {
-  float: left;
-  width: 30px; height: 25px;
-  background: url('imgs/player-sprites.png');
-  cursor: pointer;
-}
-
-.Ldt-Ctrl-spacer {
-    float: left; width: 1px; height: 25px; background: #b6b8b8;
-}
-
-.Ldt-CtrlPlay {
-  margin: 0 15px;
-}
-
-.Ldt-CtrlPlay-PlayState {
-  background-position: 0 0;
-}
-
-.Ldt-CtrlPlay-PlayState:hover {
-  background-position: 0 -25px;
-}
-
-.Ldt-CtrlPlay-PlayState:active {
-  background-position: 0 -50px;
-}
-
-.Ldt-CtrlPlay-PauseState {
-  background-position: -30px 0;
-}
-
-.Ldt-CtrlPlay-PauseState:hover {
-  background-position: -30px -25px;
-}
-
-.Ldt-CtrlPlay-PauseState:active {
-  background-position: -30px -50px;
-}
-
-
-.Ldt-CtrlAnnotate {
-  margin: 0 2px;
-  background-position: -60px 0;
-}
-
-.Ldt-CtrlAnnotate:hover {
-  background-position: -60px -25px;
-}
-
-.Ldt-CtrlAnnotate:active {
-  background-position: -60px -50px;
-}
-
-.Ldt-CtrlSearch {
-  margin: 0 2px;
-  background-position: -90px 0;
-}
-
-.Ldt-CtrlSearch:hover {
-  background-position: -90px -25px;
-}
-
-.Ldt-CtrlSearch:active {
-  background-position: -90px -50px;
-}
-
-.LdtSearch {
-  display: none;
-  width: 165px;
-  height: 25px;
-  border: 1px;
-  border-color: #CFCFCF;
-  float: left;
-  text-align: center;
-}
-
-.Ldt-Time {
-  float: left;
-  margin: 5px;
-  font-size: 12px;
-  font-family: Arial, Verdana, sans-serif;
-}
-
-.Ldt-ElapsedTime {
-  float: left;
-  color: #4a4a4a;
-}
-
-.Ldt-TimeSeparator {
-  margin: 0 4px;      
-  float: left;
-}
-
-.Ldt-TotalTime {
-  float: left;
-  color: #b2b2b2; 
-}
-
-.Ldt-CtrlSound {
-  margin: 0 2px;
-}
-
-.Ldt-CtrlSound-Full {
-  background-position: -120px 0;
-}
-
-.Ldt-CtrlSound-Full:hover {
-  background-position: -120px -25px;
-}
-
-.Ldt-CtrlSound-Full:active {
-  background-position: -120px -50px;
-}
-
-.Ldt-CtrlSound-Mute {
-  background-position: -150px 0;
-}
-
-.Ldt-CtrlSound-Mute:hover {
-  background-position: -150px -25px;
-}
-
-.Ldt-CtrlSound-Mute:active {
-  background-position: -150px -50px;
-}
-
-.Ldt-CtrlSound-Half {
-  background-position: -180px 0;
-}
-
-.Ldt-CtrlSound-Half:hover {
-  background-position: -180px -25px;
-}
-
-.Ldt-CtrlSound-Half:active {
-  background-position: -180px -50px;
-}
-
-.Ldt-Ctrl-Volume-Control {
-    display: none;
-  position: absolute;
-  background:url('imgs/player_gradient.png') repeat-x transparent ;
-  height: 25px;
-  width: 100px; top: 25px; right: -1px; z-index: 100;
-  padding: 0 2px;
-  border: 1px solid #b6b8b8;
-}
-
-.Ldt-Ctrl-Volume-Bar { 
-    height: 5px; margin: 9px 3px 0; background: #cccccc; border: 1px solid #999999; border-radius: 2px;
-}
-
-.Ldt-Ctrl-Volume-Cursor {
-    position: absolute; top: 2px; width: 6px; height: 19px; background: #a8a8a8; border: 1px solid #999999; border-radius: 2px;
-    cursor: pointer;
-}
-
-.Ldt-Ctrl-Volume-Control:hover .Ldt-Ctrl-Volume-Cursor {
-     background: #F7268E;
-}
-
-.Ldt-cleaner {
-  clear:both;
-}
-
-/* Arrow Widget */
-.Ldt-arrowWidget {
-  position: relative;
-
-  height:16px;
-  width:27px;
-  margin-bottom: -3px;
-  z-index: 4;
-  left: 0%;
-}
-
-.Ldt-arrowLeftEdge {
-  background:url('imgs/left_edge_arrow.png') no-repeat scroll 0 0 transparent ;
-}
-
-.Ldt-arrowCenter {
-  background:url('imgs/arrow.png') no-repeat scroll 0 0 transparent ;
-}
-
-.Ldt-arrowRightEdge {
-  background:url('imgs/right_edge_arrow.png') no-repeat scroll 0 0 transparent ;
-}
-
-.cleaner {
-  clear:both;
-}
-
-.share {
-  background:url('imgs/widget20.png') no-repeat scroll 0 0 transparent ;
-  display:block;
-  height:16px;
-  line-height:16px !important;
-  overflow:hidden;
-  width:16px;
-  float:left;
-  cursor:pointer;
-  margin:2px;
-}
-.shareFacebook{
-  background-position:0 -704px;
-}
-.shareMySpace{
-  background-position:0 -736px;
-}
-.shareTwitter{
-  background-position:0 -1072px;
-}
-.shareGoogle{
-  background-position:0 -752px;
-}
-.shareDelicious{
-  background-position:0 -672px;
-}
-.shareJamesPot{
-  background-position:0 -1808px;
-}
-
-.tip{
-  position: absolute;
-  padding : 3px;
-  z-index: 10000000000;
-  max-width: 200px;
-  background: transparent url("imgs/white_arrow_long.png");
-  font-size: 12px;
-  height: 115px;
-  width: 180px;
-  padding: 15px 15px 20px;
-  color: black;
-  font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
-  overflow:hidden;
-}
-
-.tipcolor {
-    float: left; margin: 2px 4px 2px 0;
-}
-
-.tip img {
-    max-width: 140px; max-height: 70px; margin: 0 20px;
-}
-
-/* slider */
-.Ldt-SliderMinimized {
-  height: 6px;
-}
-
-.Ldt-SliderMaximized {
-  height: 11px;
-}
-
-.Ldt-sliderElementMinimized {
-  width: 100%;
-  height: 5px;
-}
-
-.Ldt-sliderElementMaximized {
-  width: 100%;
-  height: 10px;
-}
-
-.Ldt-sliderBackground  {
-  background-color: #B6B8B8;
-  position: absolute;
-  z-index: 2;
-  bottom: 1px;
-  width: 100%;
-  height: 5px;
-
-}
-
-.Ldt-sliderForeground  {
-  background-color: #747474;
-  z-index: 2;
-  width: 0px;
-  position: absolute;
-  bottom: 1px;
-  height: 5px;
-}
-
-.Ldt-sliderPositionMarker {
-  position: absolute;
-  z-index: 100;
-  background-color: #f7268e;
-  height: 5px;
-  width: 5px;
-  bottom: 1px;
-  border-left: 1px solid white;
-  border-right: 1px solid white;
-}
-
-/* tweet Widget */
-.Ldt-tweetWidget {
-  font-size: 12px;
-  font-family: "Arial",  "Verdana", "sans-serif";
-  background:url('imgs/wire_pattern.png') repeat scroll transparent ;
-  border: 1px solid #b6b8b8;
-  border-top: none;
-  overflow: auto;
-}
-
-.Ldt-tweet-DoubleBorder {
-  border: 1px solid white;
-  padding: 5px;
-  overflow: auto;
-}
-
-.Ldt-tweetAvatar {
-  float: left;
-}
-
-.Ldt-tweetAvatar-profileArrow {
-  float: left;
-  height: 48px;
-  margin-left: 5px;
-  margin-right: 5px;
-  background:url('imgs/profile_arrow.png');
-  background-position: 7 10px;
-}
-
-.Ldt-tweet_userHandle {
-   float: left;
-   color: #5c8df1;
-}
-
-.Ldt-tweet_realName {
-  float: left;
-  margin-left: 3px;
-}
-
-.Ldt-tweetContents {
-}
-
-.Ldt-tweet_date {
-  float: left;
-}
-
-.Ldt-tweetWidgetKeepOpen {
-  position: relative;
-  float: right;
-  height: 17px;
-  width: 17px;
-  margin-right: 1px;
-  background:url('imgs/minimize.png');
-}
-
-.Ldt-tweetWidgetMinimize {
-  position: relative;
-  float: right;
-  height: 17px;
-  width: 17px;
-  right: 9px;
-  background:url('imgs/minimize.png');
-}
-
-.Ldt-tweetWidget * a:link {
-  color: #729efa;
-
-}
-
-.Ldt-TweetReply {
-  float: left;
-  margin-left: 16px;
-}
-
-.Ldt-TweetReplyIcon {
-  background:url('imgs/reply_sprite.png') no-repeat scroll 0 0 transparent ;
-  width: 14px;
-  height: 11px;
-  float: left;
-  margin-top: 2px;
-}
-
-.Ldt-TweetReplyIcon:hover {
-  background-position: 0 -11px;
-}
-
-.Ldt-TweetReplyIcon:active {
-  background-position: 0 -22px;
-}
-
-.Ldt-Retweet {
-  float: left;
-  margin-left: 16px;
-}
-
-.Ldt-RetweetIcon {
-  background:url('imgs/retweet_sprite.png') no-repeat scroll 0 0 transparent ;
-  width: 14px;
-  height: 8px;
-  float: left;
-  margin-top: 3px;
-}
-
-.Ldt-RetweetIcon:hover {
-  background-position: 0 -8px;
-}
-
-.Ldt-RetweetIcon:active {
-  background-position: 0 -16px;
-}
-
-/* styling of a "++" in a tweet */
-.Ldt-PolemicPlusPlus {
-  background-color: #1d973d;
-}
-
-/* styling of a "==" in a tweet */
-.Ldt-PolemicEqualEqual {
-  background-color: #5c8df1
-}
-
-/* styling of a "--" in a tweet */
-.Ldt-PolemicMinusMinus {
-  background-color: #ce0a15;
-}
-
-/* styling of a "??" in a tweet */
-.Ldt-PolemicQuestion {
-  background-color: #c5a62d;
-}
-
-/* the styling of a spacer div */
-.Ldt-spacer {
-  background-color:#eeeeee;
-}
-
-/* sparkline widget */
-.Ldt-sparklineWidget {
-  position: relative;
-  margin-bottom: 5px;
-}
-
-.Ldt-sparkLinePositionMarker {
-  position: absolute;
-  top: 0px;
-  width: 0px;
-  background-color: #333333;
-  border-right: solid 1px pink;
-  z-index: 3;
-  opacity: 0.2;
-}
-
-.Ldt-sparkLine {
-  position: absolute;
-  top: 0px;
-}
-
-.Ldt-sparkLineClickOverlay {
-  position: absolute;
-  width: 640px;
-  height: 60px;
-  z-index: 4;
-  top: 0px;
-  opacity: 0.3;
-}
-
-.Ldt-sliceWidget {
-  position: relative;
-  width: 100%;
-  height: 25px;
-  margin-top: 3px;
-}
-
-.Ldt-sliceBackground {
-  width: 100%;
-  background-color: #b6b8b8;
-  height: 12px;
-}
-
-.Ldt-sliceZone {
-  position: absolute;
-  top: 0px;
-  background:url('imgs/wire_pattern.png') repeat scroll transparent;
-  height: 12px;
-  z-index: 2;
-}
-
-.Ldt-sliceLeftHandle {
-  position: absolute;
-  top: 0px;
-  height: 25px;
-  width: 7px;
-  background:url('imgs/left_handle.gif') no-repeat scroll transparent;
-  z-index: 2;
-}
-
-.Ldt-sliceRightHandle {
-  position: absolute;
-  top: 0px;
-  height: 25px;
-  width: 7px;
-  background:url('imgs/right_handle.gif') no-repeat scroll transparent;
-  z-index: 2;
-}
-
-.Ldt-createAnnotationWidget {
-  font-size: 12px;
-  font-family: "Arial",  "Verdana", "sans-serif";
-  background-color:#eeeeee;
-  background:url('imgs/wire_pattern.png') repeat scroll transparent ;
-  border: 1px solid #b6b8b8;  
-}
-
-.Ldt-createAnnotation-DoubleBorder {
-  border: 1px solid white;
-  overflow: auto;
-  padding: 7px;
-}
-
-.Ldt-createAnnotation-Title {
-  font-size: 12pt;
-  color : #0068c4;  
-  float: left;
-  margin-right: 5px;
-}
-
-.Ldt-createAnnotation-TimeFrame {
-  font-size: 12pt;
-  color : #ff5589;  
-  float: left;
-}
-
-.Ldt-createAnnotation-Container {
-  float: left; width: 100%; clear: both;
-}
-
-.Ldt-createAnnotation-userAvatar { 
-  float: right; 
-  width: 48px;
-  height: 48px;
-  margin: 7px 0;
-  border: 1px solid #babcbc;
-}
-
-.Ldt-createAnnotation-userAvatar img { 
-  float: right; 
-  display: block;
-  max-width: 100%;
-  max-height: 100%;
-}
-
-.Ldt-createAnnotation-profileArrow {
-  float: right;
-  vertical-align: top;
-  height: 48px;
-  width: 15px;
-  margin: 7px 5px;
-  background:url('imgs/profile_arrow.png') center no-repeat;
-}
-
-.Ldt-createAnnotation-Description {
-  float: left;
-  width: 520px;
-  height: 56px; padding: 2px;
-  resize: none;
-}
-
-.Ldt-createAnnotation-btnblock {
-   float: left; width: 450px;  margin: 5px 0;
-}
-
-.Ldt-createAnnotation-btnblock label {
-    float: left; margin-left: 12px; margin: 2px 8px 2px 0; font-size: 12px;
-}
-
-.Ldt-createAnnotation-keyword-button {
-  border: 1px solid #ffffff;
-  background-color: #217bcb;
-  color: #ffffff;
-  padding: 3px 4px;
-  cursor: pointer;
-}
-
-.Ldt-createAnnotation-active-button .Ldt-createAnnotation-keyword-button {
-  background-color: #d93c71;
-}
-
-.Ldt-createAnnotation-submitButton {
-  float: right;
-  background-color: #d93c71;
-  color: #ffffff;
-  cursor: pointer;
-  background-image: url('imgs/submit_annotation.png');
-  background-repeat: no-repeat;
-  height: 48px;
-  width: 48px;
-  position: relative;
-  margin-top: 3px;
-  padding: 28px 0 0;
-  font-size: 13px;
-  border: none;
-  text-align: center;
-}
-
-.Ldt-createAnnotation-endScreen {
-  background-color: #ffffff;
-  margin-left: 5px;
-  margin-right: 5px;
-  border: 1px solid #d6d6d6;
-  padding: 10px;
-  font-size: 13px;
-  font-weight: bold;
-  color : #f7268e;
-  text-align: center;
-}
-
-.Ldt-createAnnotation-errorMessage {
-  color: #D93C71;
-}
-
-.Ldt-createAnnotation-Minimize {
-  position: relative;
-  float: right;
-  height: 17px;
-  width: 17px;
-  right: 0px;
-  background:url('imgs/minimize.png');
-}
-
-/* polemic tweet annotation buttons */
-
-.Ldt-createAnnotation-polemic-button {
-  margin: 0;
-  border: 0;
-  padding: 0;
-  margin-right: 2px;
-  width: 38px;
-  height: 26px;
-  text-indent: -999px;
-  background: url(imgs/polemic_buttons_sprite.png);
-  cursor: pointer;
-}
-
-.Ldt-createAnnotation-polemic-positive:hover {
-    background-position: 0 -26px;
-}
-.Ldt-createAnnotation-active-button .Ldt-createAnnotation-polemic-positive {
-    background-position: 0 -52px;
-}
-
-.Ldt-createAnnotation-polemic-negative {
-    background-position: -38px 0;
-}
-.Ldt-createAnnotation-polemic-negative:hover {
-    background-position: -38px -26px;
-}
-.Ldt-createAnnotation-active-button .Ldt-createAnnotation-polemic-negative {
-    background-position: -38px -52px;
-}
-
-.Ldt-createAnnotation-polemic-reference {
-    background-position: -76px 0;
-}
-.Ldt-createAnnotation-polemic-reference:hover {
-    background-position: -76px -26px;
-}
-.Ldt-createAnnotation-active-button .Ldt-createAnnotation-polemic-reference {
-    background-position: -76px -52px;
-}
-
-.Ldt-createAnnotation-polemic-question {
-    background-position: -114px 0;
-}
-.Ldt-createAnnotation-polemic-question:hover {
-    background-position: -114px -26px;
-}
-.Ldt-createAnnotation-active-button .Ldt-createAnnotation-polemic-question {
-    background-position: -114px -52px;
-}
-
-.Ldt-createAnnotation-spinner {
-	display: inline;
-	width: 16px;
-	height: 16px;
-	background-image('imgs/spinner.gif');
-}
-
-.Ldt-createAnnotation-endScreen-TweetLink {
-	width: 54px;
-	height: 20px;
-	background-image('imgs/tweet_button.png');
-}
-
-.Ldt-createAnnotation-endScreen-FbLink {
-	width: 55px;
-	height: 20px;
-	background-image('imgs/facebook_button.png');
-}
-
-.Ldt-createAnnotation-endScreen-GplusLink {
-	width: 50px;
-	height: 20px;
-	background-image('imgs/gplus_button.png');
-}
-/* AnnotationsListWidget */
-
-.Ldt-AnnotationsListWidget {
-  font-size: 12px;
-  font-family: "Arial",  "Verdana", "sans-serif";
-  border: 1px solid #b6b8b8;
-  overflow: auto;
-  max-height: 480px;
-}
-
-ul.Ldt-AnnotationsList-ul {
-  list-style: none;
-  padding: 0 3px;
-}
-
-li.Ldt-AnnotationsList-li {
-  cursor: pointer;
-  float: left; width: 100%; clear: both;
-  margin: 2px 0; padding: 2px 0;
-}
-
-.Ldt-AnnotationsList-li:hover {
-  background-color: #e9e9e9;
-}
-
-.Ldt-AnnotationsList-highlight {
-    background: #F7268E; color: #ffffff;
-}
-
-.Ldt-AnnotationsListWidget a {
-  text-decoration: none;
-}
-
-.Ldt-AnnotationsList-Thumb-Placeholder {
-  float: left;
-  height: 64px;
-  width: 64px;
-  background-image: url('imgs/video_sequence.png');
-}
-
-.Ldt-AnnotationsList-Thumbnail {
-    border: none;
-    float: left;
-    max-width: 64px;
-    max-height: 64px;
-}
-
-.Ldt-AnnotationsList-Duration {  
-  color : #f7268e;
-  float: right; text-align: right;
-}
-
-.Ldt-AnnotationsList-Title {
-  color: #0068c4;
-  font-size: 13px;
-  margin: 0 0 2px 64px;
-}
-
-.Ldt-AnnotationsList-Description {
-    clear: both;
-    margin: 2px 0;
-}
-
-ul.Ldt-AnnotationsList-Tags {
-    width: 100%; list-style: none; clear: both; padding: 0; margin: 2px 0;
-}
-
-li.Ldt-AnnotationsList-Tag-Li {
-    float: left; margin: 2px; background: #0068c4; color: #fff; padding: 4px;
-}
-
-li.Ldt-AnnotationsList-Tag-Li:hover {
-    background: #F7268E;
-}
-
-/* Tagcloud */
-
-.Ldt-TagCloud {
-    font-family: "PT Sans", Arial, Helvetica, sans-serif;
-}
-
-.Ldt-TagCloud ul {
-    list-style: none; padding: 0; margin: 5px; text-align: center;
-}
-
-.Ldt-TagCloud li {
-    display: inline-block; margin: 2px; cursor:pointer; cursor:hand;
-}
-
-.Ldt-TagCloud li:hover {
-    color: #0099ff;
-}
-
-.Ldt-TagCloud-actif {
-    color: #c000c0;
-}
Binary file web/res/css/metadataplayer/imgs/annotate_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/black.png has changed
Binary file web/res/css/metadataplayer/imgs/black_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/black_arrow_big.png has changed
Binary file web/res/css/metadataplayer/imgs/black_big.png has changed
Binary file web/res/css/metadataplayer/imgs/delicious.png has changed
Binary file web/res/css/metadataplayer/imgs/facebook.png has changed
Binary file web/res/css/metadataplayer/imgs/facebook_button.png has changed
Binary file web/res/css/metadataplayer/imgs/google.png has changed
Binary file web/res/css/metadataplayer/imgs/gplus_button.png has changed
Binary file web/res/css/metadataplayer/imgs/grey_arrow_Show.png has changed
Binary file web/res/css/metadataplayer/imgs/left_edge_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/left_handle.gif has changed
Binary file web/res/css/metadataplayer/imgs/linkedin.png has changed
Binary file web/res/css/metadataplayer/imgs/loader.gif has changed
Binary file web/res/css/metadataplayer/imgs/minimize.png has changed
Binary file web/res/css/metadataplayer/imgs/player-sprites.png has changed
Binary file web/res/css/metadataplayer/imgs/player_gradient.png has changed
Binary file web/res/css/metadataplayer/imgs/polemic_buttons_sprite.png has changed
Binary file web/res/css/metadataplayer/imgs/profile_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/purple_arrow_Show.png has changed
Binary file web/res/css/metadataplayer/imgs/reply_sprite.png has changed
Binary file web/res/css/metadataplayer/imgs/retweet_sprite.png has changed
Binary file web/res/css/metadataplayer/imgs/right_edge_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/right_handle.gif has changed
Binary file web/res/css/metadataplayer/imgs/spinner.gif has changed
Binary file web/res/css/metadataplayer/imgs/submit_annotation.png has changed
Binary file web/res/css/metadataplayer/imgs/transBlack.png has changed
Binary file web/res/css/metadataplayer/imgs/tweet_button.png has changed
Binary file web/res/css/metadataplayer/imgs/twitter.png has changed
Binary file web/res/css/metadataplayer/imgs/user_default_icon.png has changed
Binary file web/res/css/metadataplayer/imgs/video_sequence.png has changed
Binary file web/res/css/metadataplayer/imgs/white.png has changed
Binary file web/res/css/metadataplayer/imgs/white_arrow.png has changed
Binary file web/res/css/metadataplayer/imgs/white_arrow_big.png has changed
Binary file web/res/css/metadataplayer/imgs/white_arrow_long.png has changed
Binary file web/res/css/metadataplayer/imgs/white_arrow_mini.png has changed
Binary file web/res/css/metadataplayer/imgs/white_big.png has changed
Binary file web/res/css/metadataplayer/imgs/widget20.png has changed
Binary file web/res/css/metadataplayer/imgs/wire_pattern.png has changed
--- a/web/res/css/tweetcast.css	Wed May 02 19:19:51 2012 +0200
+++ b/web/res/css/tweetcast.css	Thu May 03 17:52:07 2012 +0200
@@ -86,11 +86,11 @@
 
 
 #mdpgauche {
-    float: left; width: 300px; margin-right: 10px;
+    float: left; width: 350px; margin-right: 10px;
 }
 
 #mdpdroite {
-    float: left; width: 650px; margin-top: 10px; position: relative;
+    float: left; width: 600px; margin-top: 10px; position: relative;
 }
 
 #colgauche {
@@ -571,7 +571,7 @@
 }
 
 #mdpgauche #accordeon {
-    width: 300px;
+    width: 350px;
 }
 
 #accordeon h3 {
--- a/web/res/js/LdtPlayer-release.js	Wed May 02 19:19:51 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6268 +0,0 @@
-/* 
- * 	
- *	Copyright 2010-2012 Institut de recherche et d'innovation 
- *	contributor(s) : Karim Hamidou, Samuel Huron, Raphael Velt, Thibaut Cavalie
- *	 
- *	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 _toString = Object.prototype.toString;
-
-  Array.isArray = Array.isArray || function (obj) {
-    return _toString.call(obj) == "[object Array]";
-  }
-
-  var _trim = String.prototype.trim, trim;
-
-  if (_trim) {
-    trim = function (text) {
-      return text == null ? "" : _trim.call(text);
-    }
-  } else {
-    var trimLeft, trimRight;
-
-    // IE doesn't match non-breaking spaces with \s.
-    if ((/\S/).test("\xA0")) {
-      trimLeft = /^[\s\xA0]+/;
-      trimRight = /[\s\xA0]+$/;
-    } else {
-      trimLeft = /^\s+/;
-      trimRight = /\s+$/;
-    }
-
-    trim = function (text) {
-      return text == null ? "" :
-        text.toString().replace(trimLeft, "").replace(trimRight, "");
-    }
-  }
-
-  var escapeMap = {
-    "&": "&amp;",
-    "<": "&lt;",
-    ">": "&gt;",
-    '"': '&quot;',
-    "'": '&#39;'
-  };
-
-  function escapeHTML(string) {
-    return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) {
-      return escapeMap[s] || s;
-    });
-  }
-
-  var regexCache = {};
-  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;
-        }
-      }
-
-      // get the pragmas together
-      template = this.render_pragmas(template);
-
-      // render the template
-      var html = this.render_section(template, context, partials);
-
-      // render_section did not find any sections, we still need to render the tags
-      if (html === false) {
-        html = this.render_tags(template, context, partials, in_recursion);
-      }
-
-      if (in_recursion) {
-        return html;
-      } else {
-        this.sendLines(html);
-      }
-    },
-
-    /*
-      Sends parsed lines
-    */
-    send: function (line) {
-      if (line !== "") {
-        this.buffer.push(line);
-      }
-    },
-
-    sendLines: function (text) {
-      if (text) {
-        var lines = text.split("\n");
-        for (var i = 0; i < lines.length; i++) {
-          this.send(lines[i]);
-        }
-      }
-    },
-
-    /*
-      Looks for %PRAGMAS
-    */
-    render_pragmas: function (template) {
-      // no pragmas
-      if (!this.includes("%", template)) {
-        return template;
-      }
-
-      var that = this;
-      var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) {
-        return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + 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 = trim(name);
-      if (!partials || partials[name] === undefined) {
-        throw({message: "unknown_partial '" + name + "'"});
-      }
-      if (!context || 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)) {
-        // did not render anything, there were no sections
-        return false;
-      }
-
-      var that = this;
-
-      var regex = this.getCachedRegex("render_section", function (otag, ctag) {
-        // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder
-        return new RegExp(
-          "^([\\s\\S]*?)" +         // all the crap at the beginning that is not {{*}} ($1)
-
-          otag +                    // {{
-          "(\\^|\\#)\\s*(.+)\\s*" + //  #foo (# == $2, foo == $3)
-          ctag +                    // }}
-
-          "\n*([\\s\\S]*?)" +       // between the tag ($2). leading newlines are dropped
-
-          otag +                    // {{
-          "\\/\\s*\\3\\s*" +        //  /foo (backreference to the opening tag).
-          ctag +                    // }}
-
-          "\\s*([\\s\\S]*)$",       // everything else in the string ($4). leading whitespace is dropped.
-
-        "g");
-      });
-
-
-      // for each {{#foo}}{{/foo}} section do...
-      return template.replace(regex, function (match, before, type, name, content, after) {
-        // before contains only tags, no sections
-        var renderedBefore = before ? that.render_tags(before, context, partials, true) : "",
-
-        // after may contain both sections and tags, so use full rendering function
-            renderedAfter = after ? that.render(after, context, partials, true) : "",
-
-        // will be computed below
-            renderedContent,
-
-            value = that.find(name, context);
-
-        if (type === "^") { // inverted section
-          if (!value || Array.isArray(value) && value.length === 0) {
-            // false or empty list, render it
-            renderedContent = that.render(content, context, partials, true);
-          } else {
-            renderedContent = "";
-          }
-        } else if (type === "#") { // normal section
-          if (Array.isArray(value)) { // Enumerable, Let's loop!
-            renderedContent = 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!
-            renderedContent = that.render(content, that.create_context(value),
-              partials, true);
-          } else if (typeof value == "function") {
-            // higher order section
-            renderedContent = value.call(context, content, function (text) {
-              return that.render(text, context, partials, true);
-            });
-          } else if (value) { // boolean section
-            renderedContent = that.render(content, context, partials, true);
-          } else {
-            renderedContent = "";
-          }
-        }
-
-        return renderedBefore + renderedContent + renderedAfter;
-      });
-    },
-
-    /*
-      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 that.getCachedRegex("render_tags", function (otag, ctag) {
-          return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + 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
-        case "&": // & operator is an alternative unescape method
-          return that.find(name, context);
-        default: // escape the value
-          return escapeHTML(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 = 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;
-
-      // check for dot notation eg. foo.bar
-      if (name.match(/([a-z_]+)\./ig)) {
-        var childValue = this.walk_context(name, context);
-        if (is_kinda_truthy(childValue)) {
-          value = childValue;
-        }
-      } else {
-        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 "";
-    },
-
-    walk_context: function (name, context) {
-      var path = name.split('.');
-      // if the var doesn't exist in current context, check the top level context
-      var value_context = (context[path[0]] != undefined) ? context : this.context;
-      var value = value_context[path.shift()];
-      while (value != undefined && path.length > 0) {
-        value_context = value;
-        value = value[path.shift()];
-      }
-      // if the value is a function, call it, binding the correct context
-      if (typeof value == "function") {
-        return value.apply(value_context);
-      }
-      return value;
-    },
-
-    // Utility methods
-
-    /* includes tag */
-    includes: function (needle, haystack) {
-      return haystack.indexOf(this.otag + needle) != -1;
-    },
-
-    // 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";
-    },
-
-    /*
-      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;
-      }
-    },
-
-    getCachedRegex: function (name, generator) {
-      var byOtag = regexCache[this.otag];
-      if (!byOtag) {
-        byOtag = regexCache[this.otag] = {};
-      }
-
-      var byCtag = byOtag[this.ctag];
-      if (!byCtag) {
-        byCtag = byOtag[this.ctag] = {};
-      }
-
-      var regex = byCtag[name];
-      if (!regex) {
-        regex = byCtag[name] = generator(this.otag, this.ctag);
-      }
-
-      return regex;
-    }
-  };
-
-  return({
-    name: "mustache.js",
-    version: "0.5.0-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 */
-// Why is it called main ? It only loads the libs !
-
-if ( window.IriSP === undefined && window.__IriSP === undefined ) { 
-  /**
-    @class
-    the object under which everything goes.        
-  */
-	IriSP = {}; 
-  
-  /** Alias to IriSP for backward compatibility */
-	__IriSP = IriSP;
-}
-
-/* underscore comes bundled with the player and we need 
-   it ASAP, so load it that way
-*/
-
-IriSP._ = window._.noConflict();
-IriSP.underscore = IriSP._;
-
-IriSP.getLib = function(lib) {
-    return (
-        IriSP.libFiles.useCdn && typeof IriSP.libFiles.cdn[lib] == "string"
-        ? IriSP.libFiles.cdn[lib]
-        : (
-            typeof IriSP.libFiles.locations[lib] == "string"
-            ? IriSP.libFiles.locations[lib]
-            : (
-                typeof IriSP.libFiles.inDefaultDir[lib] == "string"
-                ? IriSP.libFiles.defaultDir + IriSP.libFiles.inDefaultDir[lib]
-                : null
-            )
-        )
-    )
-}
-
-IriSP.loadLibs = function( config, metadata_url, callback ) {
-    // Localize jQuery variable
-		IriSP.jQuery = null;
-    var $L = $LAB.script(IriSP.getLib("jQuery")).script(IriSP.getLib("swfObject")).wait()
-                .script(IriSP.getLib("jQueryUI"));
-                                   
-    if (config.player.type === "jwplayer" || config.player.type === "allocine") {
-      // load our popcorn.js lookalike
-      $L.script(IriSP.getLib("jwplayer"));
-    } else {
-      // load the real popcorn
-      $L.script(IriSP.getLib("popcorn")).script(IriSP.getLib("popcorn.code"));
-      if (config.player.type === "youtube") {
-        $L.script(IriSP.getLib("popcorn.youtube"));
-      } 
-      if (config.player.type === "vimeo")
-        $L.script(IriSP.getLib("popcorn.vimeo"));
-      
-      /* do nothing for html5 */
-    }       
-    
-    /* widget specific requirements */
-    for (var idx in config.gui.widgets) {
-      if (config.gui.widgets[idx].type === "PolemicWidget" ||
-          config.gui.widgets[idx].type === "StackGraphWidget" ||
-          config.gui.widgets[idx].type === "SparklineWidget") {        
-        $L.script(IriSP.getLib("raphael"));
-      }
-      if (config.gui.widgets[idx].type === "TraceWidget") {
-          $L.script(IriSP.getLib("tracemanager"))
-      }
-    }
-    
-    // same for modules
-    /*
-    for (var idx in config.modules) {
-      if (config.modules[idx].type === "PolemicWidget")
-        $L.script(IriSP.getLib("raphaelJs"));
-    }
-    */
-
-    $L.wait(function() {
-      IriSP.jQuery = window.jQuery.noConflict( true );
-      
-      var css_link_jquery = IriSP.jQuery( "<link>", { 
-        rel: "stylesheet", 
-        type: "text/css", 
-        href: IriSP.getLib("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 Ldt-TraceMe' 	style='left: {{startPixel}}px;          width: {{pxWidth}}px;          background-color:{{hexa_color}};'    data-seek='{{seekPlace}}'    thumbnail-url='{{thumbnailUrl}}'	></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 target='_blank' class='Ldt-fbShare Ldt-TraceMe' title='{{i10n.share_on}} Facebook'></a>         <a target='_blank' class='Ldt-TwShare Ldt-TraceMe' title='{{i10n.share_on}} Twitter'></a>         <a target='_blank'  class='Ldt-GplusShare Ldt-TraceMe' title='{{i10n.share_on}} Google+'></a>        </div>        <div class='Ldt-SaTitle'></div>        <div class='Ldt-SaDescription'></div>        <div class='Ldt-SaKeywords'></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.annotationsListWidget_template = "{{! template for the annotation list widget }}<div class='Ldt-AnnotationsListWidget'>    <ul class='Ldt-AnnotationsList-ul'>        {{#annotations}}        <li id='Ldt-Annotation-li-{{id}}' class='Ldt-AnnotationsList-li Ldt-TraceMe'>            {{^url}} <a href='#id={{id}}'> {{/url}}            {{! otherwise link to url }}            {{#url}} <a href='{{url}}'> {{/url}}                <img class='Ldt-AnnotationsList-Thumbnail' src='{{thumbnail}}' />            </a>            <div class='Ldt-AnnotationsList-Duration'>                <span class='Ldt-AnnotationsList-Begin'>{{begin}}</span>                <span class='Ldt-AnnotationsList-TcSeparator'>-</span>                <span class='Ldt-AnnotationsList-End'>{{end}}</span>            </div>            <div class='Ldt-AnnotationsList-Title'>            {{! if the url is not present, it means that the annotation exists            in the current project }}                {{title}}            </div>            <div class='Ldt-AnnotationsList-Description'>            {{^url}} <a href='#id={{id}}'> {{/url}}            {{! otherwise link to url }}            {{#url}} <a href='{{url}}'> {{/url}}                {{desc}}                </a>            </div>            {{#tags.length}}            <ul class='Ldt-AnnotationsList-Tags'>                {{#tags}}                <li class='Ldt-AnnotationsList-Tag-Li'>                    <div class='Ldt-AnnotationsList-Tag-Div'>{{.}}</div>                </li>                {{/tags}}            </ul>            {{/tags.length}}        </li>        {{/annotations}}    </ul></div>";
-IriSP.arrowWidget_template = "<div class='Ldt-arrowWidget Ldt-arrowLeftEdge'></div>";
-IriSP.createAnnotationWidget_template = "{{! template for the annotation creation widget }}<div class='Ldt-createAnnotationWidget'>    <!-- ugly div because we want to have a double border -->    <div class='Ldt-createAnnotation-DoubleBorder'>        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-startScreen'>            <div style='margin-bottom: 7px; overflow: auto;'>                <div class='Ldt-createAnnotation-Title'></div>                <div class='Ldt-createAnnotation-TimeFrame'></div>                {{^cinecast_version}} <div class='Ldt-createAnnotation-Minimize Ldt-TraceMe' title='Cancel'></div>                {{/cinecast_version}}            </div>            <div class='Ldt-createAnnotation-Container'>                {{#show_from_field}}                <label>{{l10n.your_name}}&nbsp;: </label><input class='Ldt-createAnnotation-userName Ldt-TraceMe' value='{{user_name}}' />                {{/show_from_field}}                <textarea class='Ldt-createAnnotation-Description Ldt-TraceMe'></textarea>                <div class='Ldt-createAnnotation-userAvatar Ldt-TraceMe'>                    {{^user_avatar}} <img src='https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png'></img>                    {{/user_avatar}}                    {{#user_avatar}} <img src='{{ user_avatar }}'></img>                    {{/user_avatar}}                </div>                <div class='Ldt-createAnnotation-profileArrow'></div>            </div>            <button class='Ldt-createAnnotation-submitButton Ldt-TraceMe'>{{l10n.submit}}</button>            {{#tags.length}}            <div class='Ldt-createAnnotation-btnblock Ldt-createAnnotation-keywords'>                <label>{{l10n.add_keywords}} :</label>                <ul class='Ldt-floatList'>                {{#tags}}                    <li><button class='Ldt-createAnnotation-keyword-button Ldt-TraceMe' tag-id='{{id}}'>{{meta.description}}</button></li>                {{/tags}}                </ul>            </div>            {{#random_tags}}                <button class='Ldt-createAnnotation-moar-keywordz'>{{l10n.more_tags}}</button>            {{/random_tags}}            {{/tags.length}}            {{#polemic_mode}}            {{#polemics.length}}            <div class='Ldt-createAnnotation-btnblock Ldt-createAnnotation-polemics'>                <label>{{l10n.add_polemic_keywords}} :</label>                <ul class='Ldt-floatList'>                {{#polemics}}                    <li><button class='Ldt-createAnnotation-polemic-{{className}} Ldt-createAnnotation-polemic-button Ldt-TraceMe'>{{keyword}}</button></li>                {{/polemics}}                </ul>            </div>            {{/polemics.length}}            {{/polemic_mode}}        </div>        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-waitScreen' style='display: none; text-align: center'>            <div class='Ldt-createAnnotation-spinner'></div>            {{l10n.wait_while_processed}}        </div>        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-errorScreen' style='display: none; text-align: center'>            <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>            {{l10n.error_while_contacting}}        </div>        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-endScreen' style='display: none'>            <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>            {{l10n.annotation_saved}}            <br>            {{^disable_share}}            {{l10n.share_annotation}}            <div style='margin-top: 12px; text-align: center;'>                <a target='_blank' class='Ldt-createAnnotation-endScreen-TweetLink Ldt-TraceMe'></a>                <a target='_blank' class='Ldt-createAnnotation-endScreen-FbLink Ldt-TraceMe'></a>                <a target='_blank' class='Ldt-createAnnotation-endScreen-GplusLink Ldt-TraceMe'></a>            </div>            {{/disable_share}}        </div>        <div class='Ldt-floatClear'></div>    </div></div>";
-IriSP.createAnnotation_errorMessage_template = "<p class='Ldt-createAnnotation-errorMessage'>  {{l10n.empty_annotation}}</p>";
-IriSP.loading_template = "<div id='Ldt-loader' style='width: {{width}}px; height: {{height}}px;'>{{l10n.loading_wait}}</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'>	<div class='Ldt-LeftPlayerControls'>        <div class='Ldt-Ctrl-button Ldt-CtrlPlay Ldt-CtrlPlay-PlayState Ldt-TraceMe' title='{{l10n.play_pause}}'></div>        <div class='Ldt-Ctrl-spacer'></div>        {{^disable_annotate_btn}}    	<div class='Ldt-Ctrl-button Ldt-CtrlAnnotate Ldt-TraceMe' title='{{l10n.annotate}}'></div>        <div class='Ldt-Ctrl-spacer'></div>        {{/disable_annotate_btn}}        {{^disable_search_btn}}        <div class='Ldt-Ctrl-button Ldt-CtrlSearch Ldt-TraceMe' title='{{l10n.search}}'></div>        <div class='Ldt-Ctrl-spacer'></div>        {{/disable_search_btn}}        <div class='LdtSearch'>          <input class='LdtSearchInput Ldt-TraceMe'></input>        </div>	</div>	<div class='Ldt-RightPlayerControls'>        <div class='Ldt-Ctrl-spacer'></div>        <div class='Ldt-Time'>          <div class='Ldt-ElapsedTime' title='{{l10n.elapsed_time}}'>00:00</div>          <div class='Ldt-TimeSeparator'>/</div>          <div class='Ldt-TotalTime' title='{{l10n.total_time}}'>00:00</div>        </div>        <div class='Ldt-Ctrl-spacer'></div>		<div class='Ldt-Ctrl-button Ldt-CtrlSound Ldt-CtrlSound-Full Ldt-TraceMe' title='{{l10n.mute_unmute}}'></div>	</div>	<div class='Ldt-Ctrl-Volume-Control' title='{{l10n.volume_control}}'>	    <div class='Ldt-Ctrl-Volume-Bar'></div>	    <div class='Ldt-Ctrl-Volume-Cursor'></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; border-color: #CFCFCF; position: absolute; text-align: center;'>		<input class='LdtSearchInput'			style='margin-top: 1px; margin-bottom: 2px;' />	</div></div><div class='cleaner'></div>";
-IriSP.share_template = "{{! social network sharing template }}<a onclick='__IriSP.MyApiPlayer.share(\'delicious\');' title='{{l10n.share_on}} delicious'><span class='share shareDelicious'>&nbsp;</span></a>		<a onclick='__IriSP.MyApiPlayer.share(\'facebook\');' title='{{l10n.share_on}} facebook'> <span class='share shareFacebook'>&nbsp;</span></a><a onclick='__IriSP.MyApiPlayer.share(\'twitter\');' title='{{l10n.share_on}} twitter'>  <span class='share shareTwitter'>&nbsp;</span></a><a onclick='__IriSP.MyApiPlayer.share(\'myspace\');' title='{{l10n.share_on}} Myspace'>  <span class='share shareMySpace'>&nbsp;</span></a>";
-IriSP.sliceWidget_template = "{{! template for the slice widget }}<div class='Ldt-sliceWidget'>  {{! the whole bar }}  <div class='Ldt-sliceBackground'></div>    <div class='Ldt-sliceLeftHandle'></div>  {{! the zone which represents our slice }}  <div class='Ldt-sliceZone'></div>     <div class='Ldt-sliceRightHandle'></div></div>";
-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 Ldt-TraceMe'></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'>      <div class='Ldt-tweetWidgetKeepOpen Ldt-TraceMe' title='dont minimize automatically'></div>      <div class='Ldt-tweetWidgetMinimize Ldt-TraceMe' title='minimize window'></div>      <div class='Ldt-tweetAvatar'></div>      <div class='Ldt-tweetAvatar-profileArrow'></div>      <div class='Ldt-tweetContents'></div>      <a href='' target='_blank' class='Ldt-Retweet Ldt-TraceMe'><div class='Ldt-RetweetIcon'></div> - Retweet </a>      <a href='' target='_blank' class='Ldt-TweetReply Ldt-TraceMe'><div class='Ldt-TweetReplyIcon'></div> - Reply</a>  </div></div>";/* 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 milliseconds to a tuple of the form 
-   [hours, minutes, seconds]
-*/
-IriSP.msToTime = function(ms) {
-  return IriSP.secondsToTime(ms / 1000);
-}
-/* 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};
-};
-
-/* 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 val = +dec;
-  var str = val.toString(16);
-  var zeroes = "";
-  if (str.length < 6) {
-    for (var i = 0; i < 6 - str.length; i++)
-      zeroes += "0";
-  }
-  return zeroes + str;
-};
-
-/* shortcut to have global variables in templates */
-IriSP.templToHTML = function(template, values) {
-  var params = IriSP.underscore.extend(
-      { "defaults" : IriSP.default_templates_vars,
-        "l10n" : IriSP.i18n.getMessages()
-        },
-      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.jqEscape = function(text) {
-   return text.replace(/(:|\.)/g,'\\$1')
-}
-
-IriSP.jqId = function (text) { 
-   return IriSP.jQuery('#' + IriSP.jqEscape(text));
- }  
-
-IriSP.__guidCounter = 0;
-IriSP.guid = function(prefix) {
-  IriSP.__guidCounter += 1;
-  return prefix + IriSP.__guidCounter;
-};
-
-/** returns an url to share on facebook */
-IriSP.mkFbUrl = function(url, text) {
-  if (typeof(text) === "undefined")
-    text = "I'm watching ";
-  
-  return "http://www.facebook.com/share.php?u=" + IriSP.encodeURI(text) + IriSP.shorten_url(url);
-};
-
-/** returns an url to share on twitter */
-IriSP.mkTweetUrl = function(url, text) {
-  if (typeof(text) === "undefined")
-    text = "I'm watching ";
-  
-  return "http://twitter.com/home?status=" + IriSP.encodeURI(text) + IriSP.shorten_url(url);
-};
-
-/** returns an url to share on google + */
-IriSP.mkGplusUrl = function(url, text) {
-  return "https://plusone.google.com/_/+1/confirm?hl=en&url=" + IriSP.shorten_url(url);
-};
-
-/** test if a value is null or undefined */
-IriSP.null_or_undefined = function(val) {
-  return (typeof(val) === "undefined" || val === null);
-};
-
-/** get a property that can have multiple names **/
-
-IriSP.get_aliased = function(_obj, _aliases) {
-    for (var _i = 0; _i < _aliases.length; _i++) {
-        if (typeof _obj[_aliases[_i]] !== "undefined") {
-            return _obj[_aliases[_i]];
-        }
-    }
-    return null;
-}
-
-/** issue a call to an url shortener and return the shortened url */
-IriSP.shorten_url = function(url) {
-  return encodeURIComponent(url);
-};
-
-
-/* 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);
-   }
-}
-*/
-
-/* Creates regexps from text */
-IriSP.regexpFromText = function(_text) {
-    return new RegExp('(' + _text.replace(/(\W)/gim,'\\$1') + ')','gim');
-}
-/* wrapper that simulates popcorn.js because
-   popcorn is a bit unstable at the time */
-
-IriSP.PopcornReplacement = {  
-};
-
-/** base class for our popcorn-compatible players.
- */
-IriSP.PopcornReplacement.player = function(container, options) {
-  /* the jwplayer calls the callbacks in the global space so we need to 
-     preserve them using IriSP.wrap */
-  this.callbacks = {
-      onReady:  IriSP.wrap(this, this.__initApi),
-      onTime:   IriSP.wrap(this, this.__timeHandler),
-      onPlay:   IriSP.wrap(this, this.__playHandler),
-      onPause:  IriSP.wrap(this, this.__pauseHandler),
-      onSeek:   IriSP.wrap(this, this.__seekHandler) 
-  };
-  
-  this.media = { 
-    "paused": true,
-    "muted": false
-  };
-    
-  this.container = container.slice(1); //eschew the '#'
-  
-  this.msgPump = {}; /* dictionnary used to receive and send messages */
-  this.__codes = []; /* used to schedule the execution of a piece of code in 
-                        a segment (similar to the popcorn.code plugin). */
-  
-  this._options = options;
-                          
-};
-
-IriSP.PopcornReplacement.player.prototype.listen = function(msg, callback) {
-  if (!this.msgPump.hasOwnProperty(msg))
-    this.msgPump[msg] = [];
-
-  this.msgPump[msg].push(callback);
-};
-
-IriSP.PopcornReplacement.player.prototype.trigger = function(msg, params) {
-  if (!this.msgPump.hasOwnProperty(msg))
-    return;
-
-  var d = this.msgPump[msg];
-
-  for(var i = 0; i < d.length; i++) {
-    d[i].call(window, params);
-  }
-
-};
-
-IriSP.PopcornReplacement.player.prototype.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;
-};
-
-/** init the api after that flash player has been setup - called by the callback
-    defined by the embedded flash player 
-*/
-IriSP.PopcornReplacement.player.prototype.__initApi = function() {
-  this.trigger("loadedmetadata"); // we've done more than loading metadata of course,
-                                                      // but popcorn doesn't need to know more.
-  this.media.muted = this.playerFns.getMute();
-  /* some programmed segments are supposed to be run at the beginning */
-  var i = 0;
-  for(i = 0; i < this.__codes.length; i++) {
-    var c = this.__codes[i];
-    if (0 == c.start) {
-      c.onStart();
-    }
-    
-    if (0 == c.end) {
-      c.onEnd();
-    }
-  }
-};
-
-/*
-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.player.prototype.currentTime = function(time) {
-  if (typeof(time) === "undefined") {        
-      return this.playerFns.getPosition();            
-  } else {
-     var currentTime = +time;
-     this.playerFns.seek(currentTime);              
-     return currentTime;
-  }
-};
-
-IriSP.PopcornReplacement.player.prototype.play = function() {
-  this.media.paused = false;
-  this.trigger("play");
-  //IriSP.PopcornReplacement.trigger("playing");
-  this.playerFns.play();
-};
-    
-IriSP.PopcornReplacement.player.prototype.pause = function() {
-//  if ( !this.media.paused ) {
-    this.media.paused = true;
-    this.trigger( "pause" );
-    this.playerFns.pause();
-//  }
-};
-
-IriSP.PopcornReplacement.player.prototype.muted = function(val) {
-  if (typeof(val) !== "undefined") {
-
-    if (this.playerFns.getMute() !== val) {
-      if (val) {
-        this.playerFns.setMute(true);
-        this.media.muted = true;
-      } else {
-        this.playerFns.setMute(false);
-        this.media.muted = false;
-      }
-
-      this.trigger( "volumechange" );
-    }
-    
-    return this.playerFns.getMute();
-  } else {
-    return this.playerFns.getMute();
-  }
-};
-
-IriSP.PopcornReplacement.player.prototype.volume = function(val) {
-    if (typeof this.playerFns.getVolume == "undefined" || typeof this.playerFns.setVolume == "undefined") {
-        return false;
-    }
-    var _vol = this.playerFns.getVolume();
-    if (typeof(val) !== "undefined" && parseFloat(val) !== NaN) {
-        val = Math.max(0, Math.min(1, val));
-        if (parseFloat(val) != parseFloat(_vol)) {
-            this.playerFns.setVolume(val);
-            this.trigger("volumechange");
-            _vol = this.playerFns.getVolume();
-        }
-    }
-    return _vol;
-};
-
-IriSP.PopcornReplacement.player.prototype.mute = IriSP.PopcornReplacement.player.prototype.muted;
-
-IriSP.PopcornReplacement.player.prototype.code = function(options) {
-  this.__codes.push(options);
-  return this;
-};
-
-/* called everytime the player updates itself 
-   (onTime event)
- */
-
-IriSP.PopcornReplacement.player.prototype.__timeHandler = function(event) {
-  var pos = event.position;
-
-  var i = 0;
-  for(i = 0; i < this.__codes.length; i++) {
-     var c = this.__codes[i];
-
-     if (pos >= c.start && pos < c.end && 
-         pos - 1 <= c.start) {       
-        c.onStart();
-     }
- 
-     if (pos > c.start && pos > c.end && 
-         pos - 1 <= c.end) {
-         c.onEnd();
-     }
-   
-  }
- 
-  this.trigger("timeupdate");
-};
-
-IriSP.PopcornReplacement.player.prototype.__seekHandler = function(event) {
-  var i = 0;
-  
-  for(i = 0; i < this.__codes.length; i++) {
-     var c = this.__codes[i];
-    
-     if (event.position >= c.start && event.position < c.end) {        
-        c.onEnd();
-     }         
-   }
-  
-   for(i = 0; i < this.__codes.length; i++) {
-     var c = this.__codes[i];
-
-     if (typeof(event.offset) === "undefined")
-       event.offset = 0;
-           
-     if (event.offset >= c.start && event.offset < c.end) { 
-       c.onStart();
-     }
-     
-   }
-  
-  /* this signal sends as an extra argument the position in the video.
-     As far as I know, this argument is not provided by popcorn */
-  this.trigger("seeked", event.offset);  
-};
-
-IriSP.PopcornReplacement.player.prototype.__playHandler = function(event) {
-  this.media.paused = false;
-  this.trigger("play");
-};
-
-IriSP.PopcornReplacement.player.prototype.__pauseHandler = function(event) {
-  this.media.paused = true;
-  this.trigger("pause");
-};
-
-IriSP.PopcornReplacement.player.prototype.roundTime = function() {
-  var currentTime = this.currentTime();
-  return Math.round(currentTime);
-};/* 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, force_reload) {
-  var base_url = url.split("&")[0];
-  if (typeof force_reload != "undefined" && force_reload && this._cache.hasOwnProperty(base_url)) {
-      delete this._cache[base_url]
-  }
-  if (this._cache.hasOwnProperty(base_url)) {
-    callback(this._cache[base_url]);
-  } else {  
-    if (!this._callbacks.hasOwnProperty(base_url)) {
-      this._callbacks[base_url] = [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]);                                  
-                  }
-                  delete this._callbacks[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.getDuration = 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;
-  }
-};
-IriSP.language = 'en';
-
-IriSP.libFiles = {
-    defaultDir : "js/libs/",
-    inDefaultDir : {
-        jQuery : "jquery.min.js",
-        jQueryUI : "jquery-ui.min.js",
-        jQueryToolTip : "jquery.tools.min.js",
-        swfObject : "swfobject.js",
-        cssjQueryUI : "jquery-ui.css",
-        popcorn : "popcorn.js",
-        jwplayer : "jwplayer.js",
-        raphael : "raphael.js",
-        "popcorn.mediafragment" : "popcorn.mediafragment.js",
-        "popcorn.code" : "popcorn.code.js",
-        "popcorn.jwplayer" : "popcorn.jwplayer.js",
-        "popcorn.youtube" : "popcorn.youtube.js",
-        "tracemanager" : "tracemanager.js"
-    },
-    locations : {
-        // use to define locations outside defautl_dir
-    },
-    cdn : {
-        jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/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"
-    },
-    useCdn : false
-}
-
-IriSP.widgetsDefaults = {
-    "LayoutManager" : {
-        spacer_div_height : 0
-    },
-    "PlayerWidget" : {
-        
-    },
-    "AnnotationsWidget" : {
-        "share_text" : "I'm watching "
-    },
-    "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 ?
-    },
-    "SegmentsWidget" : {
-        cinecast_version : false
-    },
-    "createAnnotationWidget" : {
-        tags : [
-            {
-                "id" : "digitalstudies",
-                "meta" : {
-                    "description" : "#digital-studies"
-                }
-            },
-            {
-                "id" : "amateur",
-                "meta" : {
-                    "description" : "#amateur"
-                },
-            }
-        ],
-        remote_tags : false,
-        random_tags : false,
-        show_from_field : false,
-        disable_share : false,
-        polemic_mode : true, /* enable polemics ? */
-        polemics : [{
-            "className" : "positive",
-            "keyword" : "++"
-        }, {
-            "className" : "negative",
-            "keyword" : "--"
-        }, {
-            "className" : "reference",
-            "keyword" : "=="
-        }, {
-            "className" : "question",
-            "keyword" : "??"
-        }],
-        cinecast_version : false, /* put to false to enable the platform version, true for the festival cinecast one. */
-
-        /* where does the widget PUT the annotations - this is a mustache template. id refers to the id of the media ans is filled
-         by the widget.
-         */
-        api_endpoint_template : "", // platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json",
-        api_method : "PUT"
-    },
-    "SparklineWidget" : {
-       lineColor : "#7492b4",
-       fillColor : "#aeaeb8",
-       lineWidth : 2,
-       cinecast_version : false
-    },
-    "AnnotationsListWidget" : {
-        ajax_mode : true, /* use ajax to get information about the annotations.
-         if set to false, only search in the annotations for the
-         current project. */
-        /* the platform generates some funky urls. We replace them afterwards to point to the
-         correct place - this setting will probably be overwritten by the platform
-         implementers.
-         Note that the player has to replace the variables between {{ and }} by its own values.
-         */
-        ajax_url : "", //platform_url + "/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}",
-        ajax_granularity : 10000, /* how much ms should we look before and after the current timecode */
-        default_thumbnail : "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png",
-        project_url : "", //platform_url + "/ldtplatform/ldt/front/player/"
-        /* the beginning of a link to the new front */
-        cinecast_version : false,
-        refresh_interval : 10000
-    },
-    "StackGraphWidget" : {
-         defaultcolor : "#585858",
-         tags : [
-            {
-                "keywords" : [ "++" ],
-                "description" : "positif",
-                "color" : "#1D973D"
-            },
-            {
-                "keywords" : [ "--" ],
-                "description" : "negatif",
-                "color" : "#CE0A15"
-            },
-            {
-                "keywords" : [ "==" ],
-                "description" : "reference",
-                "color" : "#C5A62D"  
-            },
-            {
-                "keywords" : [ "??" ],
-                "description" : "question",
-                "color" : "#036AAE"
-            }
-        ],
-        streamgraph : false
-    }
-}/* the widget classes and definitions */
-
-/**
-  * @class Widget is an "abstract" class. It's mostly used to define some properties common to every widget.
-  *
-  *  Note that widget constructors are never called directly by the user. Instead, the widgets are instantiated by functions
-  *  defined in init.js
-  *  
-  * @constructor
-  * @param Popcorn a reference to the popcorn Object
-  * @param config configuration options for the widget
-  * @param Serializer a serializer instance from which the widget reads data fromCharCode  
-*/
-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;     
-  } 
-
-  if (config.hasOwnProperty("layoutManager")) {
-     this.layoutManager = config.layoutManager;
-  }
-  if (typeof this.selector != "undefined") {
-      this.selector.addClass("Ldt-TraceMe").addClass("Ldt-Widget");
-      this.selector.attr("widget-type", this._config.type);
-  }
-  
-  // Parsing Widget Defaults
-  var _this = this;
-  
-  if (typeof config.type == "string" && typeof IriSP.widgetsDefaults[config.type] == "object") {
-      IriSP._(IriSP.widgetsDefaults[config.type]).each(function(_v, _k) {
-          if (typeof config[_k] != "undefined") {
-              _this[_k] = config[_k];
-          } else {
-              _this[_k] = _v;
-          }
-      });
-  }
-  
-};
-
-
-IriSP.Widget.prototype.currentMedia = function() {
-    return this._serializer.currentMedia();
-}
-
-IriSP.Widget.prototype.getDuration = function() {
-    return this._serializer.getDuration();
-}
-
-/**
-  * This method responsible of drawing a widget on screen.
-  */
-IriSP.Widget.prototype.draw = function() {
-  /* implemented by "sub-classes" */  
-};
-
-/**
-  * Optional method if you want your widget to support redraws.
-  */
-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 */
-
-/**
-  @class 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,
-        "clear": "both"
-    });
-    
-    if (this._height !== undefined)
-      this.selector.css("height", this._height);
-};
-
-/** 
-   Set the popcorn instance used by the manager.
-   
-   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;
-}
-
-/** create a subdiv with an unique id, and a spacer div as well.
-    @param widgetName the name of the widget.
-    @return an array of the form [createdivId, spacerdivId].
-*/
-IriSP.LayoutManager.prototype.createDiv = function(widgetName) {
-    if (typeof(widgetName) === "undefined")
-       widgetName = "";
-
-    var newDiv = IriSP.guid(this._div + "_widget_" + widgetName + "_");
-    var spacerDiv = IriSP.guid("LdtPlayer_spacer_");
-    this._widgets.push([widgetName, newDiv]);    
-
-    var divTempl = "<div id='{{id}}' style='width: {{width}}px; position: relative; clear: both;'></div";
-    var spacerTempl = "<div id='{{spacer_id}}' style='width: {{width}}px; position: relative; height: {{spacer_div_height}}px;'></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:
- 
- */
-
-/**
-    set up the IriSP.__dataloader instance - 
-    we need it because we have to get the metadata
-    about the video before that the widget have even
-    loaded.
-*/
-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();
-};
-
-/** do some magic to configure popcorn according to the options object passed.
-    Works for html5, jwplayer and youtube videos 
-*/
-IriSP.configurePopcorn = function (layoutManager, options) {
-    var pop;
-    var ret = layoutManager.createDiv(); 
-    var containerDiv = ret[0];
-    var spacerDiv = ret[1];
-    
-    /* insert one pixel of margin between the video and the first widget, using the 
-       spacer.
-    */
-    IriSP.jQuery("#" + spacerDiv).css("height", "1px");
-    
-    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;
-          delete opts.type;
-
-          
-          /* Try to guess options.file and options.streamer only if file and streamer
-             are not already defined in the configuration */
-          if (options.provider === "rtmp" && !opts.hasOwnProperty("file") && !opts.hasOwnProperty("streamer")) {
-            /* 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);
-            
-            /* sometimes we get served a file with a wrong path and streamer.
-               as a streamer is of the form rtmp://domain/path/ and the media is
-               the rest, we uglily do this :
-            */
-            opts.file = "";
-            opts.streamer = "";
-            var fullPath = IriSP.get_aliased(IriSP.__jsonMetadata["medias"][0], ["href","url"]);
-            
-            if (fullPath === null) {
-              console.log("no url or href field defined in the metadata.");
-            }
-            
-            var pathSplit = fullPath.split('/');
-            
-            for (var i = 0; i < pathSplit.length; i++) {
-              if (i < 4) {
-                 opts.streamer += pathSplit[i] + "/";
-              } else {
-                 opts.file += pathSplit[i];
-                 /* omit the last slash if we're on the last element */
-                 if (i < pathSplit.length - 1)
-                  opts.file += "/";
-              }
-            }            
-          } else {
-            /* other providers type, video for instance -
-               pass everything as is */
-          }
-
-          if (!options.hasOwnProperty("flashplayer")) {
-            opts.flashplayer = IriSP.jwplayer_swf_path;
-          }
-
-          if (!options.hasOwnProperty("controlbar.position")) {
-            opts["controlbar.position"] = "none";
-          }
-
-          pop = new 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;
-      
-    case "dailymotion":
-        pop = new IriSP.PopcornReplacement.dailymotion("#" + containerDiv, options);
-        break;
-             
-      case "allocine":
-          /* pass the options as-is to the allocine player and let it handle everything */
-          pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, options);
-          break;
-          
-      default:
-        pop = undefined;
-    };
-    
-    return pop;
-};
-
-/** Configure the gui and instantiate the widgets passed as parameters
-    @param guiOptions the gui object as seen in the examples.
- */
-IriSP.configureWidgets = function (popcornInstance, layoutManager, guiOptions) {
- 
-  var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
-  var params = {width: guiOptions.width, height: guiOptions.height};
-
-  var default_options = guiOptions.default_options;
-  if (IriSP.null_or_undefined(default_options))
-    default_options = {};
-  
-  var ret_widgets = [];
-  var index;
-  
-  for (index = 0; index < guiOptions.widgets.length; index++) {    
-    var widget = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, guiOptions.widgets[index], default_options);
-   
-    ret_widgets.push(widget);   
-  };
-
-  return ret_widgets;
-};
-
-/** configure modules. @see configureWidgets */
-IriSP.configureModules = function (popcornInstance, modulesList) {
-  if (IriSP.null_or_undefined(modulesList))
-    return;
-  
-  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;
-};
-
-/** instantiate a widget - only called by configureWidgets, never by the user. Handles widget 
-    dependencies.
-    @param popcornInstance popcorn instance the widget will user
-    @param serialFactory serializer factory to instantiate the widget with
-    @param layoutManager layout manager
-    @param widgetConfig configuration options for the widget
-    @param defaultOptions a dictionnary with some options defined for every widget.
- */
-IriSP.instantiateWidget = function(popcornInstance, serialFactory, layoutManager, widgetConfig, defaultOptions) {
-
-    if (IriSP.null_or_undefined(defaultOptions))
-      defaultOptions = {};
-    
-    widgetConfig = IriSP.underscore.defaults(widgetConfig, defaultOptions);
-
-    var arr = IriSP.jQuery.extend({}, widgetConfig);
-    
-    /* create a div for those widgets who didn't already specify a container; */
-    if (!arr.hasOwnProperty("container")) {
-      /* 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];           
-      arr.container = container;
-      arr.spacer = spacer;
-      arr.layoutManager = layoutManager;
-    }
-    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"],
-            _configobj = IriSP.jQuery.extend({}, widgetConfig.requires[i]),
-            _div = document.createElement('div'),
-            _container = IriSP.guid(arr.container + '_' + widgetName + '_');
-        _configobj.container = _container;
-        _div.id = _container;
-        widget.selector.append(_div);
-        widget[widgetName] = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, _configobj, defaultOptions);
-      }
-    }       
-     
-    serializer.sync(IriSP.wrap(widget, function() { this.draw(); }));
-    return widget;
-};
-
-/** single point of entry for the metadataplayer */
-IriSP.initPlayer = function(config, metadata_url) {
-    document.getElementById(config.gui.container).innerHTML = IriSP.templToHTML(IriSP.loading_template, config.gui);
-    IriSP.loadLibs(config, metadata_url,
-      function() {   
-              
-              var layoutManager = new IriSP.LayoutManager(config.gui);
-
-              var pop = IriSP.configurePopcorn(layoutManager, config.player);
-              
-              IriSP._widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); 
-              IriSP._modules = IriSP.configureModules(pop, config.modules); 
-              IriSP.jQuery('#Ldt-loader').detach();
-      });
-};IriSP.I18n = function() {
-    this.messages = {};
-    this.base_lang = 'en';
-}
-
-IriSP.I18n.prototype.getLanguage = function(lang) {
-    var _lang = (
-        typeof lang != "undefined"
-        ? lang
-        : (
-            typeof IriSP.language != "undefined"
-            ? IriSP.language
-            : this.base_lang
-        )
-    );
-    return (
-        typeof this.messages[_lang] == "object"
-        ? _lang
-        : (
-            typeof this.messages[this.base_lang] == "object"
-            ? this.base_lang
-            : null
-        )
-    )
-}
-
-IriSP.I18n.prototype.getMessages = function(lang) {
-    var _lang = this.getLanguage(lang);
-    return (
-        _lang != null
-        ? this.messages[_lang]
-        : {}
-    );
-}
-
-IriSP.I18n.prototype.getMessage = function(message, lang) {
-    var _msgs = this.getMessages(lang);
-    return (
-        typeof _msgs[message] != "undefined"
-        ? _msgs[message]
-        : message
-    )
-}
-
-IriSP.I18n.prototype.addMessage = function(lang, messagekey, messagevalue) {
-    if (typeof this.messages[lang] == "undefined") {
-        this.messages[lang] = {};
-    }
-    this.messages[lang][messagekey] = messagevalue;
-}
-
-IriSP.I18n.prototype.addMessages = function(messagesObj) {
-    var _this = this;
-    IriSP.underscore(messagesObj).each(function(_messages, _lang) {
-        IriSP.underscore(_messages).each(function(_value, _key) {
-            _this.addMessage(_lang, _key, _value);
-        })
-    });
-}
-
-IriSP.i18n = new IriSP.I18n();
-
-IriSP.i18n.addMessages({
-    "fr": {
-        "loading_wait": "Chargement en cours, veuillez patienter&hellip;"
-    },
-    "en": {
-        "loading_wait": "Loading, please wait&hellip;"
-    }
-})
-/* To wrap a player the develop should create a new class derived from
-the IriSP.PopcornReplacement.player and defining the correct functions */
-
-/** allocine player wrapper */
-IriSP.PopcornReplacement.allocine = function(container, options) {
-//    console.log("Calling allocine player");
-    /* appel du parent pour initialiser les structures communes à tous les players */
-    IriSP.PopcornReplacement.player.call(this, container, options);   
-    
-    var _this = this;
-
-    /* Définition des fonctions de l'API -  */
-
-    this.playerFns = {
-        play : function() {
-            return _this.apiCall("play");
-        },
-        pause : function() {
-            return _this.apiCall("pause");
-        },
-        getPosition : function() {
-            return _this.apiCall("getSeek","return") || 0;
-        },
-        seek : function(pos) {
-            return _this.apiCall("seek",pos);
-        },
-        getMute : function() {
-            return _this.apiCall("getMute","return");
-        },
-        setMute : function(p) {
-            return _this.apiCall("setMute", p);
-        }
-    }
-
-    window.onReady = IriSP.wrap(this, this.ready);
-    window.onAllocineStateChange = IriSP.wrap(this, this.stateHandler);
-    window.onTime = IriSP.wrap(this, this.progressHandler);
-    
-    var _videoUrl = (
-        typeof options.directVideoPath == "string"
-        ? options.directVideoPath
-        : IriSP.get_aliased(IriSP.__jsonMetadata["medias"][0], ["href","url"])
-    );
-    var _flashVars = {
-        "streamFMS" : true,
-        "adVast" : false,
-        "lg" : "fr_cinecast",
-        "autoPlay" : options.autoPlay,
-        "directVideoTitle" : "",
-        "urlAcData" : options.urlAcData,
-        "directVideoPath" : _videoUrl,
-        "host" : "http://allocine.fr"
-    }
-    
-    if (typeof IriSP.__jsonMetadata["medias"][0].meta == "object" && typeof IriSP.__jsonMetadata["medias"][0].meta.subtitles == "string") {
-        _flashVars.subTitlePath = IriSP.__jsonMetadata["medias"][0].meta.subtitles;
-    }
-    
-
-    var params = {
-        "allowScriptAccess" : "always",
-        "wmode": "opaque",
-        "flashvars" : IriSP.jQuery.param(_flashVars),
-        "allowfullscreen" : true
-    };
-    var atts = {
-        id : this.container
-    };
-    swfobject.embedSWF(options.acPlayerUrl, this.container, options.width, options.height, "10", null, null, params, atts);
-
-};
-
-IriSP.PopcornReplacement.allocine.prototype = new IriSP.PopcornReplacement.player("", {});
-
-IriSP.PopcornReplacement.allocine.prototype.ready = function() {
-    this.player = document.getElementById(this.container);
-    this.player.addEventListener("onStateChange", "onAllocineStateChange");
-    this.player.cueVideoByUrl(this._options.video);
-    this.callbacks.onReady();
-};
-
-IriSP.PopcornReplacement.allocine.prototype.progressHandler = function(progressInfo) {
-    this.callbacks.onTime({
-        position: progressInfo.mediaTime
-    });
-}
-
-
-IriSP.PopcornReplacement.allocine.prototype.apiCall = function(_method, _arg) {
-    if (this.player) {
-        try {
-            if (typeof _arg == "undefined") {
-                return this.player.sendToActionScript(_method);
-            } else {
-                return this.player.sendToActionScript(_method, _arg);
-            }
-        } catch(e) {
-            console.error('Exception while requesting AcPlayer for "' + _method + (typeof _arg == "undefined" ? '' : '" with argument "' + _arg ) + '"\n', e);
-            return false;
-        }
-    } else {
-        return false;
-    }
-}
-
-IriSP.PopcornReplacement.allocine.prototype.stateHandler = function(state) {
-    console.log("stateHandler");
-    switch(state) {
-        case 1:
-            this.callbacks.onPlay();
-            break;
-
-        case 2:
-            this.callbacks.onPause();
-            break;
-
-        case 3:
-            this.callbacks.onSeek({
-                position: this.player.getCurrentTime()
-            });
-            break;
-
-        /*
-        case 5:
-            this.callbacks.onReady();
-            break;
-        */
-    }
-    
-};/* To wrap a player the develop should create a new class derived from
-the IriSP.PopcornReplacement.player and defining the correct functions */
-
-/** jwplayer player wrapper */
-IriSP.PopcornReplacement.dailymotion = function(container, options) {
-    console.log("Calling");
-    /* appel du parent pour initialiser les structures communes à tous les players */
-    IriSP.PopcornReplacement.player.call(this, container, options);   
-    
-    var _this = this;
-
-    /* Définition des fonctions de l'API -  */
-
-    this.playerFns = {
-        play : function() {
-            if (_this.player) {
-                return _this.player.playVideo();
-            } else {
-                return false;
-            }
-        },
-        pause : function() {
-            if (_this.player) {
-                return _this.player.pauseVideo();
-            } else {
-                return false;
-            }
-        },
-        getPosition : function() {
-            if (_this.player) {
-                return _this.player.getCurrentTime();
-            } else {
-                return 0;
-            }
-        },
-        seek : function(pos) {
-            if (_this.player) {
-                return _this.player.seekTo(pos);
-            } else {
-                return false;
-            }
-        },
-        getMute : function() {
-            if (_this.player) {
-                return _this.player.isMuted();
-            } else {
-                return false;
-            }
-        },
-        setMute : function(p) {
-            if (_this.player) {
-                if (p) {
-                    _this.player.mute();
-                }
-                else {
-                    _this.player.unMute();
-                }
-            }
-        },
-        getVolume : function() {
-            if (_this.player) {
-                return _this.player.getVolume() / 100;
-            } else {
-                return false;
-            }
-        },
-        setVolume : function(p) {
-            if (_this.player) {
-                _this.player.setVolume(Math.floor(100 * p));
-            }
-        },
-    }
-
-    window.onDailymotionPlayerReady = IriSP.wrap(this, this.ready);
-    window.onDailymotionStateChange = IriSP.wrap(this, this.stateHandler);
-    window.onDailymotionVideoProgress = IriSP.wrap(this, this.progressHandler);
-
-    var params = {
-        "allowScriptAccess" : "always",
-        "wmode": "opaque"
-    };
-    var atts = {
-        id : this.container
-    };
-    swfobject.embedSWF("http://www.dailymotion.com/swf?chromeless=1&enableApi=1", this.container, options.width, options.height, "8", null, null, params, atts);
-
-};
-
-IriSP.PopcornReplacement.dailymotion.prototype = new IriSP.PopcornReplacement.player("", {});
-
-IriSP.PopcornReplacement.dailymotion.prototype.ready = function() {
-    
-    this.player = document.getElementById(this.container);
-    
-    this.player.addEventListener("onStateChange", "onDailymotionStateChange");
-    this.player.addEventListener("onVideoProgress", "onDailymotionVideoProgress");
-    this.player.cueVideoByUrl(this._options.video);
-    
-    this.callbacks.onReady();
-};
-
-IriSP.PopcornReplacement.dailymotion.prototype.progressHandler = function(progressInfo) {
-    
-    this.callbacks.onTime({
-        position: progressInfo.mediaTime
-    });
-}
-
-IriSP.PopcornReplacement.dailymotion.prototype.stateHandler = function(state) {
-    
-    switch(state) {
-        case 1:
-            this.callbacks.onPlay();
-            break;
-
-        case 2:
-            this.callbacks.onPause();
-            break;
-
-        case 3:
-            this.callbacks.onSeek({
-                position: this.player.getCurrentTime()
-            });
-            break;
-
-        /*
-        case 5:
-            this.callbacks.onReady();
-            break;
-        */
-    }
-    
-};/* To wrap a player the develop should create a new class derived from 
-   the IriSP.PopcornReplacement.player and defining the correct functions */
-
-/** jwplayer player wrapper */
-IriSP.PopcornReplacement.jwplayer = function(container, options) {
-  /* appel du parent pour initialiser les structures communes à tous les players */
-  IriSP.PopcornReplacement.player.call(this, container, options);
-  
-  this.media.duration = options.duration; /* optional */
-  
-  /* Définition des fonctions de l'API -  */
-  this.playerFns = {
-    play: function() { return jwplayer(this.container).play(); },
-    pause: function() { return jwplayer(this.container).pause(); },
-    getPosition: function() { return jwplayer(this.container).getPosition(); },
-    seek: function(pos) { return jwplayer(this.container).seek(pos); },
-    getMute: function() { return jwplayer(this.container).getMute() },
-    setMute: function(p) { return jwplayer(this.container).setMute(p); },
-    getVolume: function() { return jwplayer(this.container).getVolume() / 100; },
-    setVolume: function(p) { return jwplayer(this.container).setVolume(Math.floor(100*p)); }
-  }
-
-  options.events = this.callbacks;
-
-  jwplayer(this.container).setup(options);
-};
-
-IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
-/* embed module - listens and relay hash changes to a parent window. */
-
-IriSP.EmbedModule = function(Popcorn, config, Serializer) {
-  IriSP.Module.call(this, Popcorn, config, Serializer);
-
-  window.addEventListener('message', IriSP.wrap(this, this.handleMessages), false);
-  this._Popcorn.listen("IriSP.Mediafragment.hashchange", IriSP.wrap(this, this.relayChanges));
-};
-
-IriSP.EmbedModule.prototype = new IriSP.Module();
-
-IriSP.EmbedModule.prototype.handleMessages = function(e) {
-  if (e.data.type === "hashchange") {
-    window.location.hash = e.data.value;    
-  }  
-};
-
-IriSP.EmbedModule.prototype.relayChanges = function(newHash) {
-  window.parent.postMessage({type: "hashchange", value: newHash}, "*"); 
-  return;
-};/* 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,this.advanceTime));
-  this._Popcorn.listen( "pause", IriSP.wrap(this,this.updateTime));
-  this._Popcorn.listen( "seeked", IriSP.wrap(this,this.updateTime));
-  this._Popcorn.listen( "IriSP.PolemicTweet.click", IriSP.wrap(this,this.updateAnnotation));
-  this._Popcorn.listen( "IriSP.SegmentsWidget.click", IriSP.wrap(this,this.updateAnnotation));
-  
-  window.onhashchange = IriSP.wrap(this, this.advanceTime);
-};
-
-IriSP.MediaFragment.prototype = new IriSP.Module();
-
-IriSP.MediaFragment.prototype.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) );
-                    
-                    /* we have to trigger this signal manually because of a
-                     bug in the jwplayer */
-                    this._Popcorn.trigger("seeked", parseFloat(offsettime));
-                    }
-                  } else if ( pageoffset.substring(0, 3) === "id=") {
-                    // annotation
-                    var annotationId = pageoffset.substring( 3 );
-                    // there's no better way than that because
-                    // of possible race conditions
-                    this._serializer.sync(IriSP.wrap(this, function() {
-                          this.lookupAnnotation.call(this, annotationId); 
-                          }));
-                  }
-              }
-};
-
-/** handler for the seeked signal. It may have or may have not an argument.
-    @param time if not undefined, the time we're seeking to 
-*/
-IriSP.MediaFragment.prototype.updateTime = function(time) {
-  if (this.mutex === true) {
-    return;
-  }
-
-  var history = window.history;
-  if ( !history.pushState ) {
-    return false;
-  }
-    
-  if (IriSP.null_or_undefined(time) || typeof(time) != "number") {
-    var ntime = this._Popcorn.currentTime().toFixed(2)
-  } else {
-    var ntime = time.toFixed(2);
-  }
-
-  // used to relay the new hash to the embedder
-  this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#t=" + ntime);
-  
-  splitArr = window.location.href.split( "#" )
-  history.replaceState( {}, "", splitArr[0] + "#t=" + ntime );
-};
-
-
-IriSP.MediaFragment.prototype.updateAnnotation = function(annotationId) {
-  var _this = this;
-  this.mutex = true;
-
-  var history = window.history;
-  if ( !history.pushState ) {
-    return false;
-  }
- 
-  
-  // used to relay the new hash to the embedder
-  this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#id=" + annotationId);
-  
-  splitArr = window.location.href.split( "#" )
-  history.replaceState( {}, "", splitArr[0] + "#id=" + annotationId);
-
-  
-  // reset the mutex afterwards to prevent the module from reacting to his own changes.
-  window.setTimeout(function() { _this.mutex = false }, 50);
-};
-
-// lookup and seek to the beginning of an annotation
-IriSP.MediaFragment.prototype.lookupAnnotation = function(annotationId) {
-  var _this = this;
-  this.mutex = true;
-
-  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);
-
-    /* we have to trigger this signal manually because of a
-     bug in the jwplayer */
-    this._Popcorn.trigger("seeked", annotation.begin / 1000);
-    this._Popcorn.trigger("IriSP.Mediafragment.showAnnotation", annotationId);
-  }
-  
-  window.setTimeout(function() { _this.mutex = false }, 50);
-};
-IriSP.AnnotationsListWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  this.__counter = 0;
-  this.__oldList = [];
-  this.searchRe = null;
-  this._ajax_cache = [];
-  var _this = this;
-  
-  this._Popcorn.listen("IriSP.search", function(searchString) {
-      _this.searchHandler(searchString);
-  });
-  this._Popcorn.listen("IriSP.search.closed", function() {
-      _this.searchHandler(false);
-  });
-  this._Popcorn.listen("IriSP.search.cleared", function() {
-      _this.searchHandler(false);
-  });
-};
-
-
-IriSP.AnnotationsListWidget.prototype = new IriSP.Widget();
-
-IriSP.AnnotationsListWidget.prototype.clear = function() {
-};
-
-IriSP.AnnotationsListWidget.prototype.clearWidget = function() {
-};
-
-IriSP.AnnotationsListWidget.prototype.searchHandler = function(searchString) {
-  this.searchRe = (searchString && searchString.length) ? IriSP.regexpFromText(searchString) : null;
-  if (this.ajax_mode && !this.cinecast_version) {
-      var _this = this,
-        _annotations = (
-            this.searchRe === null
-            ? this._ajax_cache
-            : IriSP.underscore.filter(this._ajax_cache, function(_a) {
-               return (_this.searchRe.test(_a.desc) || _this.searchRe.test(_a.title)); 
-            })
-        );
-    this.do_redraw(_annotations);
-    if (_annotations.length) {
-        this._Popcorn.trigger("IriSP.search.matchFound");
-      } else {
-        this._Popcorn.trigger("IriSP.search.noMatchFound");
-      }    
-  } else {
-      this.drawList();
-  }
-}
-
-/** effectively redraw the widget - called by drawList */
-IriSP.AnnotationsListWidget.prototype.do_redraw = function(list) {
-    var _html = IriSP.templToHTML(
-        IriSP.annotationsListWidget_template, {
-            annotations: list
-        }),
-        _this = this;
-      
-    this.selector.html(_html);
-    
-    this.selector.find('.Ldt-AnnotationsList-Tag-Li').click(function() {
-        _this._Popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().trim());
-    })
-    
-    if (this.searchRe !== null) {
-        this.selector.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description")
-            .each(function()  {
-                var _$ = IriSP.jQuery(this);
-                _$.html(_$.text().trim().replace(_this.searchRe, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
-            })
-    }
-};
-
-IriSP.AnnotationsListWidget.prototype.transformAnnotation = function(a) {
-    var _this = this;
-    return {
-        "id" : a.id,
-        "title": this.cinecast_version ? IriSP.get_aliased(a.meta, ['creator_name', 'creator']) : a.content.title,
-        "desc" : this.cinecast_version ? a.content.data : a.content.description,
-        "begin": IriSP.msToTime(a.begin),
-        "end" : IriSP.msToTime(a.end),
-        "thumbnail" : (typeof a.meta == "object" && typeof a.meta.thumbnail == "string") ? a.meta.thumbnail : this.default_thumbnail,
-        "url" : (typeof a.meta == "object" && typeof a.meta.url == "string") ? a.meta.url : null,
-        "created_at" :(typeof a.meta == "object" && typeof a.meta.created == "string") ? Date.parse(a.meta.created.replace(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}\:\d{2}\:\d{2}).*$/,"$2/$3/$1 $4 UTC+0000")) : null,
-        "tags": typeof a.tags == "object"
-            ? IriSP.underscore(a.tags)
-                .chain()
-                .map(function(_t) {
-                    if (typeof _t == "string") {
-                        return _t.replace(/^.*:/,'#');
-                    } else {
-                        if (typeof _t['id-ref'] != "undefined") {
-                            var _f = IriSP.underscore.find(_this._serializer._data.tags, function(_tag) {
-                                return _tag.id == _t['id-ref'];
-                            });
-                            if (typeof _f != "undefined") {
-                                return IriSP.get_aliased(_f.meta, ['dc:title', 'title']);
-                            }
-                        }
-                    }
-                    return null;
-                })
-                .filter(function(_t) {
-                    return _t !== null && _t !== ""
-                })
-                .value()
-            : []
-    }    
-}
-
-/** draw the annotation list */
-IriSP.AnnotationsListWidget.prototype.drawList = function(force_redraw) {
-  var _this = this;
-  
-//  var view_type = this._serializer.getContributions();
-  var annotations = this._serializer._data.annotations;
-  var currentTime = this._Popcorn.currentTime();
-  var list = [];
-
-/*  if (typeof(view_type) === "undefined") {    
-    return;
-} */
-  for (i = 0; i < annotations.length; i++) {
-    var obj = this.transformAnnotation(annotations[i]);
-    obj.iterator = i;
-    obj.distance = Math.abs((annotations[i].end + annotations[i].begin) / 2000 - currentTime);
-    if (!this.cinecast_version || annotations[i].type == "cinecast:UserAnnotation") {
-        list.push(obj);
-    }
-    
-  }
-  
-    if (this.searchRe !== null) {
-        list = list.filter(function(_a) {
-            return (_this.searchRe.test(_a.desc) || _this.searchRe.test(_a.title)); 
-        });
-        if (list.length) {
-            this._Popcorn.trigger("IriSP.search.matchFound");
-          } else {
-            this._Popcorn.trigger("IriSP.search.noMatchFound");
-          }
-    }
-  list = IriSP.underscore(list)
-    .chain()
-    .sortBy(function(_o) {
-        return _o.distance;
-    })
-    .first(10)
-    .sortBy(function(_o) {
-        return (_this.cinecast_version ? - _o.created_at : _o.iterator);
-    })
-    .value();
-  var idList = IriSP.underscore.pluck(list, "id").sort();
-
-  if (!IriSP.underscore.isEqual(this.__oldList, idList) || this.lastSearch !== this.searchRe || typeof(force_redraw) !== "undefined") {
-    this.do_redraw(list);
-    this.__oldList = idList;
-    this.lastSearch = this.searchRe;
-  }
-   /* save for next call */
-  
-  
-};
-
-IriSP.AnnotationsListWidget.prototype.ajaxRedraw = function(timecode) {
-
-  /* the seeked signal sometimes passes an argument - depending on if we're using
-     our popcorn lookalike or the real thing - if it's the case, use it as it's
-     more precise than currentTime which sometimes contains the place we where at */
-  if (IriSP.null_or_undefined(timecode) || typeof(timecode) != "number") {
-     var tcode = this._Popcorn.currentTime();     
-   } else {
-     var tcode = timecode;     
-  }
-   
-  
-  /* the platform gives us a special url - of the type : http://path/{{media}}/{{begin}}/{{end}}
-     we double the braces using regexps and we feed it to mustache to build the correct url
-     we have to do that because the platform only knows at run time what view it's displaying.
-  */
-     
-  var media_id = this.currentMedia()["id"];
-  var duration = this.getDuration();
-  
-  var begin_timecode = (Math.floor(tcode) - 300) * 1000;
-  if (begin_timecode < 0)
-    begin_timecode = 0;
-    
-  var end_timecode = (Math.floor(tcode) + 300) * 1000;
-  if (end_timecode > duration)
-    end_timecode = duration;
-  
-  var templ = Mustache.to_html(this.ajax_url, {media: media_id, begin: begin_timecode,
-                                 end: end_timecode});
-
-  /* we create on the fly a serializer to get the ajax */
-  var serializer = new IriSP.JSONSerializer(IriSP.__dataloader, templ);
-  serializer.sync(IriSP.wrap(this, function(json) { this.processJson(json, serializer) }));
-};
-
-/** process the received json - it's a bit hackish */
-IriSP.AnnotationsListWidget.prototype.processJson = function(json, serializer) {
-  /* FIXME: DRY the whole thing */
-  var annotations = serializer._data.annotations;
-  if (IriSP.null_or_undefined(annotations))
-    return;
-  
-  /*
-  commented in case we wanted to discriminate against some annotation types.
-  var view_types = serializer.getIds("Contributions");
-  */
-  var l = [];
-  
-  var media = this.currentMedia()["id"];
-  
-  for (i = 0; i < annotations.length; i++) {
-    var obj = this.transformAnnotation(annotations[i])
-      if (typeof obj.url == "undefined" || !obj.url) {
-          /* only if the annotation isn't present in the document create an
-             external link */
-          if (this.annotations_ids.indexOf(obj.id.toLowerCase()) == -1) {
-            // braindead url; jacques didn't want to create a new one in the platform,
-            // so we append the cutting id to the url.
-            obj.url = this.project_url + "/" + media + "/" + 
-                         annotations[i].meta.project + "/" +
-                         annotations[i].meta["id-ref"] + '#id=' + annotations[i].id;
-                         
-            // obj.url = document.location.href.split("#")[0] + "/" + annotation.meta.project;
-          }
-          }
-      l.push(obj);
-  }
-  this._ajax_cache = l;
-  this.do_redraw(l);
-};
-IriSP.AnnotationsListWidget.prototype.draw = function() {
-  
-  /* build a table of the annotations present in the document for faster 
-     lookup
-  */
-  this.annotations_ids = IriSP.underscore(this._serializer._data.annotations).map(function(_a) {
-    return _a.id.toLowerCase();
-  });
-  
-  var _this = this;
-    
-    if (!this.ajax_mode || this.cinecast_version) {
-        var _throttled = IriSP.underscore.throttle(function() {
-            _this.drawList();
-        }, 1500);
-        _throttled();
-        this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", _throttled);
-        this._Popcorn.listen("timeupdate", _throttled);
-        if (this.cinecast_version) {
-            window.setInterval(function() {
-                var _tmpSerializer = new IriSP.JSONSerializer(IriSP.__dataloader,  _this._config.metadata.src, true);
-                _tmpSerializer.sync(function(json) {
-                    _this.annotations_ids = IriSP.underscore(_this._serializer._data.annotations).map(function(_a) {
-                      return _a.id.toLowerCase();
-                    });
-                    IriSP.underscore(json.annotations).each(function(_a) {
-                        var _j = _this.annotations_ids.indexOf(_a.id);
-                        if (_j == -1) {
-                            _this._serializer._data.annotations.push(_a);
-                            _this.annotations_ids.push(_a.id);
-                        } else {
-                            _this._serializer._data.annotations[_j] = _a;
-                        }
-                        _throttled();
-                    });
-                }, true); // true is for force_refresh
-            },this.refresh_interval);
-        }
-  } else {
-    /* update the widget when the video has finished loading and when it's seeked and paused */
-    this._Popcorn.listen("seeked", IriSP.wrap(this, this.ajaxRedraw));
-    this._Popcorn.listen("loadedmetadata", IriSP.wrap(this, this.ajaxRedraw));
-    this._Popcorn.listen("paused", IriSP.wrap(this, this.ajaxRedraw));
-    
-    this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.ajaxRedraw));
-  }
-
-};/* Internationalization for this widget */
-
-IriSP.i18n.addMessages(
-    {
-        "fr": {
-            "keywords": "Mots-clés"
-        },
-        "en": {
-            "keywords": "Keywords"
-        }
-    }
-);
-
-IriSP.AnnotationsWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  /* flag used when we're creating an annotation */
-  this._hidden = false;
-};
-
-
-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 =  "";
-    var begin = +annotation.begin / 1000;
-    var end = +annotation.end / 1000;
-    var duration = this.getDuration();
-    var tags = "";
-    
-    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);
-    
-    
-    if (!IriSP.null_or_undefined(annotation.tags) && !IriSP.null_or_undefined(this._serializer._data.tags)) {
-      /* save the tag id and keywords in a unique structure */
-      var tag_list = {};
-      for (var i = 0; i < this._serializer._data.tags.length; i++) {
-        var id = this._serializer._data.tags[i]["id"];
-        var keyword = IriSP.get_aliased(this._serializer._data.tags[i]["meta"], ["dc:title", "title"]);
-
-        tag_list[id] = keyword;
-      }
-
-      /* then browse the list of defined tags for the current annotation */
-      for (var i = 0; i < annotation.tags.length; i++) {
-        if (tag_list.hasOwnProperty(annotation.tags[i]["id-ref"]))
-          tags += tag_list[annotation.tags[i]["id-ref"]] + ", ";
-      }
-    }
-    
-    tags = IriSP.i18n.getMessage("keywords") + ": " + tags.slice(0, tags.length - 2);
-    
-    this.selector.find(".Ldt-SaKeywords").text(tags);
-    
-    // update sharing buttons
-    var url = document.location.href + "#id=" + annotation.id;
-    this.selector.find(".Ldt-fbShare").attr("href", IriSP.mkFbUrl(url, this.share_text));
-    this.selector.find(".Ldt-TwShare").attr("href", IriSP.mkTweetUrl(url, this.share_text));
-    this.selector.find(".Ldt-GplusShare").attr("href", IriSP.mkGplusUrl(url, this.share_text));
-};
-
-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);
-
-  this._Popcorn.listen("IriSP.AnnotationsWidget.show", 
-                        IriSP.wrap(this, this.show));
-  this._Popcorn.listen("IriSP.AnnotationsWidget.hide", 
-                        IriSP.wrap(this, this.hide));
- 
-  var legal_ids = [];
-  if (typeof(this._serializer.getChapitrage()) !== "undefined")
-    legal_ids.push(this._serializer.getChapitrage());
-  else 
-    legal_ids = this._serializer.getNonTweetIds();
-  
-  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 (typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
-          && !IriSP.underscore.include(legal_ids, annotation.meta["id-ref"])) {
-        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.AnnotationsWidget.prototype.hide = function() {
-  if (this._hidden == false) {
-    this.selector.hide();
-    this._hidden = true;
-  }
-};
-
-IriSP.AnnotationsWidget.prototype.show = function() {
-  if (this._hidden == true) {
-    this.selector.show();
-    this._hidden = false;
-  }
-};IriSP.ArrowWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-
-  this._oldAnnotation = null;
-  this._blockArrow = false;
-};
-
-
-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));
-  this._Popcorn.listen("IriSP.ArrowWidget.blockArrow", IriSP.wrap(this, this.blockArrow));
-  this._Popcorn.listen("IriSP.ArrowWidget.releaseArrow", IriSP.wrap(this, this.releaseArrow));
-  
-};
-
-IriSP.ArrowWidget.prototype.timeUpdateHandler = function(percents) {
-  if (this._blockArrow)
-    return;
-  
-  var currentTime = this._Popcorn.currentTime();
-  var currentAnnotation = this._serializer.currentChapitre(currentTime);
-  if (IriSP.null_or_undefined(currentAnnotation)) {
-    var c_annots = this._serializer.currentAnnotation(currentTime)
-    if (c_annots.length != 0)
-      var currentAnnotation = c_annots[0]; // FIXME : use the others ?
-    else
-      return;
-  }
-  
-  /* 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.getDuration() / 1000;
-    var middle_time = (begin + end) / 2;
-    var percents = middle_time / duration;
-
-    // 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 pixels = percents * totalWidth;
-    var correction = (27 / 2);
-    var corrected_pixels = pixels - correction;
-    
-    /* make sure that the arrow is aligned with the pattern
-       of the widget under it */
-    if (corrected_pixels % 3 != 0)
-      corrected_pixels -= (corrected_pixels % 3 - 1);
-    
-    /* don't move out of the screen */
-    if (corrected_pixels <= 0)
-      corrected_pixels = 0;
-    
-    if (corrected_pixels <= 15) {      
-      this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
-                                                .addClass("Ldt-arrowLeftEdge"); 
-    } else if (corrected_pixels >= totalWidth - 25) {
-           this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
-                                                .addClass("Ldt-arrowRightEdge"); 
-    } else {
-      this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
-                                                .addClass("Ldt-arrowCenter"); 
-    }
-    
-    this.selector.children(".Ldt-arrowWidget").animate({"left" : corrected_pixels + "px"});
-
-    this._oldAnnotation = currentAnnotation;
-  }
-};
-
-/** Block the arrow for instance when the user is annotating */
-IriSP.ArrowWidget.prototype.blockArrow = function() {
-  this._blockArrow = true;
-};
-
-IriSP.ArrowWidget.prototype.releaseArrow = function() {
-  this._blockArrow = false;   
-};
-/* Internationalization for this widget */
-
-IriSP.i18n.addMessages(
-    {
-        "en": {
-            "submit": "Submit",
-            "add_keywords": "Add keywords",
-            "add_polemic_keywords": "Add polemic keywords",
-            "your_name": "Your name",
-            "type_here": "Type your annotation here.",
-            "wait_while_processed": "Please wait while your request is being processed...",
-            "error_while_contacting": "An error happened while contacting the server. Your annotation has not been saved.",
-            "empty_annotation": "Your annotation is empty. Please write something before submitting.",
-            "annotation_saved": "Thank you, your annotation has been saved.",
-            "share_annotation": "Would you like to share it on social networks ?",
-            "share_on": "Share on",
-            "more_tags": "More tags"
-        },
-        "fr": {
-            "submit": "Envoyer",
-            "add_keywords": "Ajouter des mots-clés",
-            "add_polemic_keywords": "Ajouter des mots-clés polémiques",
-            "your_name": "Votre nom",
-            "type_here": "Rédigez votre annotation ici.",
-            "wait_while_processed": "Veuillez patienter pendant le traitement de votre requête...",
-            "error_while_contacting": "Une erreur s'est produite en contactant le serveur. Votre annotation n'a pas été enregistrée",
-            "empty_annotation": "Votre annotation est vide. Merci de rédiger un texte avant de l'envoyer.",
-            "annotation_saved": "Merci, votre annotation a été enregistrée.",
-            "share_annotation": "Souhaitez-vous la partager sur les réseaux sociaux ?",
-            "share_on": "Partager sur",
-            "more_tags": "Plus de mots-clés"
-        }
-    }
-);
-
-IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  this._hidden = true;
-                         
-  if (!IriSP.null_or_undefined(IriSP.user)) {
-      if (!IriSP.null_or_undefined(IriSP.user.avatar)) {
-        this.user_avatar = IriSP.user.avatar;
-      }
-      if (!IriSP.null_or_undefined(IriSP.user.name)) {
-        this.user_name = IriSP.user.name;
-      }
-  }
-  
-  /* variables to save the current position of the slicer */
-  if (this.cinecast_version) {
-    this.sliceLeft = 0;
-    this.sliceWidth = 0;
-  }
-};
-
-
-IriSP.createAnnotationWidget.prototype = new IriSP.Widget();
-
-IriSP.createAnnotationWidget.prototype.clear = function() {
-    this.selector.find(".Ldt-SaTitle").text("");
-    this.selector.find(".Ldt-SaDescription").text("");
-    this.selector.find(".Ldt-SaKeywordText").text("");
-};
-
-IriSP.createAnnotationWidget.prototype.draw = function() {
-    var _this = this;
-    if (typeof this.remote_tags == "object") {
-        IriSP.jQuery.getJSON((typeof this.remote_tags.alias == "string" ? this.remote_tags.alias : this.remote_tags.url), function(_json) {
-            _this.tags = _json.tags;
-            _this.drawCallback();
-        });
-    } else {
-        this.drawCallback();
-    }
-}
-
-IriSP.createAnnotationWidget.prototype.drawCallback = function() {
-  var _this = this;
-  
-  var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, 
-                                           this);
-  
-	this.selector.append(annotationMarkup);
-  
-  if (!this.cinecast_version)
-    this.selector.hide();
-  else {
-    this.showStartScreen();
-  }
-  
-  if (this.random_tags) {
-      this.selector.find(".Ldt-createAnnotation-keywords li").hide();
-      this.showMoreTags();
-      this.selector.find('.Ldt-createAnnotation-moar-keywordz').click(function() {
-          _this.showMoreTags();
-      })
-  }
-  // Add onclick event to both polemic and keywords buttons
-  
-  this.selector.find(".Ldt-createAnnotation-keyword-button, .Ldt-createAnnotation-polemic-button").click(function() {
-      _this.addKeyword(IriSP.jQuery(this).text());
-      return false;
-  });
-  
-  // js_mod is a custom event because there's no simple way to test for a js
-  // change in a textfield.                    
-  this.selector.find(".Ldt-createAnnotation-Description")
-               .bind("propertychange keyup input paste click js_mod", IriSP.wrap(this, this.handleTextChanges));
-               
-  /* the cinecast version of the player is supposed to pause when the user clicks on the button */
-
-  /* the cinecast version expects the user to comment on a defined segment.
-     As the widget is always shown, we need a way to update it's content as
-     time passes. We do this like we did with the annotationsWidget : we schedule
-     a .code start function which will be called at the right time.
-  */
-  if (this.cinecast_version) {
-    var legal_ids;
-    if (typeof(this._serializer.getChapitrage()) !== "undefined")
-      legal_id = this._serializer.getChapitrage();
-    else 
-      legal_id = this._serializer.getNonTweetIds()[0];
-    
-    var annotations = this._serializer._data.annotations;
-    var i;
-  
-    for (i in annotations) {     
-      var annotation = annotations[i];
-      if (typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
-            && legal_id !== annotation.meta["id-ref"]) {
-          continue;
-      }
-      
-      code = {start: annotation.begin / 1000, end: annotation.end / 1000,
-              onStart: function(annotation) { return function() {
-                      if (typeof(annotation.content) !== "undefined")
-                        _this.selector.find(".Ldt-createAnnotation-Title").html(annotation.content.title);
-
-                      _this._currentAnnotation = annotation;
-                      var beginTime = IriSP.msToTime(annotation.begin);
-                      var endTime = IriSP.msToTime(annotation.end);
-                      var timeTemplate = IriSP.templToHTML("- ({{begin}} - {{ end }})", {begin: beginTime, end: endTime });
-                      _this.selector.find(".Ldt-createAnnotation-TimeFrame").html(timeTemplate);
-              } }(annotation)
-            };
-      
-      this._Popcorn.code(code);
-    }
-  }
-  
-  this.selector.find(".Ldt-createAnnotation-submitButton").click(IriSP.wrap(this, this.handleButtonClick));
-  
-  if (!this.cinecast_version) {
-    this._Popcorn.listen("IriSP.PlayerWidget.AnnotateButton.clicked", 
-                          IriSP.wrap(this, this.handleAnnotateSignal));
-    
-    // handle clicks on the cancel button too.
-    this.selector.find(".Ldt-createAnnotation-Minimize").click(IriSP.wrap(this, 
-      function() {
-        // we've got to simulate the pressing of the button because there's no
-        // other way to minimize the widget and show the widgets that were hidden
-        // same time
-        this._Popcorn.trigger("IriSP.PlayerWidget.AnnotateButton.clicked");
-      }
-    ));
-  }
-};
-
-IriSP.createAnnotationWidget.prototype.showMoreTags = function() {
-    for (var j=0; j < this.random_tags; j++) {
-        var _jq = this.selector.find(".Ldt-createAnnotation-keywords li:hidden");
-        if (_jq.length > 1) {
-            IriSP.jQuery(_jq[Math.floor(_jq.length*Math.random())]).show();
-        } else {
-            _jq.show();
-            break;
-        }     
-    }
-    if (this.selector.find(".Ldt-createAnnotation-keywords li:hidden").length == 0) {
-        this.selector.find('.Ldt-createAnnotation-moar-keywordz').hide();
-    }
-}
-
-/* Handles adding keywords and polemics */
-IriSP.createAnnotationWidget.prototype.addKeyword = function(_keyword) {
-    var _field = this.selector.find(".Ldt-createAnnotation-Description"),
-        _rx = IriSP.regexpFromText(_keyword),
-        _contents = _field.val();
-    _contents = ( _rx.test(_contents)
-        ? _contents.replace(_rx,"").replace("  "," ").trim()
-        : _contents.trim() + " " + _keyword
-    );
-    _field.val(_contents.trim()).trigger("js_mod");
-}
-
-/** handles clicks on the annotate button. Works only for the non-cinecast version */
-IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() {
-  
-  if (this._hidden == false && this._state == 'startScreen') {
-    this.selector.hide();
-    this._hidden = true;
-    
-    // free the arrow.
-    this._Popcorn.trigger("IriSP.ArrowWidget.releaseArrow");
-    this._Popcorn.trigger("IriSP.SliceWidget.hide");
-    this._Popcorn.trigger("IriSP.AnnotationsWidget.show");
-    
-  } else {
-    this._Popcorn.trigger("IriSP.AnnotationsWidget.hide");
-    this.showStartScreen();    
-    this.selector.show();
-    this._hidden = false;
-    var currentTime = this._Popcorn.currentTime();
-    
-    // block the arrow.
-    this._Popcorn.trigger("IriSP.ArrowWidget.blockArrow");
-    
-    var duration = this.getDuration();
-        
-    var currentChapter = this._serializer.currentChapitre(currentTime);
-
-    if (IriSP.null_or_undefined(currentChapter)) {      
-      var left = this.selector.width() / 2;
-      var width = this.selector.width() / 10;
-    } else {
-      var left = (currentChapter.begin / duration) * this.selector.width();
-      var width = (currentChapter.end / duration) * this.selector.width() - left;
-    }
-    
-    // slider position and length is kept in percents.
-    this.sliceLeft = (left / this.selector.width()) * 100;
-    this.sliceWidth = (width / this.selector.width()) * 100;
-    
-    this._Popcorn.trigger("IriSP.SliceWidget.position", [left, width]);
-    this._Popcorn.listen("IriSP.SliceWidget.zoneChange", IriSP.wrap(this, this.handleSliderChanges));
-    this._Popcorn.trigger("IriSP.SliceWidget.show");
-    
-    if (!IriSP.null_or_undefined(currentChapter)) {
-      this.selector.find(".Ldt-createAnnotation-Title").html(currentChapter.content.title);
-
-      this._currentcurrentChapter = currentChapter;
-      var beginTime = IriSP.msToTime(currentChapter.begin);
-      var endTime = IriSP.msToTime(currentChapter.end);
-      var timeTemplate = IriSP.templToHTML("- ({{begin}} - {{ end }})", {begin: beginTime, end: endTime });
-      this.selector.find(".Ldt-createAnnotation-TimeFrame").html(timeTemplate);
-    }
-  }
-};
-
-
-/** watch for changes in the textfield and change the buttons accordingly */
-IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) {
-  var contents = this.selector.find(".Ldt-createAnnotation-Description").val();
-  if (this.cinecast_version) {
-      this._Popcorn.pause();
-  }
-  this.selector.find(".Ldt-createAnnotation-btnblock button").each(function() {
-      var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text());
-      if (_rx.test(contents)) {
-          IriSP.jQuery(this).parent().addClass("Ldt-createAnnotation-active-button");
-      } else {
-          IriSP.jQuery(this).parent().removeClass("Ldt-createAnnotation-active-button");
-      }
-  });
-  
-};
-
-IriSP.createAnnotationWidget.prototype.showStartScreen = function() {
-  this.selector.find(".Ldt-createAnnotation-screen").hide();
-  this.selector.find(".Ldt-createAnnotation-startScreen").show();
-  
-  var jqTextfield = this.selector.find(".Ldt-createAnnotation-Description"); // handle on the textfield. used for the closure
-  
-  /* test if the browser supports the placeholder attribute */
-  if (!IriSP.null_or_undefined(jqTextfield.get(0).placeholder)) {
-    jqTextfield.attr("placeholder", IriSP.i18n.getMessage('type_here')); 
-  } else {
-    jqTextfield.val(IriSP.i18n.getMessage('type_here'));
-    jqTextfield.one("click", IriSP.wrap(this, function() { jqTextfield.val(""); }));    
-  }
-  
- 
-  
-  this._state = "startScreen";
-};
-
-IriSP.createAnnotationWidget.prototype.showWaitScreen = function() {
-  this.selector.find(".Ldt-createAnnotation-screen").hide();
-  this.selector.find(".Ldt-createAnnotation-waitScreen").show();
-  this._state = "waitScreen";
-};
-
-IriSP.createAnnotationWidget.prototype.showErrorScreen = function() {
-  this.selector.find(".Ldt-createAnnotation-screen").hide();
-  this.selector.find(".Ldt-createAnnotation-errorScreen").show();
-  this._state = "errorScreen";
-  var _this = this;
-  window.setTimeout(function() { _this.showStartScreen(); }, 2000);
-};
-
-/** update show the final screen with links to share the created annotation */
-IriSP.createAnnotationWidget.prototype.showEndScreen = function(annotation) {
-  this.selector.find(".Ldt-createAnnotation-screen").hide();
-  
-  if (this.cinecast_version) {
-    this.selector.find(".Ldt-createAnnotation-Title").parent().show();      
-  }
-
-  var url = ( (typeof annotation.meta == "object" && typeof annotation.meta.url == "string" && annotation.meta.url.length)
-    ? annotation.meta.url
-    : ( document.location.href + "#id=" + annotation.id ) );
-  var twStatus = IriSP.mkTweetUrl(url);
-  var gpStatus = IriSP.mkGplusUrl(url);
-  var fbStatus = IriSP.mkFbUrl(url);
-  
-  this.selector.find(".Ldt-createAnnotation-endScreen-TweetLink").attr("href", twStatus);
-  this.selector.find(".Ldt-createAnnotation-endScreen-FbLink").attr("href", fbStatus);
-  this.selector.find(".Ldt-createAnnotation-endScreen-GplusLink").attr("href", gpStatus);
-          
-  this.selector.find(".Ldt-createAnnotation-endScreen").show();
-  this._state = "endScreen";
-};
-
-/** handle clicks on "send annotation" button */
-IriSP.createAnnotationWidget.prototype.handleButtonClick = function(event) {
-  var _this = this;
-  var textfield = this.selector.find(".Ldt-createAnnotation-Description");
-  var contents = textfield.val();
-  
-  if (contents === "") {  
-    if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) {
-      this.selector.find(".Ldt-createAnnotation-Container")
-                   .after(IriSP.templToHTML(IriSP.createAnnotation_errorMessage_template));
-      textfield.css("background-color", "#d93c71");      
-    } else {      
-      this.selector.find(".Ldt-createAnnotation-errorMessage").show();
-    }
-
-      textfield.one("js_mod propertychange keyup input paste", IriSP.wrap(this, function() {
-                      var contents = textfield.val();
-                      
-                      if (contents !== "") {
-                        this.selector.find(".Ldt-createAnnotation-errorMessage").hide();
-                        textfield.css("background-color", "");
-                      }
-                   }));
-  } else {
-    this.showWaitScreen();
-    
-    this.sendLdtData(contents, function(annotation) {
-                      if (_this.cinecast_version) {
-                          if (_this._Popcorn.media.paused)
-                            _this._Popcorn.play();
-                      }
-
-                      if (_this._state == "waitScreen") {
-                        _this.showEndScreen(annotation);
-                        if (_this.cinecast_version) {
-                          window.setTimeout(function() { _this.showStartScreen(); }, 5000);
-                        }
-                      }
-                      // hide the slicer widget
-                      if (!_this.cinecast_version) {                      
-                        _this._Popcorn.trigger("IriSP.SliceWidget.hide");
-                      }           
-                    });
-  }
-};
-
-IriSP.createAnnotationWidget.prototype.handleSliderChanges = function(params) {
-  this.sliceLeft = params[0];
-  this.sliceWidth = params[1];
-};
-
-IriSP.createAnnotationWidget.prototype.sendLdtData = function(contents, callback) {
-  var _this = this;
-  var apiJson = {
-      format : "http://advene.org/ns/cinelab/",
-      annotations : [
-        {}
-        ],
-        meta: {}};
-  var annotation = apiJson.annotations[0];
-  
-  annotation.media = this.currentMedia()["id"];
-  
-  if (this.cinecast_version) {   
-      annotation.begin = Math.round(this._Popcorn.currentTime() * 1000);
-      annotation.end = annotation.begin;      
-  } else {
-    var duration = this.getDuration();    
-    annotation.begin = +((duration * (this.sliceLeft / 100)).toFixed(0));
-    annotation.end = +((duration * ((this.sliceWidth + this.sliceLeft) / 100)).toFixed(0));
-  }
-
-  // boundary checks
-  annotation.begin = Math.max(0, annotation.begin);
-  annotation.end = Math.min(this.getDuration(), annotation.end);
-  
-  annotation.type = ( this.cinecast_version ? "cinecast:UserAnnotation" : ( this._serializer.getContributions() || "" ));
-  if (typeof(annotation.type) === "undefined")
-    annotation.type = "";
-  
-  annotation.type_title = "Contributions";
-  annotation.content = {};
-  annotation.content.data = contents;
-  if (this.cinecast_version) {
-      var _extract = IriSP.underscore(this._serializer._data.annotations)
-          .filter(function(_a) {
-              return (_a.begin <= annotation.begin && _a.end >= annotation.begin && _a.type == "cinecast:MovieExtract");
-          })
-      if (_extract.length) {
-          annotation.extract = _extract[0].id;
-      }
-  }
-  
-  var meta = apiJson.meta;
-  
-  
-  var _username = this.selector.find(".Ldt-createAnnotation-userName").val();
-  meta.creator = (
-      (_username && _username.length)
-      ? _username
-      : (
-          (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name))
-          ? IriSP.user.name
-          : "Anonymous user"
-      )
-  );
-  
-  meta.created = Date().toString();
-  
-  var _tags = [];
-  IriSP._(this.tags).each(function(_v) {
-      var _rx = IriSP.regexpFromText(_v.meta.description);
-        if (_rx.test(contents)) {
-            _tags.push(_v.id);
-        }
-  });
-
-  if (typeof this.remote_tags == "object") {
-     _tags = IriSP._(_tags).map(function(_t) {
-         return _this.remote_tags.id + ':' + _t
-     });
-    if (typeof apiJson.imports == "undefined") {
-       apiJson.imports = [];
-    }
-    apiJson.imports.push({
-        "id" : this.remote_tags.id,
-        "url" : this.remote_tags.url
-    })
-  }
-  annotation.tags = IriSP.underscore.uniq(_tags);
-  
-  var jsonString = JSON.stringify(apiJson);
-  var project_id = this._serializer._data.meta.id;
-  
-  //TODO: extract magic url
-  var url = Mustache.to_html(this.api_endpoint_template,
-                              {id: project_id});
-                          
-  IriSP.jQuery.ajax({
-      url: url,
-      type: this.api_method,
-      contentType: 'application/json',
-      data: jsonString,               
-      //dataType: 'json',
-      success: IriSP.wrap(this, function(json, textStatus, XMLHttpRequest) {                   
-                    /* add the annotation to the annotation and tell the world */
-                    var annotation = json.annotations[0];
-                    
-                    if (!this.cinecast_version) {
-                    /* if the media doesn't have a contributions line, we need to add one */
-                        if (typeof(this._serializer.getContributions()) === "undefined") {
-                          /* set up a basic view */
-                          var tmp_view = {"dc:contributor": "perso", "dc:creator": "perso", "dc:title": "Contributions",
-                                          "id": json.annotations[0].type}
-    
-                          
-                            IriSP.get_aliased(this._serializer._data, ["annotation_types", "annotation-types"]).push(tmp_view);
-                        }
-                        
-                        delete annotation.tags;
-                        annotation.content.description = annotation.content.data;
-                        annotation.content.title = "";
-                        delete annotation.content.data;
-                        annotation.id = json.annotations[0].id;
-    
-                        annotation.meta = meta;
-                        annotation.meta["id-ref"] = json.annotations[0]["type"];
-                    } else {
-                        annotation.type = "cinecast:UserAnnotation";
-                    }
-                    // everything is shared so there's no need to propagate the change
-                    var _an_ids = IriSP.underscore(this._serializer._data.annotations).map(function(_a) {
-                        return _a.id.toLowerCase();
-                    });
-                    if (_an_ids.indexOf(annotation.id.toLowerCase()) == -1) {
-                        _this._serializer._data.annotations.push(annotation);
-                    }
-                    
-                    _this._Popcorn.trigger("IriSP.createAnnotationWidget.addedAnnotation", annotation);
-                    this.selector.find(".Ldt-createAnnotation-Description").val("").trigger("js_mod");
-                    callback(annotation);
-      }), 
-      error: 
-              function(jqXHR, textStatus, errorThrown) { 
-                            console.log("an error occured while contacting " 
-                            + url + " and sending " + jsonString + textStatus ); 
-                            _this.showErrorScreen(); } });
-};IriSP.HelloWorldWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-}
-
-IriSP.HelloWorldWidget.prototype = new IriSP.Widget();
-
-IriSP.HelloWorldWidget.prototype.draw = function() {
-    this.selector
-        .html('Hello, world')
-        .css({
-            "text-align" : "center",
-            "padding": "10px 0",
-            "font-size" : "14px"
-        });
-        
-    console.log(this);
-}
-/* Internationalization for this widget */
-
-IriSP.i18n.addMessages(
-    {
-        "en": {
-            "play_pause": "Play/Pause",
-            "mute_unmute": "Mute/Unmute",
-            "play": "Play",
-            "pause": "Pause",
-            "mute": "Mute",
-            "unmute": "Unmute",
-            "annotate": "Annotate",
-            "search": "Search",
-            "elapsed_time": "Elapsed time",
-            "total_time": "Total time",
-            "volume": "Volume",
-            "volume_control": "Volume control"
-        },
-        "fr": {
-            "play_pause": "Lecture/Pause",
-            "mute_unmute": "Couper/Activer le son",
-            "play": "Lecture",
-            "pause": "Pause",
-            "mute": "Couper le son",
-            "unmute": "Activer le son",
-            "annotate": "Annoter",
-            "search": "Rechercher",
-            "elapsed_time": "Durée écoulée",
-            "total_time": "Durée totale",
-            "volume": "Niveau sonore",
-            "volume_control": "Réglage du niveau sonore"
-        }
-    }
-);
-
-
-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 playerTempl = IriSP.templToHTML(IriSP.player_template, this._config);
-  this.selector.append(playerTempl);		
-	
-  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.volumeUpdater));
-
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeDisplayUpdater));  
-  // update the time display for the first time.
-  this._Popcorn.listen("loadedmetadata", 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._Popcorn.listen("IriSP.search.triggeredSearch", IriSP.wrap(this, this.triggeredSearch));
-  
-  
-  this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); });
-  this.selector.find(".Ldt-CtrlAnnotate").click(function() 
-                                            { self._Popcorn.trigger("IriSP.PlayerWidget.AnnotateButton.clicked"); });
-  this.selector.find(".Ldt-CtrlSearch").click(function() { self.searchButtonHandler.call(self); });
-  
-	var _volctrl = this.selector.find(".Ldt-Ctrl-Volume-Control");
-    this.selector.find('.Ldt-CtrlSound')
-        .click(function() { self.muteHandler.call(self); } )
-        .mouseover(function() {
-            _volctrl.show();
-        })
-        .mouseout(function() {
-            _volctrl.hide();
-        });
-    _volctrl.mouseover(function() {
-        _volctrl.show();
-    }).mouseout(function() {
-        _volctrl.hide();
-    });
-  
-  /*
-  var searchButtonPos = this.selector.find(".Ldt-CtrlSearch").position();
-  var searchBox = Mustache.to_html(IriSP.search_template, {margin_left : searchButtonPos.left + "px"});
-  this.selector.find(".Ldt-CtrlSearch").after(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.selector.find(".Ldt-Ctrl-Volume-Cursor").draggable({
-      axis: "x",
-      drag: function(event, ui) {
-          var _vol = Math.max(0, Math.min( 1, ui.position.left / (ui.helper.parent().width() - ui.helper.outerWidth())));
-          ui.helper.attr("title",IriSP.i18n.getMessage('volume')+': ' + Math.floor(100*_vol) + '%');
-          self._Popcorn.volume(_vol);
-      },
-      containment: "parent"
-  });
- 
- setTimeout(function() {
-     self.volumeUpdater();
- }, 1000); /* 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.getDuration() / 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 ){
-    /* the background sprite is changed by adding/removing the correct classes */
-    this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('play'));
-    this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PauseState").addClass("Ldt-CtrlPlay-PlayState");
-  } else {
-    this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('pause'));
-    this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PlayState").addClass("Ldt-CtrlPlay-PauseState");
-  }  
-
-  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() {
-  this._Popcorn.mute(!this._Popcorn.muted());
-};
-
-IriSP.PlayerWidget.prototype.volumeUpdater = function() {
-    var _muted = this._Popcorn.muted(),
-        _vol = this._Popcorn.volume();
-    if (_vol === false) {
-        _vol = .5;
-    }
-    var _soundCtl = this.selector.find(".Ldt-CtrlSound");
-    _soundCtl.removeClass("Ldt-CtrlSound-Mute Ldt-CtrlSound-Half Ldt-CtrlSound-Full");
-    if (_muted) {        
-        _soundCtl.attr("title", IriSP.i18n.getMessage('unmute'))
-            .addClass("Ldt-CtrlSound-Mute");    
-    } else {
-        _soundCtl.attr("title", IriSP.i18n.getMessage('mute'))
-            .addClass(_vol < .5 ? "Ldt-CtrlSound-Half" : "Ldt-CtrlSound-Full" )
-    }
-    var _cursor = this.selector.find(".Ldt-Ctrl-Volume-Cursor");
-    _cursor.css({
-        "left": ( _muted ? 0 : Math.floor(_vol * (_cursor.parent().width() - _cursor.outerWidth())) ) + "px"
-    })
-};
-
-IriSP.PlayerWidget.prototype.showSearchBlock = function() {
-  var self = this;
-  
-  if (this._searchBlockOpen == false) {
-    this.selector.find(".LdtSearch").show("blind", { direction: "horizontal"}, 100);
-    this.selector.find(".LdtSearchInput").css('background-color','#fff');
-   
-    this._searchBlockOpen = true;           
-    this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } );
-    this.selector.find(".LdtSearchInput").focus();
-    
-    // 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");     
-	}
-};
-
-IriSP.PlayerWidget.prototype.hideSearchBlock = function() {
- if (this._searchBlockOpen == true) {
-    this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
-    this.selector.find(".LdtSearchInput").attr('value','');
-    this.selector.find(".LdtSearch").hide("blind", { direction: "horizontal"}, 75);
-    
-    // unbind the watcher event.
-    this.selector.find(".LdtSearchInput").unbind('keypress set');
-    this._searchBlockOpen = false;
-
-    this._positiveMatch = false;
-    
-    this._Popcorn.trigger("IriSP.search.closed");
-	}
-};
-
-/** react to clicks on the search button */
-IriSP.PlayerWidget.prototype.searchButtonHandler = function() {
-  var self = this;
-
-  /* show the search field if it is not shown */
-  if ( this._searchBlockOpen == false ) {
-    this.showSearchBlock();
-    this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue);      
-    this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural.
-	} else {
-    this.hideSearchBlock();
-  }
-};
-
-/** 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");
-};
-
-/** react to an IriSP.Player.triggeredSearch - that is, when
-    a widget ask the PlayerWidget to do a search on his behalf */
-IriSP.PlayerWidget.prototype.triggeredSearch = function(searchString) {
-  this.showSearchBlock();
-  this.selector.find(".LdtSearchInput").attr('value', searchString);      
-  this._Popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural.
-};
-
-
-/* 
- *   
- *  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  ::
-
-/** the polemic widget */
-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 = {};
-  
-  this.oldSearchMatches = [];
-};
-
-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.getDuration();      // timescale width 
-    var frameLength   = lineSize / frameSize;    // frame timescale  
-    var timeline;
-    var colors  = new Array("","#1D973D","#036AAE","#CE0A15","#C5A62D","#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); return; });
-      
-      function loaded_callback (json) {
-      var view_type = this._serializer.getTweets();
-
-      
-      if (typeof(view_type) === "undefined") {
-        var view_type = this._serializer.getTweetIds()[0];
-        if (typeof(view_type) === "undefined") {
-          // default to guessing if nothing else works.
-          var view = json.views[0];
-          
-          if(typeof(view.annotation_types) !== "undefined") {
-            /* we need to be backward compatible with the old files which used to
-               feature only two lines : Chapitrage and Tweets. We've added a
-               "Contributions" line so we need to discriminate against that */
-            if (view.annotation_types.length === 2 && typeof(this._serializer.getContributions()) === "undefined") {
-              var view_type = view.annotation_types[1];
-            } else {
-              console.log("PolemicWidget: invalid file - minimizing");
-              return;
-            }
-          }      
-        }
-      }
-      
-      // Make and define the Raphael area
-      this.paper = Raphael(document.getElementById(this._id), this._config.width, this._config.height);
-      
-      // 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));
-      this.selector.mouseleave(IriSP.wrap(this, function() { self.TooltipWidget.hide.call(self.TooltipWidget); }));
-      this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.sliderUpdater));
-      this._Popcorn.listen("IriSP.Mediafragment.showAnnotation", IriSP.wrap(this, this.showAnnotation));
-      
-      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"] === view_type) {
-            
-            var MyTJson = {},
-                _source = IriSP.get_aliased(item.meta, ['dc:source', 'source']);
-            if (_source !== null) {
-              var MyTJson = JSON.parse(_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;
-      var newHeight = TweetHeight * max + 10;
-
-      
-      if (newHeight > this.height) {
-        this.paper.setSize(this.width, newHeight);
-        this.height = newHeight;
-        console.log("resizeing");
-      }
-      
-  
-      // 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.height - addEheight;
-                  
-                  if (this.yMax > y) {
-                    this.yMax = y;
-                  }
-                  
-                  /* some tweets seem to be duplicated - so we make a check before
-                     creating a new rect */
-                  if (this.svgElements.hasOwnProperty(frames[i].mytweetsID[k].cinecast_id))
-                    continue;
-                  
-                  var e = this.paper.rect(x, y, frameSize - margin, TweetHeight /* height */)
-                                    .attr({stroke:"#00","stroke-width":0.1,  fill: colors[j]});  
-                  
-                  addEheight += TweetHeight;
-                  
-                  /* stick a lot of things into e because that's the easiest way
-                     to do it */
-                  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;
-                  
-                  IriSP.jQuery(e.node).mouseenter(function(element) { return function (_e) {                    
-                        self.TooltipWidget.show.call(self.TooltipWidget, element.title, element.attr("fill"), element.attrs.x + element.attrs.width / 2, element.attrs.y - 2);
-                        element.displayed = true;
-                        self._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", {
-                            "widget" : "StackGraphWidget",
-                            "type": "mousemove",
-                            "x": _e.pageX,
-                            "y": _e.pageY,
-                            "annotation_id": element.id
-                        });
-                  }}(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.height).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.height).attr({fill:"#D4D5D5", stroke: "none", opacity: 1});
-      
-      // the small white line displayed over the slider.
-      this.sliderTip = this.paper.rect(0, 0, 1, this.height).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();
-    }
-    
-
-}
-
-/** update the positionMarker as time passes */
-IriSP.PolemicWidget.prototype.sliderUpdater = function() {
-
-    var time = +this._Popcorn.currentTime();
-    var duration = this.getDuration();
-    
-    this.paperSlider.attr("width", time * (this.width / (duration / 1000)));
-        
-    this.sliderTip.attr("x", time * (this.width / (duration / 1000)));
-};
-
-/** reacts to IriSP.search events */    
-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");
-  }
-
-  
-  // decrease the opacity of the other elements.
-  for (var id in this.svgElements) {
-    var e = this.svgElements[id];
-    e.attr({fill: e.color, opacity: 0.4});   
-  }
-  
-
-  for (var id in matches) {    
-    if (this.svgElements.hasOwnProperty(id)) {
-      var e = this.svgElements[id];
-      this.svgElements[id].attr({fill: "#fc00ff", opacity: 1});
-    }
-  }
-
-  this.oldSearchMatches = matches;
-};
-
-/** reacts to IriSP.search.cleared messages */
-IriSP.PolemicWidget.prototype.searchFieldClearedHandler = function() {
-  for (var id in this.svgElements) {
-    var e = this.svgElements[id];
-    e.attr({fill: e.color, opacity: 1});
-  }
-};
-
-/** reacts to IriSP.search.closed messages by clearing the highlighted elements */
-IriSP.PolemicWidget.prototype.searchFieldClosedHandler = function() {
-  for (var id in this.svgElements) {
-    var e = this.svgElements[id];
-    e.attr({fill: e.color, opacity: 1});
-  }
- 
-};
-   
-IriSP.PolemicWidget.prototype.showAnnotation = function(id) {
-  if (this.svgElements.hasOwnProperty(id)) {
-    var e = this.svgElements[id];
-    this.TooltipWidget.show(e.title, e.attr("fill"), e.x - 103, e.y - 160);
-  }
-};   
-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); });
-  
-  this.defaultColors = ["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"]
-};
-
-IriSP.SegmentsWidget.prototype = new IriSP.Widget();
-
-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));
-  
-  this.positionMarker = this.selector.find(".Ldt-SegmentPositionMarker");
-  
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.positionUpdater));
-  var duration = this.getDuration();
-  
-  if (this.cinecast_version) {
-      var segments_annotations = IriSP.underscore.filter(
-          this._serializer._data.annotations,
-          function(_a) {
-              return _a.type == "cinecast:MovieExtract";
-          }
-      );
-  }
-  else {
-
-      var view_type = this._serializer.getChapitrage();
-      if (typeof(view_type) === "undefined") {
-        view_type = this._serializer.getNonTweetIds()[0];  
-      }
-    
-      
-      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 _w = this.selector.width();
-  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 id = annotation.id;
-        
-    var startPixel = Math.floor(_w * (begin / duration));
-
-    var endPixel = Math.floor(_w * (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 = this.cinecast_version
-        ? annotation.content.data
-        : annotation.content.title + ( annotation.content.title ? "<br />" : "" ) + annotation.content.description.replace(/(^.{120,140})[\s].+$/,'$1&hellip;');
-    
-    var thumbUrl = annotation.meta.thumbnail || '';
-    
-    var hexa_color = typeof(annotation.content.color) !== "undefined"
-        ? '#' + IriSP.DEC_HEXA_COLOR(annotation.content.color)
-        : typeof(annotation.color) !== "undefined"
-            ? '#' + IriSP.DEC_HEXA_COLOR(annotation.color)
-            : this.defaultColors[i % this.defaultColors.length];
-
-    /*
-    if (hexa_color === "FFCC00")
-      hexa_color = "333";
-    */
-    if (hexa_color.length == 5)
-      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), "thumbnailUrl": thumbUrl});
-
-        
-    this.selector.append(annotationTemplate);
-    
-    /* add a special class to the last segment and change its border */
-    if (annotation.id === lastSegment.id) {
-        IriSP.jqId(id).addClass("Ldt-lastSegment").css("border-color", hexa_color);  
-    }
-   }
-    // react to mediafragment messages.
-    this._Popcorn.listen("IriSP.Mediafragment.showAnnotation", 
-        function(id, divTitle) {
-        
-            var divObject = IriSP.jqId(id);
-            if (divObject.length) {
-            divObject.fadeTo(0,1);
-            var offset_x = divObject.position().left + divObject.outerWidth() / 2;
-            self.TooltipWidget.show(divObject.attr("title"), IriSP.jQuery(this).css("background-color"), offset_x, 0);
-            IriSP.jQuery(document).one("mousemove", function() { divObject.fadeTo(0,.5);
-                                                                self.TooltipWidget.hide(); });
-        }
-      });
-      
-    this.selector.find(".Ldt-iri-chapter")
-        .fadeTo(0, .5)
-        .click(function() {
-            self._Popcorn.trigger("IriSP.SegmentsWidget.click", this.id);
-            self._Popcorn.currentTime(IriSP.jQuery(this).attr("data-seek"));
-        })
-        .mouseover( function(event) {
-            var divObject = IriSP.jQuery(this);
-            divObject.fadeTo(0,1);
-            var offset_x = divObject.position().left + divObject.outerWidth() / 2;
-            var thumb = divObject.attr("thumbnail-url");
-            var txt = divObject.attr("title") + (thumb && thumb.length ? '<br /><img src="' + thumb + '" />' : '');
-            self.TooltipWidget.show(txt, IriSP.jQuery(this).css("background-color"), offset_x, 0);
-        })
-        .mouseout(function(){
-            IriSP.jQuery(this).fadeTo(0,.5);
-            self.TooltipWidget.hide();
-        });
-};
-
-/* restores the view after a search */
-IriSP.SegmentsWidget.prototype.clear = function() {
-  this.selector.children(".Ldt-iri-chapter").fadeTo(0,.5);
-};
-
-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.getDuration() / 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.SegmentsWidget.prototype.showAnnotation = function() {
-
-};
-/** A widget to create a new segment */
-IriSP.SliceWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  
-};
-
-IriSP.SliceWidget.prototype = new IriSP.Widget();
-
-IriSP.SliceWidget.prototype.draw = function() {
-  var templ = Mustache.to_html(IriSP.sliceWidget_template);
-  this.selector.append(templ);
-  
-  this.sliceZone = this.selector.find(".Ldt-sliceZone");
-  
-  /* global variables used to keep the position and width
-     of the zone.
-  */  
-  this.zoneLeft = 0;
-  this.zoneWidth = 0;
-  
-  this.leftHandle = this.selector.find(".Ldt-sliceLeftHandle");
-  this.rightHandle = this.selector.find(".Ldt-sliceRightHandle");
-
-  var left = this.selector.offset().left;
-  var top = this.selector.offset().top;
-
-  // a bug in firefox makes it use the wrong format
-  if (!IriSP.jQuery.browser.mozilla) {
-    // contain the handles correctly - we cannot set
-    // containment: parent because it wouldn't allow to select the 
-    // whole slice, so we have to compute a box in which the slice is
-    // allowed to move.
-    var containment = [left - 8, top, this.selector.width() + left, top];
-
-    // var containment = [left - 16, top, this.selector.width() + left - 8, top];
-    this.leftHandle.draggable({axis: "x",
-    drag: IriSP.wrap(this, this.leftHandleDragged),  
-    containment: containment
-    });
-
-    containment = [left, top, this.selector.width() + left, top];
-    // containment = [left, top, this.selector.width() + left - 8, top];
-    this.rightHandle.draggable({axis: "x",
-    drag: IriSP.wrap(this, this.rightHandleDragged),    
-    containment: containment
-    });
-  
-  } else { // firefox
-    // we need to define a containment specific to firefox.
-    
-    var containment = [left - 16, top, this.selector.width() + left - 8, top];
-    this.leftHandle.draggable({axis: "x",
-    drag: IriSP.wrap(this, this.leftHandleDragged),  
-    containment: containment
-    });
-
-    containment = [left, top, this.selector.width() + left - 8, top];
-    this.rightHandle.draggable({axis: "x",
-    drag: IriSP.wrap(this, this.rightHandleDragged),    
-    containment: containment
-    });
-  }
-  
-  this.leftHandle.css("position", "absolute");
-  this.rightHandle.css("position", "absolute");
-  
-  this._Popcorn.listen("IriSP.SliceWidget.position", 
-                        IriSP.wrap(this, this.positionSliceHandler));
-  
-  this._Popcorn.listen("IriSP.SliceWidget.show", IriSP.wrap(this, this.show));
-  this._Popcorn.listen("IriSP.SliceWidget.hide", IriSP.wrap(this, this.hide));
-  this.selector.hide();
-};
-
-/** responds to an "IriSP.SliceWidget.position" message
-    @param params an array with the first element being the left distance in
-           percents and the second element the width of the slice in pixels
-*/        
-IriSP.SliceWidget.prototype.positionSliceHandler = function(params) {
-  left = params[0];
-  width = params[1];
-  
-  this.zoneLeft = left;
-  this.zoneWidth = width;
-  this.sliceZone.css("left", left + "px");
-  this.sliceZone.css("width", width + "px");
-  this.leftHandle.css("left", (left - 7) + "px");
-  this.rightHandle.css("left", left + width + "px");
-  
-  this._leftHandleOldLeft = left - 7;
-  this._rightHandleOldLeft = left + width;
-};
-
-/** handle a dragging of the left handle */
-IriSP.SliceWidget.prototype.leftHandleDragged = function(event, ui) {
-  /* we have a special variable, this._leftHandleOldLeft, to keep the
-     previous position of the handle. We do that to know in what direction
-     is the handle being dragged
-  */
-  
-  var currentX = this.leftHandle.offset().left;
-  var rightHandleX = Math.floor(this.rightHandle.position()["left"]);
-  
-  var container_offset = this.selector.offset().left;
-
-  if (Math.floor(ui.position.left) >= rightHandleX - 7) {
-    /* prevent the handle from moving past the right handle */
-    ui.position.left = rightHandleX - 7;
-  }
-
-  this.zoneWidth = rightHandleX - Math.floor(ui.position.left) - 7;  
-  this.zoneLeft = Math.floor(ui.position.left) + 8;
-  
-  this.sliceZone.css("width", this.zoneWidth);
-  this.sliceZone.css("left", this.zoneLeft + "px");
-  
-  this._leftHandleOldLeft = ui.position.left;  
-  this.broadcastChanges();
-    
-};
-
-/** handle a dragging of the right handle */
-IriSP.SliceWidget.prototype.rightHandleDragged = function(event, ui) { 
-  /* we have a special variable, this._leftHandleOldLeft, to keep the
-     previous position of the handle. We do that to know in what direction
-     is the handle being dragged
-  */
-  
-  var currentX = this.leftHandle.position()["left"];
-  var leftHandleX = Math.floor(this.leftHandle.position()["left"]);
-
-  var container_offset = this.selector.offset().left + this.selector.width();
-  
-  if (Math.floor(ui.position.left) < leftHandleX + 7) {
-    /* prevent the handle from moving past the left handle */
-    ui.position.left = leftHandleX + 7;
-  }
-
-  this.zoneWidth = Math.floor(ui.position.left) - (leftHandleX + 7);    
-  
-  this.sliceZone.css("width", this.zoneWidth);
-  //this.sliceZone.css("left", this.zoneLeft + "px");
-  this._rightHandleOldLeft = Math.floor(this._rightHandleOldLeft);  
-  this.broadcastChanges();
-};
-
-/** tell to the world that the coordinates of the slice have
-    changed 
-*/
-IriSP.SliceWidget.prototype.broadcastChanges = function() {
-  var leftPercent = (this.zoneLeft / this.selector.width()) * 100;
-  var zonePercent = (this.zoneWidth / this.selector.width()) * 100;
-
-  this._Popcorn.trigger("IriSP.SliceWidget.zoneChange", [leftPercent, zonePercent]);  
-};
-
-IriSP.SliceWidget.prototype.show = function() {
-  this.selector.show();
-};
-
-IriSP.SliceWidget.prototype.hide = function() {
-  this.selector.hide();
-};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.getDuration() / 1000;
-  var percents = time / duration;
-  
-  /* we do these complicated calculations to center exactly
-     the position Marker */
-
-  var divWidth = this.selector.width();
-  var pixels = Math.floor(this.selector.width() * percents);
-  var positionMarker_width = this.positionMarker.width();
-  var correction = (positionMarker_width / 2);
-
-  /* check that we don't leave the left side */
-  var newPos = pixels - correction;
-  if (newPos <= 0)
-    newPos = 0;
-  
-  /* check that we don't leave the right side */
-  var rightEdgePos = pixels + 1 * correction;
-
-  if (rightEdgePos >= divWidth)
-    newPos = divWidth - 1 * correction - 1;
-  
-  this.sliderForeground.css("width", pixels + "px");
-  this.positionMarker.css("left", newPos + "px");
-
-};
-
-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.getDuration() / 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.getDuration() / 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),
-                                     this.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.originalEvent.pageX - parentOffset.left;
-
-  var duration = this.getDuration() / 1000;
-  var newTime = ((relX / width) * duration).toFixed(2);
-  this._Popcorn.currentTime(newTime);
-  
-  this.draggingOngoing = false;
-};
-
-/** @class The constructor for the sparkline widget */
-IriSP.SparklineWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-
-  this._oldAnnotation = null;
-  this._results = [];
-  
-  this.slices = this._config.slices || Math.floor(this.width/20);
-  if (!this.width) {
-      this.width = this.selector.width();
-  }
-  if (!this.height) {
-      this.height = 40;
-  }
-  this.selector.css("height", this.height + "px");
-  if (this._config.background) {
-      this.selector.css("background", this._config.background);
-  }
-};
-
-
-IriSP.SparklineWidget.prototype = new IriSP.Widget();
-
-IriSP.SparklineWidget.prototype.clear = function() {
-
-};
-
-/** draw the sparkline using jquery sparkline */
-IriSP.SparklineWidget.prototype.draw = function() {
-    this.duration = this.getDuration();
-    this.paper = new Raphael(this.selector[0], this.width, this.height);
-    var _this = this;
-  
-  var views = this._serializer._data.views;
-  var stat_view;
-  if (!IriSP.null_or_undefined(views)) {
-    for (var i = 0; i < views.length; i++) {
-      var view = views[i];
-      if (view.id === "stat") {
-          stat_view = view;
-          break;
-      }
-    }
-  }
-  
-    var _ = IriSP.underscore;
-  // If we've found the correct view, feed the directly the data from the view
-  // to jquery sparkline. Otherwise, compute it ourselves.
-    if (!IriSP.null_or_undefined(stat_view)) {
-        //console.log("sparklinewidget : using stats embedded in the json");
-        var _results = stat_view.meta.stat.split(",");      
-    } else {
-        var _annotations = this._serializer._data.annotations;
-        if (this.cinecast_version) {
-            _annotations = _(_annotations).filter(function(_a) {
-                return _a.type !== "cinecast:MovieExtract";
-            });
-        }
-        var _sliceDuration = Math.floor( this.duration / this.slices),
-            _results = _(_.range(this.slices)).map(function(_i) {
-                return _(_annotations).filter(function(_a){
-                    return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration)
-                }).length;
-            });
-    }
-    var _max = Math.max(1, _(_results).max()),
-        _h = this.height,
-        _scale = (_h - this.lineWidth) / _max,
-        _width = this.width / this.slices,
-        _y = _(_results).map(function(_v) {
-            return _h - (_scale * _v);
-        }),
-        _d = _(_y).reduce(function(_memo, _v, _k) {
-               return _memo + ( _k
-                   ? 'C' + (_k * _width) + ' ' + _y[_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v
-                   : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v )
-            },'') + 'L' + this.width + ' ' + _y[_y.length - 1],
-        _d2 = _d + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height;
-    this.paper.path(_d2).attr({
-        "stroke" : "none",
-        "fill" : this.fillColor
-    });
-         
-    this.paper.path(_d).attr({
-        "fill" : "none",
-        "stroke" : this.lineColor,
-        "stroke-width" : this.lineWidth
-    });
-  
-    this.rectangleProgress = this.paper.rect(0,0,0,this.height)
-        .attr({
-            "stroke" : "none",
-            "fill" : "#808080",
-            "opacity" : .3
-        });
-    this.ligneProgress = this.paper.path("M0 0L0 "+this.height).attr({"stroke":"#ff00ff", "line-width" : 2});
-  // save the results in an array so that we can re-use them when a new annotation
-  // is added.
-  this._results = _results;
-  
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler));
-//  this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.handleNewAnnotation));
-  
-  this.selector.click(IriSP.wrap(this, this.clickHandler));  
-};
-
-/** react to a timeupdate event */
-IriSP.SparklineWidget.prototype.timeUpdateHandler = function() {
-    var _currentTime = this._Popcorn.currentTime(),
-        _x = (1000 * _currentTime / this.duration) * this.width;
-    this.rectangleProgress.attr({
-        "width" : _x
-    });
-    this.ligneProgress.attr({
-        "path" : "M" + _x + " 0L" + _x + " " + this.height
-    });
-                                  
-}
-
-/** handle clicks on the widget */
-IriSP.SparklineWidget.prototype.clickHandler = function(event) {
-  var relX = event.pageX - this.selector.offset().left;
-  var newTime = ((relX / this.width) * this.duration/1000).toFixed(2);
-    
-  this._Popcorn.trigger("IriSP.SparklineWidget.clicked", newTime);
-  this._Popcorn.currentTime(newTime);
-};
-
-/** react when a new annotation is added */
-IriSP.SparklineWidget.prototype.handleNewAnnotation = function(annotation) {
-//  var num_columns = this._results.length;
-//  var duration = this._serializer.getDuration();
-//  var time_step = Math.round(duration / num_columns); /* the time interval between two columns */
-//  var begin = +annotation.begin;
-//  var end = +annotation.end;
-//  
-//  /* increment all the values between the beginning and the end of the annotation */
-//  var index_begin = Math.floor(begin / time_step);
-//  var index_end = Math.floor(end / time_step);
-//  
-//  for (var i = index_begin; i < Math.min(index_end, this._results.length); i++) {
-//    this._results[i]++;
-//  }
-//  
-//  this.selector.find(".Ldt-sparkLine").sparkline(this._results, {lineColor: "#7492b4", fillColor: "#aeaeb8",
-//                                                           spotColor: "#b70056",
-//                                                           width: this.width, height: this.height});
-};IriSP.StackGraphWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-}
-
-IriSP.StackGraphWidget.prototype = new IriSP.Widget();
-
-IriSP.StackGraphWidget.prototype.draw = function() {
-    var _ = IriSP._;
-    this.height =  this._config.height || 50;
-    this.width = this.selector.width();
-    this.slices = this._config.slices || ~~(this.width/(this.streamgraph ? 20 : 5));
-    _(this.tags).each(function(_a) {
-        _a.regexp = new RegExp(_(_a.keywords).map(function(_k) {
-            return _k.replace(/([\W])/gm,'\\$1');
-        }).join("|"),"im")
-    });
-    this.paper = new Raphael(this.selector[0], this.width, this.height);
-    this.groups = [];
-    this.duration = this.getDuration();
-    
-    var _annotationType = this._serializer.getTweets(),
-        _sliceDuration = ~~ ( this.duration / this.slices),
-        _annotations = this._serializer._data.annotations,
-        _groupedAnnotations = _(_.range(this.slices)).map(function(_i) {
-            return _(_annotations).filter(function(_a){
-                return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration)
-            });
-        }),
-        _max = IriSP._(_groupedAnnotations).max(function(_g) {
-            return _g.length
-        }).length,
-        _scale = this.height / _max,
-        _width = this.width / this.slices,
-        _showTitle = !this._config.excludeTitle,
-        _showDescription = !this._config.excludeDescription;
-    
-    
-    var _paths = _(this.tags).map(function() {
-        return [];
-    });
-    _paths.push([]);
-    
-    for (var i = 0; i < this.slices; i++) {
-        var _group = _groupedAnnotations[i];
-        if (_group) {
-            var _vol = _(this.tags).map(function() {
-                return 0;
-            });
-            for (var j = 0; j < _group.length; j++){
-           var _txt = (_showTitle ? _group[j].content.title : '') + ' ' + (_showDescription ? _group[j].content.description : '')
-                var _tags = _(this.tags).map(function(_tag) {
-                        return (_txt.search(_tag.regexp) == -1 ? 0 : 1)
-                    }),
-                    _nbtags = _(_tags).reduce(function(_a,_b) {
-                        return _a + _b;
-                    }, 0);
-                if (_nbtags) {
-                    IriSP._(_tags).each(function(_v, _k) {
-                        _vol[_k] += (_v / _nbtags);
-                    });
-                }
-            }
-            var _nbtags = _(_vol).reduce(function(_a,_b) {
-                    return _a + _b;
-                }, 0),
-                _nbneutre = _group.length - _nbtags,
-                _h = _nbneutre * _scale,
-                _base = this.height - _h;
-            if (!this.streamgraph) {
-                this.paper.rect(i * _width, _base, _width - 1, _h ).attr({
-                    "stroke" : "none",
-                    "fill" : this.defaultcolor
-                });
-            }
-           _paths[0].push(_base);
-            for (var j = 0; j < this.tags.length; j++) {
-                _h = _vol[j] * _scale;
-                _base = _base - _h;
-                if (!this.streamgraph) {
-                    this.paper.rect(i * _width, _base, _width - 1, _h ).attr({
-                        "stroke" : "none",
-                        "fill" : this.tags[j].color
-                    });
-                }
-                _paths[j+1].push(_base);
-            }
-            this.groups.push(_(_vol).map(function(_v) {
-                return _v / _group.length;
-            }))
-        } else {
-            for (var j = 0; j < _paths.length; j++) {
-                _paths[j].push(this.height);
-            }
-            this.groups.push(_(this.tags).map(function() {
-                return 0;
-            }));
-        }
-    }
-    
-    if (this.streamgraph) {
-        for (var j = _paths.length - 1; j >= 0; j--) {
-            var _d = _(_paths[j]).reduce(function(_memo, _v, _k) {
-               return _memo + ( _k
-                   ? 'C' + (_k * _width) + ' ' + _paths[j][_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v
-                   : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v )
-            },'') + 'L' + this.width + ' ' + _paths[j][_paths[j].length - 1] + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height;
-            this.paper.path(_d).attr({
-                "stroke" : "none",
-                "fill" : (j ? this.tags[j-1].color : this.defaultcolor)
-            });
-        }
-    }
-    this.rectangleFocus = this.paper.rect(0,0,_width,this.height)
-        .attr({
-            "stroke" : "none",
-            "fill" : "#ff00ff",
-            "opacity" : 0
-        })
-    this.rectangleProgress = this.paper.rect(0,0,0,this.height)
-        .attr({
-            "stroke" : "none",
-            "fill" : "#808080",
-            "opacity" : .3
-        });
-    this.ligneProgress = this.paper.path("M0 0L0 "+this.height).attr({"stroke":"#ff00ff", "line-width" : 2})
-    
-    this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler));
-    var _this = this;
-    this.selector
-        .click(IriSP.wrap(this, this.clickHandler))
-        .mousemove(function(_e) {
-            _this.updateTooltip(_e);
-            // Trace
-            var relX = _e.pageX - _this.selector.offset().left;
-            var _duration = _this.getDuration();
-            var _time = parseInt((relX / _this.width) * _duration);
-            _this._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", {
-                "widget" : "StackGraphWidget",
-                "type": "mousemove",
-                "x": _e.pageX,
-                "y": _e.pageY,
-                "time": _time
-            });
-
-        })
-        .mouseout(function() {
-            _this.TooltipWidget.hide();
-            _this.rectangleFocus.attr({
-                "opacity" : 0
-            })
-        })
-}
-
-IriSP.StackGraphWidget.prototype.timeUpdateHandler = function() {
-    var _currentTime = this._Popcorn.currentTime(),
-        _x = (1000 * _currentTime / this.duration) * this.width;
-    this.rectangleProgress.attr({
-        "width" : _x
-    });
-    this.ligneProgress.attr({
-        "path" : "M" + _x + " 0L" + _x + " " + this.height
-    })
-}
-
-IriSP.StackGraphWidget.prototype.clickHandler = function(event) {
-  /* Ctrl-C Ctrl-V'ed from another widget
-  */
-
-  var relX = event.pageX - this.selector.offset().left;
-  var newTime = ((relX / this.width) * this.duration/1000).toFixed(2);
-  this._Popcorn.trigger("IriSP.StackGraphWidget.clicked", newTime);
-  this._Popcorn.currentTime(newTime);                                 
-};
-
-IriSP.StackGraphWidget.prototype.updateTooltip = function(event) {
-    var _segment = Math.max(0,Math.min(this.groups.length - 1, Math.floor(this.slices * (event.pageX - this.selector.offset().left)/this.width))),
-        _valeurs = this.groups[_segment],
-        _width = this.width / this.slices,
-        _html = '<ul style="list-style: none; margin: 0; padding: 0;">' + IriSP._(this.tags).map(function(_tag, _i) {
-            return '<li style="clear: both;"><span style="float: left; width: 10px; height: 10px; margin: 2px; background: '
-                + _tag.color
-                + ';"></span>'
-                + ~~(100 * _valeurs[_i])
-                + '% de '
-                + _tag.description
-                + '</li>';
-        }).join('') + '</ul>';
-    this.TooltipWidget._shown = false; // Vraiment, on ne peut pas ouvrir le widget s'il n'est pas encore ouvert ?
-    this.TooltipWidget.show('','',(_segment + .5)* this.width / this.slices, 0);
-    this.TooltipWidget.selector.find(".tip").html(_html);
-    this.rectangleFocus.attr({
-        "x" : _segment * _width,
-        "opacity" : .4
-    })
-}
-
-IriSP.TagCloudWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-}
-
-IriSP.TagCloudWidget.prototype = new IriSP.Widget();
-
-IriSP.TagCloudWidget.prototype.draw = function() {
-    
-    var _urlRegExp = /https?:\/\/[0-9a-zA-Z\.%\/-_]+/g,
-        _stopWords = [
-            'aussi', 'and', 'avec', 'aux', 'bien', 'car', 'cette', 'comme', 'dans', 'donc', 'des', 'elle', 'encore', 'entre', 'est',
-            'être', 'eux', 'faire', 'fait', 'http', 'ici', 'ils', 'les', 'leur', 'leurs', 'mais', 'mes', 'même', 'mon', 'notre',
-            'non', 'nos', 'nous', 'ont', 'par', 'pas', 'peu', 'peut', 'plus', 'pour', 'que', 'qui', 'sans', 'ses' ,'son', 'sont', 'sur',
-            'tes', 'très', 'the', 'ton', 'tous', 'tout', 'une', 'votre', 'vos', 'vous' ],
-        _regexpword = /[^\s\.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g,
-        _words = {},
-        _showTitle = !this._config.excludeTitle,
-        _showDescription = !this._config.excludeDescription,
-        _excludePattern = this._config.excludePattern || null,
-        _tagCount = this._config.tagCount || 30;
-    if (typeof this._config.excludeWords !== "undefined" && this._config.excludeWords.length) {
-        IriSP._(this._config.excludeWords).each(function(_w) {
-            _stopWords.push(_w.toLowerCase());
-        });
-    }
-    
-    IriSP._(this._serializer._data.annotations).each(function(_annotation) {
-       if (_annotation.content && _annotation.content.description) {
-           var _txt = (_showTitle ? _annotation.content.title : '') + ' ' + (_showDescription ? _annotation.content.description : '')
-           IriSP._(_txt.toLowerCase().replace(_urlRegExp, '').match(_regexpword)).each(function(_mot) {
-               if (_stopWords.indexOf(_mot) == -1 && (_excludePattern == null || !_excludePattern.test(_mot))) {
-                   _words[_mot] = 1 + (_words[_mot] || 0);
-               }
-           })
-       } 
-    });
-    
-    _words = IriSP._(_words)
-        .chain()
-        .map(function(_v, _k) {
-            return {
-                "word" : _k,
-                "count" : _v
-            }
-        })
-        .filter(function(_v) {
-            return _v.count > 2;
-        })
-        .sortBy(function(_v) {
-            return - _v.count;
-        })
-        .first(_tagCount)
-        .value();
-    var _max = _words[0].count,
-        _min = Math.min(_words[_words.length - 1].count, _max - 1),
-        _scale = 16 / Math.sqrt(_max - _min),
-        _this = this,
-        _html = '<ul>'
-            + IriSP._(_words)
-                .chain()
-                .shuffle()
-                .map(function(_word) {
-                    var _size = 10 + _scale * Math.sqrt(_word.count - _min);
-                    return '<li class="Ldt-TraceMe" style="font-size:'
-                        + _size
-                        + 'px;">'
-                        + _word.word
-                        + '</li>'
-                })
-                .value()
-                .join("")
-            + '</ul>';
-    this.selector
-        .addClass("Ldt-TagCloud")
-        .html(_html);
-    this.selector.find("li").click(function() {
-        var _txt = this.textContent.replace(/(^[\s]+|[\s]+$)/g,'');
-        _this._Popcorn.trigger("IriSP.search.triggeredSearch", _txt);
-    });
-    this._Popcorn.listen("IriSP.search", IriSP.wrap(this, function(searchString) {
-        var _rgxp = new RegExp("(" + searchString.replace(/(\W)/g,'\\$1') + ")","gi");
-        this.selector.find("li").each(function(_i, _e) {
-            _e.innerHTML = searchString.length ?
-                _e.textContent.replace(_rgxp,'<span class="Ldt-TagCloud-actif Ldt-TraceMe">$1</span>')
-                : _e.textContent;
-        });
-    }));
-    this._Popcorn.listen("IriSP.search.closed", IriSP.wrap(this, this.endsearch));
-    this._Popcorn.listen("IriSP.search.cleared", IriSP.wrap(this, this.endsearch));
-}
-
-IriSP.TagCloudWidget.prototype.endsearch = function() {
-    this.selector.find("li").each(function(_i, _e) {
-        _e.innerHTML = _e.textContent;
-    });
-}
-/* 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);
-  // position the widget absolutely relative to document. --- NOOOO !!!!
-  this.selector.css({
-      "position": "absolute",
-      "top": 0,
-      "left": 0
-  });
-  this.selector.parent().css({
-      "position": "relative"
-  });
-  this.selector.append(templ);
-  var _this = this;
-  this.selector.mouseover(function() {
-      _this.hide();
-  });
-  this.hide();
-
-};
-
-IriSP.TooltipWidget.prototype.clear = function() {
-	this.selector.find(".tiptext").html("");
-};
-
-IriSP.TooltipWidget.prototype.show = function(text, color, x, y) {
-
-  if (this._displayedText == text && this._shown)
-    return;
-
-  this.selector.find(".tipcolor").css("background-color", color);
-  this._displayedText = text;
-  this.selector.find(".tiptext").html(text);
-  
-  var _tip = this.selector.find(".tip");
-  _tip.show();
-  _tip.css({
-      "left": Math.floor(x - _tip.outerWidth() / 2)+"px",
-      "top": Math.floor(y - _tip.outerHeight())+"px"
-  });
-  this._shown = true;
-};
-
-IriSP.TooltipWidget.prototype.hide = function() {                                                   
-  this.selector.find(".tip").hide();
-  this._shown = false;  
-};IriSP.TraceWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  this.lastEvent = "";
-  var _this = this,
-    _listeners = {
-        "IriSP.createAnnotationWidget.addedAnnotation" : 0,
-        "IriSP.search.open" : 0,
-        "IriSP.search.closed" : 0,
-        "IriSP.search" : 0,
-        "IriSP.search.cleared" : 0,
-        "IriSP.search.matchFound" : 0,
-        "IriSP.search.noMatchFound" : 0,
-        "IriSP.search.triggeredSearch" : 0,
-        "IriSP.TraceWidget.MouseEvents" : 0,
-        "play" : 0,
-        "pause" : 0,
-        "volumechange" : 0,
-        "seeked" : 0,
-        "play" : 0,
-        "pause" : 0,
-        "timeupdate" : 2000
-    };
-    IriSP._(_listeners).each(function(_ms, _listener) {
-        var _f = function(_arg) {
-            _this.eventHandler(_listener, _arg);
-        }
-        if (_ms) {
-            _f = IriSP.underscore.throttle(_f, _ms);
-        }
-        _this._Popcorn.listen(_listener, _f);
-    });
-    this._Popcorn.listen("timeupdate", IriSP.underscore.throttle(function(_arg) {
-        _this.eventHandler(_listener, _arg);
-    }));
-    
-    this.tracer = IriSP.TraceManager(IriSP.jQuery).init_trace("test", this._config);
-    this.tracer.set_default_subject("default_subject");
-    this.tracer.trace("StartTracing", { "hello": "world" });
-    
-}
-
-IriSP.TraceWidget.prototype = new IriSP.Widget();
-
-IriSP.TraceWidget.prototype.draw = function() {
-    this.mouseLocation = '';
-    var _this = this;
-    IriSP.jQuery(".Ldt-Widget").bind("click mouseover mouseout dragstart dragstop", function(_e) {
-        var _widget = IriSP.jQuery(this).attr("widget-type"),
-            _class = _e.target.className;
-        var _data = {
-            "type": _e.type,
-            "x": _e.clientX,
-            "y": _e.clientY,
-            "widget": _widget
-        }
-        if (typeof _class == "string" && _class.indexOf('Ldt-TraceMe') != -1) {
-            var _name = _e.target.localName,
-                _id = _e.target.id,
-                _text = _e.target.textContent.trim(),
-                _title = _e.target.title,
-                _value = _e.target.value;
-            _data.target = _name + (_id.length ? '#' + IriSP.jqEscape(_id) : '') + (_class.length ? ('.' + IriSP.jqEscape(_class).replace(/\s/g,'.')).replace(/\.Ldt-(Widget|TraceMe)/g,'') : '');
-            if (typeof _title == "string" && _title.length && _title.length < 140) {
-                _data.title = _title;
-            }
-            if (typeof _text == "string" && _text.length && _text.length < 140) {
-                _data.text = _text;
-            }
-            if (typeof _value == "string" && _value.length) {
-                _data.value = _value;
-            }
-            _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-        } else {
-            //console.log(_e.type+','+_this.mouseLocation+','+_widget);
-            if (_e.type == "mouseover") {
-                if (_this.mouseLocation != _widget) {
-                    _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-                } else {
-                    if (typeof _this.moTimeout != "undefined") {
-                        clearTimeout(_this.moTimeout);
-                        delete _this.moTimeout;
-                    }
-                }
-            }
-            if (_e.type == "click") {
-                _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-            }
-            if (_e.type == "mouseout") {
-                if (typeof _this.moTimeout != "undefined") {
-                    clearTimeout(_this.moTimeout);
-                }
-                _this.moTimeout = setTimeout(function() {
-                   if (_data.widget != _this.mouseLocation) {
-                       _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-                   }
-                },100);
-            }
-        }
-        _this.mouseLocation = _widget;
-    });
-}
-
-IriSP.TraceWidget.prototype.eventHandler = function(_listener, _arg) {
-    var _traceName = 'Mdp_';
-    if (typeof _arg == "string" || typeof _arg == "number") {
-        _arg = { "value" : _arg }
-    }
-    if (typeof _arg == "undefined") {
-        _arg = {}
-    }
-    switch(_listener) {
-        case 'IriSP.TraceWidget.MouseEvents':
-            _traceName += _arg.widget + '_' + _arg.type;
-            delete _arg.widget;
-            delete _arg.type;
-        break;
-        case 'timeupdate':
-        case 'play':
-        case 'pause':
-            _arg.time = this._Popcorn.currentTime() * 1000;
-        case 'seeked':
-        case 'volumechange':
-            _traceName += 'Popcorn_' + _listener;
-        break;
-        default:
-            _traceName += _listener.replace('IriSP.','').replace('.','_');
-    }
-    this.lastEvent = _traceName;
-    this.tracer.trace(_traceName, _arg);
-    if (this._config.js_console) {
-        console.log("tracer.trace('" + _traceName + "', " + JSON.stringify(_arg) + ");");
-    }
-}
-/* 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; 
-  this._hidden = false; /* hidden means that the createAnnotationWidget is shown */
-};
-
-
-IriSP.TweetsWidget.prototype = new IriSP.Widget();
-
-
-IriSP.TweetsWidget.prototype.drawTweet = function(annotation) {
-    if (this._hidden)
-      return;
-    
-    var title = IriSP.formatTweet(annotation.content.title);
-    var img = annotation.content.img.src;
-    if (typeof(img) === "undefined" || img === "" || img === "None") {
-      img = this.default_profile_picture;
-    }
-
-    var imageMarkup = IriSP.templToHTML("<img src='{{src}}' alt='user image'></img>", 
-                                       {src : img});
-    
-    if (typeof(IriSP.get_aliased(annotation.meta, ["dc:source", "source"]).content) !== "undefined") {
-      var tweetContents = JSON.parse(IriSP.get_aliased(annotation.meta, ["dc:source", "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), this.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));
-  this._Popcorn.listen("IriSP.PlayerWidget.AnnotateButton.clicked", 
-                        IriSP.wrap(this, this.handleAnnotateSignal));  
-};
-
-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;
-};
-
-/** handle clicks on the annotate button by hiding/showing itself */
-IriSP.TweetsWidget.prototype.handleAnnotateSignal = function() {
-  if (this._hidden == false) {
-    this.selector.hide();
-    this._hidden = true;
-  } else {
-    if (this._displayingTweet !== false)
-      this.selector.show();
-      
-    
-    this._hidden = false;
-  }
-};/** @class This class implement a serializer for the JSON-Cinelab format
-    @params DataLoader a dataloader reference
-    @url the url from which to get our cinelab
- */
-IriSP.JSONSerializer = function(DataLoader, url) {
-  IriSP.Serializer.call(this, DataLoader, url);
-};
-
-IriSP.JSONSerializer.prototype = new IriSP.Serializer();
-
-/** serialize data */
-IriSP.JSONSerializer.prototype.serialize = function(data) {
-  return JSON.stringify(data);
-};
-
-/** deserialize data */
-IriSP.JSONSerializer.prototype.deserialize = function(data) {
-  return JSON.parse(data);
-};
-
-/** load JSON-cinelab data and also sort the annotations by start time
-    @param callback function to call when the data is ready.
- */
-IriSP.JSONSerializer.prototype.sync = function(callback, force_refresh) {
-  /* we don't have to do much because jQuery handles json for us */
-
-  var self = this;
-
-  var fn = function(data) {
-	  //TODO: seems taht data can be null here
-	  if (data !== null) {
-		  self._data = data;  
-	      if (typeof(self._data["annotations"]) === "undefined" ||
-	          self._data["annotations"] === null)
-	          self._data["annotations"] = [];
-	      
-	      // 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, force_refresh);
-};
-
-/** @return the metadata about the media being read FIXME: always return the first media. */
-IriSP.JSONSerializer.prototype.currentMedia = function() {  
-  return (typeof this._data.medias == "object" && this._data.medias.length) ? this._data.medias[0] : IriSP.__jsonMetadata.medias[0];
-};
-
-IriSP.JSONSerializer.prototype.getDuration = function() {
-    var _m = this.currentMedia();
-    if (_m === null || typeof _m.meta == "undefined") {
-        return 0;
-    }
-    return +(IriSP.get_aliased(_m.meta, ["dc:duration", "duration"]) || 0);
-}
-
-
-/** searches for an annotation which matches title, description and keyword 
-   "" matches any field. 
-   Note: it ignores tweets.
-   @return a list of matching ids.
-*/    
-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 searchViewType = this.getTweets();
-    if (typeof(searchViewType) === "undefined") {
-      var view;
-      
-      if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
-         view = this._data.views[0];    
-
-      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);
-
-};
-
-/**
-  search an annotation according to its title, description and keyword
-  @param filter a function to filter the results with. Used to select between annotation types.
- */    
-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.
-   
-   @param searchString a string of words.
-   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;
-};
-
-/** 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.
-   
-   @param currentTime the time at which we search.
-   @param (optional) the if of the type of the annotations we want to get.
- */
-
-IriSP.JSONSerializer.prototype.currentAnnotations = function(currentTime, id) {
-  var view;
-  var currentTimeMs = 1000 * currentTime;
-
-  if (typeof(id) === "undefined") {
-      var legal_ids = this.getNonTweetIds();
-  } else {
-      legal_ids = [id];
-  }
-  
-  var ret_array = [];
-  
-  var i;
-  
-  for (i in this._data.annotations) {
-    var annotation = this._data.annotations[i];
-    
-    if (IriSP.underscore.include(legal_ids, annotation.meta["id-ref"]) && 
-        annotation.begin <= currentTimeMs &&
-        annotation.end >= currentTimeMs)
-          ret_array.push(annotation);
-  }
- 
-  if (ret_array == []) {
-    console.log("ret_array empty, ", legal_ids);
-  }
-  
-  return ret_array;
-};
-
-/** return the current chapitre
-    @param currentTime the current time, in seconds.
-*/
-IriSP.JSONSerializer.prototype.currentChapitre = function(currentTime) {
-  return this.currentAnnotations(currentTime, this.getChapitrage())[0];
-};
-
-/** returns a list of ids of tweet lines (aka: groups in cinelab) */
-IriSP.JSONSerializer.prototype.getTweetIds = function() {
-  if (IriSP.null_or_undefined(this._data.lists) || IriSP.null_or_undefined(this._data.lists) ||
-      IriSP.null_or_undefined(this._data.views) || IriSP.null_or_undefined(this._data.views[0]))
-    return [];
-
-  
-  /* Get the displayable types
-     We've got to jump through a few hoops because the json sometimes defines
-     fields with underscores and sometimes with dashes
-  */
-  var annotation_types = IriSP.get_aliased(this._data.views[0], ["annotation_types", "annotation-types"]);
-  if (annotation_types === null) {
-      console.log("neither view.annotation_types nor view.annotation-types are defined");      
-      return;
-  }
-
-  var available_types = IriSP.get_aliased(this._data, ["annotation_types", "annotation-types"]);    
-  if (available_types === null) {
-      console.log("neither view.annotation_types nor view.annotation-types are defined");      
-      return;
-  }
-  
-  var potential_types = [];
-  
-  // Get the list of types which contain "Tw" in their content
-  for (var i = 0; i < available_types.length; i++) {
-    if (/Tw/i.test(IriSP.get_aliased(available_types[i], ['dc:title', 'title']))) {
-      potential_types.push(available_types[i].id);
-    }
-  }
-  
-  // Get the intersection of both.
-  var tweetsId = IriSP.underscore.intersection(annotation_types, potential_types);
-  
-  return tweetsId;
-};
-
-/** this function returns a list of lines which are not tweet lines */
-IriSP.JSONSerializer.prototype.getNonTweetIds = function() {
-  if (IriSP.null_or_undefined(this._data.lists) || IriSP.null_or_undefined(this._data.lists) ||
-      IriSP.null_or_undefined(this._data.views) || IriSP.null_or_undefined(this._data.views[0]))
-    return [];
-
-  /* Get the displayable types
-     We've got to jump through a few hoops because the json sometimes defines
-     fields with underscores and sometimes with dashes
-  */
-  var annotation_types = IriSP.get_aliased(this._data.views[0], ["annotation_types", "annotation-types"]);
-  if (annotation_types === null) {
-      console.log("neither view.annotation_types nor view.annotation-types are defined");      
-      return;
-  }
-
-  var available_types = IriSP.get_aliased(this._data, ["annotation_types", "annotation-types"]);    
-  if (available_types === null) {
-      console.log("neither view.annotation_types nor view.annotation-types are defined");      
-      return;
-  }
-
-  var potential_types = [];
-  
-  // Get the list of types which do not contain "Tw" in their content
-  for (var i = 0; i < available_types.length; i++) {
-    if (!(/Tw/i.test(IriSP.get_aliased(available_types[i], ['dc:title', 'title'])))) {
-      potential_types.push(available_types[i].id);
-    }
-  }
-
-  // Get the intersection of both.
-  var nonTweetsId = IriSP.underscore.intersection(annotation_types, potential_types);
-  
-  return nonTweetsId;
-  
-};
-
-/** return the id of the ligne de temps which contains name
-    @param name of the ligne de temps
-*/
-IriSP.JSONSerializer.prototype.getId = function(name) {
-   var available_types = IriSP.get_aliased(this._data, ["annotation_types", "annotation-types"]);  
-   
-  if (available_types == null)
-    return;
-
-  name = name.toUpperCase();
-  var e;  
-  e = IriSP.underscore.find(available_types, 
-    function(entry) {
-        if (IriSP.get_aliased(entry, ['dc:title', 'title']) === null)
-          return false;
-        return (entry["dc:title"].toUpperCase().indexOf(name) !== -1);
-    });
-  
-  if (typeof(e) === "undefined")
-    return;
-    
-  var id = e.id;
-
-  return id;
-};
-
-/** return the list of id's of the ligne de temps which contains name
-    @param name of the ligne de temps
-*/
-IriSP.JSONSerializer.prototype.getIds = function(name) {
-   var available_types = IriSP.get_aliased(this._data, ["annotation_types", "annotation-types"]);  
-   
-  if (available_types == null)
-    return;
-
-  name = name.toUpperCase();
-  var e = [];  
-  e = IriSP.underscore.filter(available_types, 
-                                  function(entry) { return (IriSP.get_aliased(entry, ['dc:title', 'title']).toUpperCase().indexOf(name) !== -1) });
-  return IriSP.underscore.pluck(e, "id");  
-};
-
-/** return the id of the ligne de temps named "Chapitrage" */
-IriSP.JSONSerializer.prototype.getChapitrage = function() {
-  var val = this.getId("Chapitrage");
-  if (typeof(val) === "undefined")
-    val = this.getId("Chapter");   
-  if (typeof(val) === "undefined")
-    val = this.getId("Chapit");
-  if (typeof(val) === "undefined")
-    val = this.getId("Chap");
-    
-  return val;
-};
-
-/** return the id of the ligne de temps named "Tweets" */
-IriSP.JSONSerializer.prototype.getTweets = function() {
-  var val = this.getId("Tweets");
-  if (typeof(val) === "undefined")
-    val = this.getId("Tweet");
-  if (typeof(val) === "undefined")
-    val = this.getId("Twitter");
-  if (typeof(val) === "undefined")
-    val = this.getId("twit");
-  if (typeof(val) === "undefined")
-    val = this.getId("Polemic");
-  
-  return val;
-};
-
-/** return the id of the ligne de temps named "Contributions" */
-IriSP.JSONSerializer.prototype.getContributions = function() {
-  var val = this.getId("Contribution");
-  if (typeof(val) === "undefined")
-    val = this.getId("Particip");   
-  if (typeof(val) === "undefined")
-    val = this.getId("Contr");
-  if (typeof(val) === "undefined")
-    val = this.getId("Publ");
-    
-  return val;
-};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/js/mustache.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,436 @@
+/*
+  mustache.js — Logic-less templates in JavaScript
+
+  See http://mustache.github.com/ for more info.
+*/
+
+var Mustache = function () {
+  var _toString = Object.prototype.toString;
+
+  Array.isArray = Array.isArray || function (obj) {
+    return _toString.call(obj) == "[object Array]";
+  }
+
+  var _trim = String.prototype.trim, trim;
+
+  if (_trim) {
+    trim = function (text) {
+      return text == null ? "" : _trim.call(text);
+    }
+  } else {
+    var trimLeft, trimRight;
+
+    // IE doesn't match non-breaking spaces with \s.
+    if ((/\S/).test("\xA0")) {
+      trimLeft = /^[\s\xA0]+/;
+      trimRight = /[\s\xA0]+$/;
+    } else {
+      trimLeft = /^\s+/;
+      trimRight = /\s+$/;
+    }
+
+    trim = function (text) {
+      return text == null ? "" :
+        text.toString().replace(trimLeft, "").replace(trimRight, "");
+    }
+  }
+
+  var escapeMap = {
+    "&": "&amp;",
+    "<": "&lt;",
+    ">": "&gt;",
+    '"': '&quot;',
+    "'": '&#39;'
+  };
+
+  function escapeHTML(string) {
+    return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) {
+      return escapeMap[s] || s;
+    });
+  }
+
+  var regexCache = {};
+  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;
+        }
+      }
+
+      // get the pragmas together
+      template = this.render_pragmas(template);
+
+      // render the template
+      var html = this.render_section(template, context, partials);
+
+      // render_section did not find any sections, we still need to render the tags
+      if (html === false) {
+        html = this.render_tags(template, context, partials, in_recursion);
+      }
+
+      if (in_recursion) {
+        return html;
+      } else {
+        this.sendLines(html);
+      }
+    },
+
+    /*
+      Sends parsed lines
+    */
+    send: function (line) {
+      if (line !== "") {
+        this.buffer.push(line);
+      }
+    },
+
+    sendLines: function (text) {
+      if (text) {
+        var lines = text.split("\n");
+        for (var i = 0; i < lines.length; i++) {
+          this.send(lines[i]);
+        }
+      }
+    },
+
+    /*
+      Looks for %PRAGMAS
+    */
+    render_pragmas: function (template) {
+      // no pragmas
+      if (!this.includes("%", template)) {
+        return template;
+      }
+
+      var that = this;
+      var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) {
+        return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + 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 = trim(name);
+      if (!partials || partials[name] === undefined) {
+        throw({message: "unknown_partial '" + name + "'"});
+      }
+      if (!context || 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)) {
+        // did not render anything, there were no sections
+        return false;
+      }
+
+      var that = this;
+
+      var regex = this.getCachedRegex("render_section", function (otag, ctag) {
+        // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder
+        return new RegExp(
+          "^([\\s\\S]*?)" +         // all the crap at the beginning that is not {{*}} ($1)
+
+          otag +                    // {{
+          "(\\^|\\#)\\s*(.+)\\s*" + //  #foo (# == $2, foo == $3)
+          ctag +                    // }}
+
+          "\n*([\\s\\S]*?)" +       // between the tag ($2). leading newlines are dropped
+
+          otag +                    // {{
+          "\\/\\s*\\3\\s*" +        //  /foo (backreference to the opening tag).
+          ctag +                    // }}
+
+          "\\s*([\\s\\S]*)$",       // everything else in the string ($4). leading whitespace is dropped.
+
+        "g");
+      });
+
+
+      // for each {{#foo}}{{/foo}} section do...
+      return template.replace(regex, function (match, before, type, name, content, after) {
+        // before contains only tags, no sections
+        var renderedBefore = before ? that.render_tags(before, context, partials, true) : "",
+
+        // after may contain both sections and tags, so use full rendering function
+            renderedAfter = after ? that.render(after, context, partials, true) : "",
+
+        // will be computed below
+            renderedContent,
+
+            value = that.find(name, context);
+
+        if (type === "^") { // inverted section
+          if (!value || Array.isArray(value) && value.length === 0) {
+            // false or empty list, render it
+            renderedContent = that.render(content, context, partials, true);
+          } else {
+            renderedContent = "";
+          }
+        } else if (type === "#") { // normal section
+          if (Array.isArray(value)) { // Enumerable, Let's loop!
+            renderedContent = 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!
+            renderedContent = that.render(content, that.create_context(value),
+              partials, true);
+          } else if (typeof value == "function") {
+            // higher order section
+            renderedContent = value.call(context, content, function (text) {
+              return that.render(text, context, partials, true);
+            });
+          } else if (value) { // boolean section
+            renderedContent = that.render(content, context, partials, true);
+          } else {
+            renderedContent = "";
+          }
+        }
+
+        return renderedBefore + renderedContent + renderedAfter;
+      });
+    },
+
+    /*
+      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 that.getCachedRegex("render_tags", function (otag, ctag) {
+          return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + 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
+        case "&": // & operator is an alternative unescape method
+          return that.find(name, context);
+        default: // escape the value
+          return escapeHTML(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 = 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;
+
+      // check for dot notation eg. foo.bar
+      if (name.match(/([a-z_]+)\./ig)) {
+        var childValue = this.walk_context(name, context);
+        if (is_kinda_truthy(childValue)) {
+          value = childValue;
+        }
+      } else {
+        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 "";
+    },
+
+    walk_context: function (name, context) {
+      var path = name.split('.');
+      // if the var doesn't exist in current context, check the top level context
+      var value_context = (context[path[0]] != undefined) ? context : this.context;
+      var value = value_context[path.shift()];
+      while (value != undefined && path.length > 0) {
+        value_context = value;
+        value = value[path.shift()];
+      }
+      // if the value is a function, call it, binding the correct context
+      if (typeof value == "function") {
+        return value.apply(value_context);
+      }
+      return value;
+    },
+
+    // Utility methods
+
+    /* includes tag */
+    includes: function (needle, haystack) {
+      return haystack.indexOf(this.otag + needle) != -1;
+    },
+
+    // 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";
+    },
+
+    /*
+      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;
+      }
+    },
+
+    getCachedRegex: function (name, generator) {
+      var byOtag = regexCache[this.otag];
+      if (!byOtag) {
+        byOtag = regexCache[this.otag] = {};
+      }
+
+      var byCtag = byOtag[this.ctag];
+      if (!byCtag) {
+        byCtag = byOtag[this.ctag] = {};
+      }
+
+      var regex = byCtag[name];
+      if (!regex) {
+        regex = byCtag[name] = generator(this.otag, this.ctag);
+      }
+
+      return regex;
+    }
+  };
+
+  return({
+    name: "mustache.js",
+    version: "0.5.0-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");
+      }
+    }
+  });
+}();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/js/raphael-min.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,7 @@
+/*
+ * Raphael 1.5.2 - JavaScript Vector Library
+ *
+ * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
+ * Licensed under the MIT (http://raphaeljs.com/license.html) license.
+ */
+(function(){function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={"NaN":1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:"10px \"Arial\"","font-family":"\"Arial\"","font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML="<v:shape adj=\"1\"/>";bg=bf.firstChild;bg.style.behavior="url(#default#VML)";if(!(bg&&typeof bg.adj=="object"))return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML");j[e]=a[e];k=j[e];a._id=0;a._oid=0;a.fn={};a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b};a.angle=function(b,c,d,e,f,g){{if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)}};a.rad=function(a){return a%360*D/180};a.deg=function(a){return a*180/D%360};a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~(~(y.random()*16)))[H](16);a[12]=4;a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}a.setWindow=function(a){h=a;g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>");e.close();d=e.body}catch(a){d=createPopup().document.body}var f=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=f.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");h.title="Raphaël Colour Picker";h.style.display="none";g.body[l](h);bi=bm(function(a){h.style.color=a;return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b){d=b.b;c=b.s;b=b.h;e=b.o}return a.hsl2rgb(b,c,d/2,e)};a.hsl2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b){d=b.l;c=b.s;b=b.h}if(b>1||c>1||d>1){b/=360;c/=100;d/=100}var f={},g=["r","g","b"],h,i,j,k,l,m;if(c){d<0.5?h=d*(1+c):h=d+c-d*c;i=2*d-h;for(var n=0;n<3;n++){j=b+1/3*-(n-1);j<0&&j++;j>1&&j--;j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}}else f={r:d,g:d,b:d};f.r*=255;f.g*=255;f.b*=255;f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);a.is(e,"finite")&&(f.opacity=e);f.toString=bl;return f};a.rgb2hsb=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=f;{if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};a.rgb2hsl=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;k={h:h,s:i,l:j}}k.toString=bk;return k};a._path2string=function(){return this.join(",")[Y](ba,"$1")};function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("►"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];j[L](h);i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}a.getRGB=bm(function(b){if(!b||!(!((b=r(b)).indexOf("-")+1)))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){if(k[2]){g=T(k[2].substring(5),16);e=T(k[2].substring(3,5),16);d=T(k[2].substring(1,3),16)}if(k[3]){g=T((i=k[3].charAt(3))+i,16);e=T((i=k[3].charAt(2))+i,16);d=T((i=k[3].charAt(1))+i,16)}if(k[4]){j=k[4][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g};k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})}return c.hex};a.getColor.reset=function(){delete this.start};a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)});if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));g="l";b=b=="m"?"l":"L"}while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}});d[H]=a._path2string;return d});a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)}else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[];if(l[0]=="m"){f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f;e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2];e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=+b[0][1];e=+b[0][2];f=d;g=e;h++;c[0]=["M",d,e]}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d;g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f;e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(j){G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);if(x>1){x=y.sqrt(x);c=x*c;d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G;H=h<E?D-H:H;G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1];b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1);k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){if(a&&b&&a[g][0]=="M"&&b[g][0]!="M"){b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e);h(c,j);d&&(d[j]=g(d[j],f));d&&h(d,j);i(c,d,e,f,j);i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2];e.y=l[p-1];e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;f.bx=d&&(S(o[q-4])||f.x);f.by=d&&(S(o[q-3])||f.y);f.x=d&&o[q-2];f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++){if(c[j].offset){i=c[j].offset;break}}if(!i){i=100;j=e}i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++){h+=k;c[d].offset=h+"%"}}}return c}),by=function(b,c,d,e){var f;if(a.is(b,F)||a.is(b,"object")){f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){var c=this;for(var d in b){if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;default:a[d]=b[d];break}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){if(b.top===a)return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){if(b.bottom===a)return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},bF=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg";k.xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~(~a)===a)*0.5};var bG=function(a,b){if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};a[H]=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k;j[3]*=k;if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);for(var n in d){if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B);bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx){n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh();bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight});bG(E,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);c.paper.safari()};g.body[l](F);F.src=D[1];c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}var G=a.getRGB(o);if(G.error)if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o;i.fill="none";break}else{delete d.gradient;delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o);h[R](n,G.hex);n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break}default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);break}}}bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x});m[l](g.createTextNode(i[j]));e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},bN=function(b,c){var d=0,e=0;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.paper=c;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);this.prev=c.top;c.top&&(c.top.next=this);c.top=this;this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b);if(c[w]-1){d=S(c[1]);e=S(c[2])}c=S(c[0]);d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;e==null&&(d=null);this._.rt.cx=d;this._.rt.cy=e;d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;if(this._.rt.deg){this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})}else{this.transformations[0]=p;this.clip&&bG(this.clip,{transform:p})}bG(this.node,{transform:this.transformations[v](q)});return this};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this};bN[e].show=function(){!this.removed&&(this.node.style.display="");return this};bN[e].remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var c=0,d=this.node.getNumberOfChars();c<d;c++){var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this};bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this};bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);var a=this.paper}return this};bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};f.type="text";bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[R]("width",this.width);this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h});if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Raphaël"));a[l](this.desc);a[l](this.defs=bG("defs"))};k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);return f};bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";u.parentNode.insertBefore(q,u);q[l](u);e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+"\"");d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;v.type="solid";if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){h.fill="none";h.gradient=d.fill}}}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);d["stroke-width"]&&(C.weight=F);F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");C.miterlimit=d["stroke-miterlimit"]||8;d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"&#60;")[Y](/&/g,"&#38;")[Y](/\n/g,"<br>"));m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=c;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;default:i=0;j=0;k=this.paper.width;l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;if(ca[f](this.type)){e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)}else{d.width!=(q=this.paper.width+"px")&&(d.width=q);d.height!=(q=this.paper.height+"px")&&(d.height=q);e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0;i=i||0;f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);return k};k.clear=function(){this.canvas.innerHTML=p;this.span=g.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}if(k){var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};bO.translate=function(a,b){return this.attr({translation:a+" "+b})};bO[H]=function(){return"Raphaël’s object"};a.ae=cv;var cC=function(a){this.items=[];this[w]=0;this.type="set";if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];i.was?h.Raphael=a:Raphael=a})()
\ No newline at end of file
--- a/web/res/js/raphael.js	Wed May 02 19:19:51 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-/*
- * Raphael 1.5.2 - JavaScript Vector Library
- *
- * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
- * Licensed under the MIT (http://raphaeljs.com/license.html) license.
- */
-(function(){function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={"NaN":1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:"10px \"Arial\"","font-family":"\"Arial\"","font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML="<v:shape adj=\"1\"/>";bg=bf.firstChild;bg.style.behavior="url(#default#VML)";if(!(bg&&typeof bg.adj=="object"))return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML");j[e]=a[e];k=j[e];a._id=0;a._oid=0;a.fn={};a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b};a.angle=function(b,c,d,e,f,g){{if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)}};a.rad=function(a){return a%360*D/180};a.deg=function(a){return a*180/D%360};a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~(~(y.random()*16)))[H](16);a[12]=4;a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}a.setWindow=function(a){h=a;g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>");e.close();d=e.body}catch(a){d=createPopup().document.body}var f=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=f.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");h.title="Raphaël Colour Picker";h.style.display="none";g.body[l](h);bi=bm(function(a){h.style.color=a;return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b){d=b.b;c=b.s;b=b.h;e=b.o}return a.hsl2rgb(b,c,d/2,e)};a.hsl2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b){d=b.l;c=b.s;b=b.h}if(b>1||c>1||d>1){b/=360;c/=100;d/=100}var f={},g=["r","g","b"],h,i,j,k,l,m;if(c){d<0.5?h=d*(1+c):h=d+c-d*c;i=2*d-h;for(var n=0;n<3;n++){j=b+1/3*-(n-1);j<0&&j++;j>1&&j--;j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}}else f={r:d,g:d,b:d};f.r*=255;f.g*=255;f.b*=255;f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);a.is(e,"finite")&&(f.opacity=e);f.toString=bl;return f};a.rgb2hsb=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=f;{if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};a.rgb2hsl=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;k={h:h,s:i,l:j}}k.toString=bk;return k};a._path2string=function(){return this.join(",")[Y](ba,"$1")};function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("►"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];j[L](h);i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}a.getRGB=bm(function(b){if(!b||!(!((b=r(b)).indexOf("-")+1)))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){if(k[2]){g=T(k[2].substring(5),16);e=T(k[2].substring(3,5),16);d=T(k[2].substring(1,3),16)}if(k[3]){g=T((i=k[3].charAt(3))+i,16);e=T((i=k[3].charAt(2))+i,16);d=T((i=k[3].charAt(1))+i,16)}if(k[4]){j=k[4][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g};k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})}return c.hex};a.getColor.reset=function(){delete this.start};a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)});if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));g="l";b=b=="m"?"l":"L"}while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}});d[H]=a._path2string;return d});a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)}else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[];if(l[0]=="m"){f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f;e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2];e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=+b[0][1];e=+b[0][2];f=d;g=e;h++;c[0]=["M",d,e]}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d;g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f;e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(j){G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);if(x>1){x=y.sqrt(x);c=x*c;d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G;H=h<E?D-H:H;G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1];b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1);k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){if(a&&b&&a[g][0]=="M"&&b[g][0]!="M"){b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e);h(c,j);d&&(d[j]=g(d[j],f));d&&h(d,j);i(c,d,e,f,j);i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2];e.y=l[p-1];e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;f.bx=d&&(S(o[q-4])||f.x);f.by=d&&(S(o[q-3])||f.y);f.x=d&&o[q-2];f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++){if(c[j].offset){i=c[j].offset;break}}if(!i){i=100;j=e}i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++){h+=k;c[d].offset=h+"%"}}}return c}),by=function(b,c,d,e){var f;if(a.is(b,F)||a.is(b,"object")){f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){var c=this;for(var d in b){if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;default:a[d]=b[d];break}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){if(b.top===a)return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){if(b.bottom===a)return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},bF=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg";k.xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~(~a)===a)*0.5};var bG=function(a,b){if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};a[H]=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k;j[3]*=k;if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);for(var n in d){if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B);bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx){n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh();bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight});bG(E,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);c.paper.safari()};g.body[l](F);F.src=D[1];c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}var G=a.getRGB(o);if(G.error)if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o;i.fill="none";break}else{delete d.gradient;delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o);h[R](n,G.hex);n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break}default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);break}}}bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x});m[l](g.createTextNode(i[j]));e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},bN=function(b,c){var d=0,e=0;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.paper=c;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);this.prev=c.top;c.top&&(c.top.next=this);c.top=this;this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b);if(c[w]-1){d=S(c[1]);e=S(c[2])}c=S(c[0]);d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;e==null&&(d=null);this._.rt.cx=d;this._.rt.cy=e;d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;if(this._.rt.deg){this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})}else{this.transformations[0]=p;this.clip&&bG(this.clip,{transform:p})}bG(this.node,{transform:this.transformations[v](q)});return this};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this};bN[e].show=function(){!this.removed&&(this.node.style.display="");return this};bN[e].remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var c=0,d=this.node.getNumberOfChars();c<d;c++){var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this};bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this};bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);var a=this.paper}return this};bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};f.type="text";bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[R]("width",this.width);this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h});if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Raphaël"));a[l](this.desc);a[l](this.defs=bG("defs"))};k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);return f};bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";u.parentNode.insertBefore(q,u);q[l](u);e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+"\"");d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;v.type="solid";if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){h.fill="none";h.gradient=d.fill}}}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);d["stroke-width"]&&(C.weight=F);F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");C.miterlimit=d["stroke-miterlimit"]||8;d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"&#60;")[Y](/&/g,"&#38;")[Y](/\n/g,"<br>"));m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=c;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;default:i=0;j=0;k=this.paper.width;l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;if(ca[f](this.type)){e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)}else{d.width!=(q=this.paper.width+"px")&&(d.width=q);d.height!=(q=this.paper.height+"px")&&(d.height=q);e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0;i=i||0;f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);return k};k.clear=function(){this.canvas.innerHTML=p;this.span=g.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}if(k){var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};bO.translate=function(a,b){return this.attr({translation:a+" "+b})};bO[H]=function(){return"Raphaël’s object"};a.ae=cv;var cC=function(a){this.items=[];this[w]=0;this.type="set";if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];i.was?h.Raphael=a:Raphael=a})()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Annotation.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,98 @@
+.Ldt-Annotation-Widget {
+    border-style: none solid solid;
+    border-width: 1px;
+    border-color: #b7b7b7;
+    padding: 0 1px 1px;
+    margin: 0;
+    font-family: Helvetica, Arial, sans-serif;
+}
+
+.Ldt-Annotation-Widget.Ldt-Annotation-ShowTop {
+    border-top-style: solid;
+    padding-top: 1px;
+}
+
+.Ldt-Annotation-Inner {
+    background: url(img/pinstripe.png);
+    padding: 5px;
+    margin: 0;
+}
+
+.Ldt-Annotation-Inner h3 {
+    margin: 5px 0;
+    font-size: 15px;
+    font-weight: bold;
+}
+
+.Ldt-Annotation-Title {
+    color: #0068c4;
+}
+
+.Ldt-Annotation-Time {
+    color: #ff3b77
+}
+
+.Ldt-Annotation-Inner p {
+    margin: 5px 0; font-size: 12px;
+}
+
+.Ldt-Annotation-ShareIcons {
+    float: right;
+}
+
+.Ldt-Annotation-Share {
+    display: inline-block; width: 24px; height: 24px; margin: 2px 0 0 2px; background: url(img/socialbuttons.png);
+}
+
+.Ldt-Annotation-Twitter {
+    background-position: 0 0;
+}
+
+.Ldt-Annotation-Twitter:hover {
+    background-position: 0 -24px;
+}
+
+.Ldt-Annotation-Fb {
+    background-position: -24px 0;
+}
+
+.Ldt-Annotation-Fb:hover {
+    background-position: -24px -24px;
+}
+
+.Ldt-Annotation-Gplus {
+    background-position: -48px 0;
+}
+
+.Ldt-Annotation-Gplus:hover {
+    background-position: -48px -24px;
+}
+
+.Ldt-Annotation-Tags-Block {
+    font-size: 12px;
+}
+
+.Ldt-Annotation-NoTags {
+    display: none;
+}
+
+ul.Ldt-Annotation-Tags {
+    list-style: none; padding: 0; margin: 5px 0;
+}
+
+.Ldt-Annotation-Tags li {
+    display: inline-block; margin: 0 3px 0 0; padding: 0;
+}
+
+.Ldt-Annotation-TagLabel {
+    font-weight: bold;
+}
+
+.Ldt-Annotation-Empty .Ldt-Annotation-HiddenWhenEmpty {
+    display: none;
+}
+
+.Ldt-Annotation-Minimized .Ldt-Annotation-HiddenWhenMinimized {
+    display: none;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Annotation.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,112 @@
+// TODO: Open share links in a small window - Migrate Timeupdate functions to Extract
+
+IriSP.Widgets.Annotation = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.lastAnnotation = false;
+};
+
+IriSP.Widgets.Annotation.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Annotation.prototype.messages = {
+    "fr": {
+        share_on: "Partager sur",
+        watching: "Je regarde ",
+        on_site: " sur ",
+        tags: "Mots-clés&nbsp;:"
+    },
+    "en": {
+        share_on: "Share on",
+        watching: "I'm watching ",
+        on_site: " on ",
+        tags: "Keywords:"
+    }
+}
+
+IriSP.Widgets.Annotation.prototype.template =
+    '<div class="Ldt-Annotation-Widget {{#show_top_border}}Ldt-Annotation-ShowTop{{/show_top_border}}">'
+    + '<div class="Ldt-Annotation-Inner Ldt-Annotation-Empty"><div class="Ldt-Annotation-ShareIcons Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty">'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Fb" title="{{l10n.share_on}} Facebook"></a>'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Twitter" title="{{l10n.share_on}} Twitter"></a>'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Gplus" title="{{l10n.share_on}} Google+"></a>'
+    + '</div><h3 class="Ldt-Annotation-HiddenWhenEmpty"><span class="Ldt-Annotation-Title"></span> <span class="Ldt-Annotation-Time">'
+    + '( <span class="Ldt-Annotation-Begin"></span> - <span class="Ldt-Annotation-End"></span> )</span></h3>'
+    + '<p class="Ldt-Annotation-Description Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty"></p>'
+    + '<div class="Ldt-Annotation-Tags-Block Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty Ldt-Annotation-NoTags">{{l10n.tags}}<ul class="Ldt-Annotation-Tags"></ul></div></div></div>';
+
+IriSP.Widgets.Annotation.prototype.defaults = {
+    annotation_type : "chap",
+    show_top_border : false,
+    site_name : "Lignes de Temps"
+}
+
+IriSP.Widgets.Annotation.prototype.draw = function() {
+    this.renderTemplate();
+    this.bindPopcorn("timeupdate","onTimeupdate");
+    this.bindPopcorn("IriSP.Annotation.hide","hide");
+    this.bindPopcorn("IriSP.Annotation.show","show");
+    this.bindPopcorn("IriSP.Annotation.minimize","minimize");
+    this.bindPopcorn("IriSP.Annotation.maximize","maximize");
+    this.onTimeupdate();
+}
+
+IriSP.Widgets.Annotation.prototype.onTimeupdate = function() {
+    var _time = Math.floor(this.player.popcorn.currentTime() * 1000),
+        _list = this.getWidgetAnnotations().filter(function(_annotation) {
+            return _annotation.begin <= _time && _annotation.end > _time;
+        });
+    if (_list.length) {
+        if (_list[0].id !== this.lastAnnotation) {
+            this.drawAnnotation(_list[0]);
+            this.player.popcorn.trigger("IriSP.Annotation.boundsChanged",[ _list[0].begin.valueOf(), _list[0].end.valueOf() ]);
+        }
+        this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: ( _list[0].begin + _list[0].end ) / 2});
+    }
+    else {
+        this.lastAnnotation = false;
+        this.$.find(".Ldt-Annotation-Inner").addClass("Ldt-Annotation-Empty");
+        this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: _time});
+        this.player.popcorn.trigger("IriSP.Annotation.boundsChanged",[ _time, _time ]);
+    }
+}
+
+IriSP.Widgets.Annotation.prototype.drawAnnotation = function(_annotation) {
+    this.lastAnnotation = _annotation.id;
+    var _url = (typeof _annotation.url !== "undefined" 
+            ? _annotation.url
+            : (document.location.href.replace(/#.*$/,'') + '#id='  + _annotation.namespacedId.name));
+    var _text = this.l10n.watching + _annotation.title + (this.site_name ? this.l10n.on_site + this.site_name : '');
+    var _tags = _annotation.getTagTexts();
+    if (_tags.length) {
+        var _html = IriSP._(_tags).map(function(_tag) {
+            return '<li class="Ldt-Annotation-TagLabel">' + _tag + '</li>';
+        }).join("");
+        this.$.find(".Ldt-Annotation-Tags").html(_html);
+        this.$.find(".Ldt-Annotation-Tags-Block").removeClass("Ldt-Annotation-NoTags");
+    } else {
+        this.$.find(".Ldt-Annotation-Tags-Block").addClass("Ldt-Annotation-NoTags");
+    }
+    this.$.find(".Ldt-Annotation-Title").html(_annotation.title);
+    this.$.find(".Ldt-Annotation-Description").html(_annotation.description);
+    this.$.find(".Ldt-Annotation-Begin").html(_annotation.begin.toString());
+    this.$.find(".Ldt-Annotation-End").html(_annotation.end.toString());
+    this.$.find(".Ldt-Annotation-Fb").attr("href", "http://www.facebook.com/share.php?" + IriSP.jQuery.param({ u: _url, t: _text }));
+    this.$.find(".Ldt-Annotation-Twitter").attr("href", "https://twitter.com/intent/tweet?" + IriSP.jQuery.param({ url: _url, text: _text }));
+    this.$.find(".Ldt-Annotation-Gplus").attr("href", "https://plusone.google.com/_/+1/confirm?" + IriSP.jQuery.param({ url: _url, title: _text }));
+    this.$.find(".Ldt-Annotation-Inner").removeClass("Ldt-Annotation-Empty");
+}
+
+IriSP.Widgets.Annotation.prototype.hide = function() {
+    this.$.slideUp();
+}
+
+IriSP.Widgets.Annotation.prototype.show = function() {
+    this.$.slideDown();
+}
+
+IriSP.Widgets.Annotation.prototype.minimize = function() {
+    this.$.find('.Ldt-Annotation-Inner').addClass("Ldt-Annotation-Minimized");
+}
+
+IriSP.Widgets.Annotation.prototype.maximize = function() {
+    this.$.find('.Ldt-Annotation-Inner').removeClass("Ldt-Annotation-Minimized");
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/AnnotationsList.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,78 @@
+/* AnnotationsListWidget */
+
+.Ldt-AnnotationsListWidget {
+}
+.Ldt-AnnotationsListWidget a {
+    text-decoration: none;
+}
+ul.Ldt-AnnotationsList-ul {
+    list-style: none;
+    padding: 2px;
+    margin: 0;
+}
+li.Ldt-AnnotationsList-li {
+    width: 100%;
+    clear: both;
+    margin: 2px 0;
+    padding: 2px 0;
+    min-height: 60px;
+}
+.Ldt-AnnotationsList-li:hover {
+    background: url(img/pinstripe-grey.png);
+}
+.Ldt-AnnotationsList-highlight {
+    background: #F7268E;
+    color: #ffffff;
+}
+.Ldt-AnnotationsList-ThumbContainer {
+    float: left;
+    width: 80px;
+    height: 50px;
+    text-align: center;
+    margin: 2px 0;
+}
+.Ldt-AnnotationsList-Thumbnail {
+    border: none;
+    max-width: 100%;
+    max-height: 100%;
+    margin: 0 auto;
+}
+.Ldt-AnnotationsList-Duration {
+    color: #f7268e;
+    float: right;
+    text-align: right;
+    font-size: 12px;
+    margin: 2px;
+}
+h3.Ldt-AnnotationsList-Title, #accordeon h3.Ldt-AnnotationsList-Title {
+    color: #0068c4;
+    font-size: 14px;
+    line-height: 1.2em;
+    margin: 0 2px 0 82px;
+    font-weight: bold;
+}
+h3.Ldt-AnnotationsList-Title a, #accordeon h3.Ldt-AnnotationsList-Title a {
+    color: #0068c4 ;
+}
+p.Ldt-AnnotationsList-Description, #accordeon p.Ldt-AnnotationsList-Description {
+    margin: 2px 0 2px 82px;
+    line-height: 1.2em;
+    font-size: 12px;
+    color: #666666;
+}
+ul.Ldt-AnnotationsList-Tags {
+    list-style: none;
+    padding: 0;
+    margin: 2px 0 8px 82px;
+}
+li.Ldt-AnnotationsList-Tag-Li {
+    display: inline-block;
+    margin: 2px;
+    background: #0068c4;
+    color: #fff;
+    padding: 2px;
+    font-size: 12px;
+}
+li.Ldt-AnnotationsList-Tag-Li:hover {
+    background: #F7268E;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/AnnotationsList.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,227 @@
+IriSP.Widgets.AnnotationsList = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.searchString = false;
+    this.lastIds = [];
+    var _this = this;
+    this.throttledRefresh = IriSP._.throttle(function() {
+        _this.refresh(false);
+    }, 1500);
+};
+
+IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.AnnotationsList.prototype.defaults = {
+    /* URL when the annotations are to be reloaded from an LDT-like segment API
+     * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?
+     */
+    ajax_url : false,
+    /* how much ms should we look before and after the current timecode in the segment API
+     */
+    ajax_granularity : 300000, 
+    default_thumbnail : "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png",
+    /* URL when the annotation is not in the current project,
+     * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}
+     */
+    foreign_url : "",
+    cinecast_version : false,
+    annotation_type : false,
+    refresh_interval : 0,
+    limit_count : 10,
+    newest_first : false
+};
+
+IriSP.Widgets.AnnotationsList.prototype.template =
+    '<div class="Ldt-AnnotationsListWidget">'
+    + '<ul class="Ldt-AnnotationsList-ul">'
+    + '{{#annotations}}'
+    + '<li id="Ldt-Annotation-li-{{id}}" class="Ldt-AnnotationsList-li Ldt-TraceMe">'
+    + '<div class="Ldt-AnnotationsList-ThumbContainer">'
+    + '<a href="{{url}}">'
+    + '<img class="Ldt-AnnotationsList-Thumbnail" src="{{thumbnail}}" />'
+    + '</a>'
+    + '</div>'
+    + '<div class="Ldt-AnnotationsList-Duration">{{begin}} - {{end}}</div>'
+    + '<h3 class="Ldt-AnnotationsList-Title">'
+    + '<a href="{{url}}">{{title}}</a>'
+    + '</h3>'
+    + '<p class="Ldt-AnnotationsList-Description">{{description}}</p>'
+    + '{{#tags.length}}'
+    + '<ul class="Ldt-AnnotationsList-Tags">'
+    + '{{#tags}}'
+    + '{{#.}}'
+    + '<li class="Ldt-AnnotationsList-Tag-Li">'
+    + '<div class="Ldt-AnnotationsList-Tag-Div">{{.}}</div>'
+    + '</li>'
+    + '{{/.}}'
+    + '{{/tags}}'
+    + '</ul>'
+    + '{{/tags.length}}'
+    + '</li>'
+    + '{{/annotations}}'
+    + '</ul>'
+    + '</div>';
+
+IriSP.Widgets.AnnotationsList.prototype.clear = function() {
+};
+
+IriSP.Widgets.AnnotationsList.prototype.clearWidget = function() {
+};
+
+IriSP.Widgets.AnnotationsList.prototype.onSearch = function(searchString) {
+    this.searchString = typeof searchString !== "undefined" ? searchString : '';
+    var _n = this.refresh(true);
+    if (this.searchString) {
+        if (_n) {
+            this.player.popcorn.trigger("IriSP.search.matchFound");
+        } else {
+            this.player.popcorn.trigger("IriSP.search.noMatchFound");
+        }
+    }
+}
+
+//obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id;
+
+IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() {
+    var _currentTime = this.player.popcorn.currentTime(),
+        _duration = this.source.getDuration();
+    if (typeof _currentTime == "undefined") {
+        _currentTime = 0;
+    }
+    this.lastAjaxQuery = _currentTime;
+    _currentTime = Math.floor(1000 * _currentTime);
+    var _url = Mustache.to_html(this.ajax_url, {
+        media : this.source.currentMedia.namespacedId.name,
+        begin : Math.max(0, _currentTime - this.ajax_granularity),
+        end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity)
+    });
+    this.currentSource = this.player.loadMetadata(IriSP._.defaults({
+        "url" : _url
+    }, this.metadata));
+}
+
+IriSP.Widgets.AnnotationsList.prototype.refresh = function(_forceRedraw) {
+    _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw);
+    if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) {
+        return 0;
+    }
+    var _this = this,
+        _currentTime = this.player.popcorn.currentTime();
+    if (typeof _currentTime == "undefined") {
+        _currentTime = 0;
+    }
+    var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type, true) : this.currentSource.getAnnotations();
+    if (this.searchString) {
+        _list = _list.searchByTextFields(this.searchString);
+    }
+    if (this.limit_count) {
+        _list = _list.sortBy(function(_annotation) {
+            return Math.abs(_annotation.begin.getSeconds() - _currentTime);
+        }).slice(0, this.limit_count)
+    }
+    if (this.newest_first) {
+        _list = _list.sortBy(function(_annotation) {
+            return -_annotation.created.valueOf();
+        });
+    } else {
+        _list = _list.sortBy(function(_annotation) {
+            return _annotation.begin;
+        });
+    }
+    
+    var _ids = _list.idIndex;
+    
+    if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) {
+        /* This part only gets executed if the list needs updating */
+        this.lastIds = _ids;
+        var _data = _list.map(function(_annotation) {
+                    var _url = (
+                        ( typeof _annotation.url !== "undefined" && _annotation.url)
+                        ? _annotation.url
+                        : (
+                            ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _annotation.project && _this.source.projectId !== _annotation.project )
+                            ? Mustache.to_html(
+                                _this.foreign_url,
+                                {
+                                    project : _annotation.project,
+                                    media : _annotation.media.id.replace(/^.*:/,''),
+                                    annotation : _annotation.namespacedId.name,
+                                    annotationType : _annotation.annotationType.id.replace(/^.*:/,'')
+                                }
+                            )
+                            : '#id=' + _annotation.namespacedId.name
+                            )
+                    );
+                    var _res = {
+                        id : _annotation.id,
+                        title : _annotation.title.replace(_annotation.description,''),
+                        description : _annotation.description,
+                        begin : _annotation.begin.toString(),
+                        end : _annotation.end.toString(),
+                        thumbnail : typeof _annotation.thumbnail !== "undefined" && _annotation.thumbnail ? _annotation.thumbnail : _this.default_thumbnail,
+                        url : _url,
+                        tags : _annotation.getTagTexts()
+                    }
+                    return _res;
+            }),
+            _html = Mustache.to_html(
+                this.template,
+                {
+                    annotations : _data
+                });
+    
+        this.$.html(_html);
+    
+        this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() {
+            _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,''));
+        })
+        
+        if(this.searchString) {
+            var _searchRe = new RegExp('(' + this.searchString.replace(/(\W)/gm,'\\$1') + ')','gim');
+            this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() {
+                var _$ = IriSP.jQuery(this);
+                _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
+            })
+        }
+    }
+    
+    if (this.ajax_url && this.ajax_granularity) {
+        if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) {
+            this.ajaxSource();
+        }
+    }
+    return _list.length;
+}
+
+IriSP.Widgets.AnnotationsList.prototype.draw = function() {
+    
+    this.bindPopcorn("IriSP.search", "onSearch");
+    this.bindPopcorn("IriSP.search.closed", "onSearch");
+    this.bindPopcorn("IriSP.search.cleared", "onSearch");
+    
+    var _this = this;
+    
+    if (this.ajax_url && this.ajax_granularity) {
+        this.ajaxSource();
+    } else {
+        this.currentSource = this.source;
+    }
+    
+    if (this.refresh_interval) {
+        window.setInterval(function() {
+            _this.currentSource.get()
+        }, this.refresh_interval);
+    }
+    
+    var _events = [
+        "IriSP.createAnnotationWidget.addedAnnotation",
+        "timeupdate",
+        "seeked",
+        "loadedmetadata"
+    ];
+    for (var _i = 0; _i < _events.length; _i++) {
+        this.player.popcorn.listen(_events[_i], this.throttledRefresh);
+    }
+    
+    this.throttledRefresh();
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Arrow.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,105 @@
+IriSP.Widgets.Arrow = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.current_pilot_widget = this.pilot_widget
+};
+
+IriSP.Widgets.Arrow.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Arrow.prototype.defaults = {
+    arrow_height : 16,
+    arrow_width : 24,
+    base_height : 0,
+    base_curve : 0,
+    fill_url: IriSP.widgetsDir + '/img/pinstripe.png',
+    fill_color: "#ffffff", //Gradients can be used, e.g. "90-#000-#fff" for vertical white-to-black
+    stroke_color: "#b7b7b7",
+    stroke_width: 1.5,
+    animation_speed: 20,
+    pilot_widget: "Annotation"
+}
+
+IriSP.Widgets.Arrow.prototype.draw = function() {
+    this.height = this.arrow_height + this.base_height;
+    this.$.addClass("Ldt-Arrow").css({
+        height: this.height + "px",
+        "margin-top": "1px"
+    });
+    this.paper = new Raphael(this.container, this.width, this.height );
+    window.myArrow = this;
+    this.svgArrow = this.paper.path('M0,' + this.height + 'L' + this.width + ',' + this.height);
+    this.svgArrow.attr({
+        stroke: this.stroke_color,
+        "stroke-width": this.stroke_width,
+        fill: this.fill_url ? ( 'url(' + this.fill_url + ')' ) : this.fill_color
+    });
+    this.moveTo(0);
+    this.bindPopcorn("IriSP.Arrow.updatePosition","onUpdatePosition");
+    this.bindPopcorn("IriSP.Arrow.takeover","onTakeover");
+    this.bindPopcorn("IriSP.Arrow.release","onRelease");
+}
+
+IriSP.Widgets.Arrow.prototype.drawAt = function(_x) {
+    _x = Math.floor(Math.max(0, Math.min(_x, this.width)));
+    var _d = 'M0,' + this.height
+        + 'L0,' + Math.min( this.height, this.arrow_height + this.base_curve)
+        + 'Q0,' + this.arrow_height
+        + ' ' + Math.max(0, Math.min(this.base_curve, _x - this.arrow_width / 2)) + ',' + this.arrow_height
+        + 'L' + Math.max(0, _x - this.arrow_width / 2) + ',' + this.arrow_height
+        + 'L' + Math.max(0, _x - this.arrow_width / 2) + ',' + Math.min(this.arrow_height, 2 * this.arrow_height * _x / this.arrow_width)
+        + 'L' + _x + ',0'
+        + 'L' + Math.min(this.width, _x + this.arrow_width / 2) + ',' + Math.min(this.arrow_height, 2 * this.arrow_height * ( this.width - _x ) / this.arrow_width)
+        + 'L' + Math.min(this.width, _x + this.arrow_width / 2) + ',' + this.arrow_height
+        + 'L' + Math.min(this.width, Math.max(this.width - this.base_curve, _x + this.arrow_width / 2)) + ',' + this.arrow_height
+        + 'Q' + this.width + ',' + this.arrow_height
+        + ' ' + this.width + ',' + Math.min( this.height, this.arrow_height + this.base_curve)
+        + 'L' + this.width + ',' + this.height;
+    this.svgArrow.attr({
+        path: _d
+    });
+}
+
+IriSP.Widgets.Arrow.prototype.moveTo = function(_x) {
+    this.targetX = Math.floor(Math.max(0, Math.min(_x, this.width)));
+    if (typeof this.animInterval === "undefined") {
+        this.animInterval = window.setInterval(
+            this.functionWrapper("increment"),
+            40
+        )
+    }
+    this.increment();
+}
+
+IriSP.Widgets.Arrow.prototype.increment = function() {
+    if (typeof this.currentX === "undefined") {
+        this.currentX = this.targetX;
+    }
+    if (this.currentX < this.targetX) {
+        this.currentX = Math.min(this.targetX, this.currentX + this.animation_speed);
+    }
+    if (this.currentX > this.targetX) {
+        this.currentX = Math.max(this.targetX, this.currentX - this.animation_speed);
+    }
+    if (this.currentX === this.targetX) {
+        window.clearInterval(this.animInterval);
+        this.animInterval = undefined;
+    }
+    this.drawAt(this.currentX);
+}
+
+IriSP.Widgets.Arrow.prototype.onUpdatePosition = function(_param) {
+    if (_param.widget === this.current_pilot_widget) {
+        if (typeof _param.x !== "undefined") {
+            this.moveTo(_param.x);
+        } else {
+            this.moveTo(this.width * _param.time / this.source.getDuration());
+        }
+    }
+}
+
+IriSP.Widgets.Arrow.prototype.onTakeover = function(_widget) {
+    this.current_pilot_widget = _widget;
+}
+
+IriSP.Widgets.Arrow.prototype.onRelease = function(_widget) {
+    this.current_pilot_widget = this.pilot_widget;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Controller.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,178 @@
+/* Player Widget */
+
+.Ldt-Ctrl {
+  font-size: 10px;
+  font-family: "Trebuchet MS", "Helvetica", "Arial",  "Verdana", "sans-serif";
+  background:url('img/player_gradient.png') repeat-x transparent ;
+  height: 25px;
+  border: 1px solid #b6b8b8;
+  position: relative;
+}
+
+.Ldt-Ctrl-Left {
+  float:left;
+}
+
+.Ldt-Ctrl-Right {
+  float: right;
+}
+
+.Ldt-Ctrl-button {
+  float: left;
+  width: 30px; height: 25px;
+  background: url('img/player-sprites.png');
+  cursor: pointer;
+}
+
+.Ldt-Ctrl-spacer {
+    float: left; width: 1px; height: 25px; background: #b6b8b8;
+}
+
+.Ldt-Ctrl-Play {
+  margin: 0 15px;
+}
+
+.Ldt-Ctrl-Play-PlayState {
+  background-position: 0 0;
+}
+
+.Ldt-Ctrl-Play-PlayState:hover {
+  background-position: 0 -25px;
+}
+
+.Ldt-Ctrl-Play-PlayState:active {
+  background-position: 0 -50px;
+}
+
+.Ldt-Ctrl-Play-PauseState {
+  background-position: -30px 0;
+}
+
+.Ldt-Ctrl-Play-PauseState:hover {
+  background-position: -30px -25px;
+}
+
+.Ldt-Ctrl-Play-PauseState:active {
+  background-position: -30px -50px;
+}
+
+.Ldt-Ctrl-Annotate {
+  margin: 0 2px;
+  background-position: -60px 0;
+}
+
+.Ldt-Ctrl-Annotate:hover {
+  background-position: -60px -25px;
+}
+
+.Ldt-Ctrl-Annotate:active {
+  background-position: -60px -50px;
+}
+
+.Ldt-Ctrl-SearchBtn {
+  margin: 0 2px;
+  background-position: -90px 0;
+}
+
+.Ldt-Ctrl-SearchBtn:hover {
+  background-position: -90px -25px;
+}
+
+.Ldt-Ctrl-SearchBtn:active {
+  background-position: -90px -50px;
+}
+
+.Ldt-Ctrl-Search {
+  display: none;
+  width: 165px;
+  height: 25px;
+  border: 1px;
+  border-color: #CFCFCF;
+  float: left;
+  text-align: center;
+}
+
+.Ldt-Ctrl-Time {
+  float: left;
+  margin: 5px;
+  font-size: 12px;
+  font-family: Arial, Verdana, sans-serif;
+}
+
+.Ldt-Ctrl-Time-Elapsed {
+  float: left;
+  color: #4a4a4a;
+}
+
+.Ldt-Ctrl-Time-Separator {
+  margin: 0 4px;      
+  float: left;
+}
+
+.Ldt-Ctrl-Time-Total {
+  float: left;
+  color: #b2b2b2; 
+}
+
+.Ldt-Ctrl-Sound {
+  margin: 0 2px;
+}
+
+.Ldt-Ctrl-Sound-Full {
+  background-position: -120px 0;
+}
+
+.Ldt-Ctrl-Sound-Full:hover {
+  background-position: -120px -25px;
+}
+
+.Ldt-Ctrl-Sound-Full:active {
+  background-position: -120px -50px;
+}
+
+.Ldt-Ctrl-Sound-Mute {
+  background-position: -150px 0;
+}
+
+.Ldt-Ctrl-Sound-Mute:hover {
+  background-position: -150px -25px;
+}
+
+.Ldt-Ctrl-Sound-Mute:active {
+  background-position: -150px -50px;
+}
+
+.Ldt-Ctrl-Sound-Half {
+  background-position: -180px 0;
+}
+
+.Ldt-Ctrl-Sound-Half:hover {
+  background-position: -180px -25px;
+}
+
+.Ldt-Ctrl-Sound-Half:active {
+  background-position: -180px -50px;
+}
+
+.Ldt-Ctrl-Volume-Control {
+    display: none;
+  position: absolute;
+  background:url('img/player_gradient.png') repeat-x transparent ;
+  height: 25px;
+  width: 100px; top: 25px; right: -1px; z-index: 100;
+  padding: 0 2px;
+  border: 1px solid #b6b8b8;
+}
+
+.Ldt-Ctrl-Volume-Bar { 
+    height: 5px; margin: 9px 3px 0; background: #cccccc; border: 1px solid #999999; border-radius: 2px;
+}
+
+.Ldt-Ctrl-Volume-Control .ui-slider-handle {
+    width: 6px; height: 19px; background: #a8a8a8; border: 1px solid #999999; border-radius: 2px; top: -8px; margin-left: -4px;
+    cursor: pointer;
+}
+
+.Ldt-Ctrl-Volume-Control:hover .ui-slider-handle {
+     background: #F7268E;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Controller.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,296 @@
+/* Displays Play and Pause buttons, Search Button and Form, Volume Control */
+
+IriSP.Widgets.Controller = function(player, config) {
+  IriSP.Widgets.Widget.call(this, player, config);
+  
+  this._searchLastValue = "";
+};
+
+IriSP.Widgets.Controller.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Controller.prototype.defaults = {
+    disable_annotate_btn: false,
+    disable_search_btn: false
+}
+
+IriSP.Widgets.Controller.prototype.template =
+    '<div class="Ldt-Ctrl">'
+    + '<div class="Ldt-Ctrl-Left">'
+    + '<div class="Ldt-Ctrl-button Ldt-Ctrl-Play Ldt-Ctrl-Play-PlayState Ldt-TraceMe" title="{{l10n.play_pause}}"></div>'
+    + '<div class="Ldt-Ctrl-spacer"></div>'
+    + '{{^disable_annotate_btn}}'
+    + '<div class="Ldt-Ctrl-button Ldt-Ctrl-Annotate Ldt-TraceMe" title="{{l10n.annotate}}"></div>'
+    + '<div class="Ldt-Ctrl-spacer"></div>'
+    + '{{/disable_annotate_btn}}'
+    + '{{^disable_search_btn}}'
+    + '<div class="Ldt-Ctrl-button Ldt-Ctrl-SearchBtn Ldt-TraceMe" title="{{l10n.search}}"></div>'
+    + '<div class="Ldt-Ctrl-spacer"></div>'
+    + '{{/disable_search_btn}}'
+    + '<div class="Ldt-Ctrl-Search">'
+    + '<input class="Ldt-Ctrl-SearchInput Ldt-TraceMe"></input>'
+    + '</div>'
+    + '</div>'
+    + '<div class="Ldt-Ctrl-Right">'
+    + '<div class="Ldt-Ctrl-spacer"></div>'
+    + '<div class="Ldt-Ctrl-Time">'
+    + '<div class="Ldt-Ctrl-Time-Elapsed" title="{{l10n.elapsed_time}}">00:00</div>'
+    + '<div class="Ldt-Ctrl-Time-Separator">/</div>'
+    + '<div class="Ldt-Ctrl-Time-Total" title="{{l10n.total_time}}">00:00</div>'
+    + '</div>'
+    + '<div class="Ldt-Ctrl-spacer"></div>'
+    + '<div class="Ldt-Ctrl-button Ldt-Ctrl-Sound Ldt-Ctrl-Sound-Full Ldt-TraceMe" title="{{l10n.mute_unmute}}"></div>'
+    + '</div>'
+    + '<div class="Ldt-Ctrl-Volume-Control" title="{{l10n.volume_control}}">'
+    + '<div class="Ldt-Ctrl-Volume-Bar"></div>'
+    + '</div>'
+    + '</div>';
+
+IriSP.Widgets.Controller.prototype.messages = {
+    en: {
+        play_pause: "Play/Pause",
+        mute_unmute: "Mute/Unmute",
+        play: "Play",
+        pause: "Pause",
+        mute: "Mute",
+        unmute: "Unmute",
+        annotate: "Annotate",
+        search: "Search",
+        elapsed_time: "Elapsed time",
+        total_time: "Total time",
+        volume: "Volume",
+        volume_control: "Volume control"
+    },
+    fr: {
+        play_pause: "Lecture/Pause",
+        mute_unmute: "Couper/Activer le son",
+        play: "Lecture",
+        pause: "Pause",
+        mute: "Couper le son",
+        unmute: "Activer le son",
+        annotate: "Annoter",
+        search: "Rechercher",
+        elapsed_time: "Durée écoulée",
+        total_time: "Durée totale",
+        volume: "Niveau sonore",
+        volume_control: "Réglage du niveau sonore"
+    }
+};
+
+IriSP.Widgets.Controller.prototype.draw = function() {
+    var _this = this;
+    this.renderTemplate();
+    
+    // Define blocks
+    this.$playButton = this.$.find(".Ldt-Ctrl-Play");
+    this.$searchBlock = this.$.find(".Ldt-Ctrl-Search");
+    this.$searchInput = this.$.find(".Ldt-Ctrl-SearchInput");
+    this.$volumeBar = this.$.find(".Ldt-Ctrl-Volume-Bar");
+    
+    // handle events
+    this.bindPopcorn("play","playButtonUpdater");
+    this.bindPopcorn("pause","playButtonUpdater");
+    this.bindPopcorn("volumechange","volumeUpdater");
+    this.bindPopcorn("timeupdate","timeDisplayUpdater");
+    this.bindPopcorn("loadedmetadata","timeDisplayUpdater");
+    this.bindPopcorn("IriSP.search.matchFound","searchMatch");
+    this.bindPopcorn("IriSP.search.noMatchFound","searchNoMatch");
+    this.bindPopcorn("IriSP.search.triggeredSearch","triggeredSearch");
+    
+    // handle clicks
+    this.$playButton.click(this.functionWrapper("playHandler"));
+    
+    this.$.find(".Ldt-Ctrl-Annotate").click(function() {
+        _this.player.popcorn.trigger("IriSP.Player.AnnotateButton.clicked");
+    });
+    this.$.find(".Ldt-Ctrl-SearchBtn").click(this.functionWrapper("searchButtonHandler"));
+    
+    this.$searchInput.keyup(this.functionWrapper("searchHandler") );
+  
+	var _volctrl = this.$.find(".Ldt-Ctrl-Volume-Control");
+    this.$.find('.Ldt-Ctrl-Sound')
+        .click(this.functionWrapper("muteHandler"))
+        .mouseover(function() {
+            _volctrl.show();
+        })
+        .mouseout(function() {
+            _volctrl.hide();
+        });
+    _volctrl.mouseover(function() {
+        _volctrl.show();
+    }).mouseout(function() {
+        _volctrl.hide();
+    });
+  
+    
+    // Allow Volume Cursor Dragging
+    this.$volumeBar.slider({
+        slide: function(event, ui) {
+            _this.$volumeBar.attr("title",_this.l10n.volume+': ' + ui.value + '%');
+            _this.player.popcorn.volume(ui.value / 100);
+        },
+        stop: this.functionWrapper("volumeUpdater")
+    });
+
+    // trigger an IriSP.Player.MouseOver to the widgets that are interested (i.e : sliderWidget)
+    this.$.hover(
+        function() {
+            _this.player.popcorn.trigger("IriSP.Player.MouseOver");
+        }, 
+        function() {
+            _this.player.popcorn.trigger("IriSP.Player.MouseOut");
+        });
+    setTimeout(this.functionWrapper("volumeUpdater"), 1000);
+    /* some players - including jwplayer - save the state of the mute button between sessions */
+};
+
+/* Update the elasped time div */
+IriSP.Widgets.Controller.prototype.timeDisplayUpdater = function() {
+    var _curTime = this.player.popcorn.roundTime();
+    if (typeof this._previousSecond !== "undefined" && _curTime === this._previousSecond) {
+        return;
+    }
+  
+    // we get it at each call because it may change.
+    var _totalTime = this.source.getDuration(),
+        _elapsedTime = new IriSP.Model.Time();
+        
+    _elapsedTime.setSeconds(_curTime);
+  
+    this.$.find(".Ldt-Ctrl-Time-Elapsed").html(_elapsedTime.toString());
+    this.$.find(".Ldt-Ctrl-Time-Total").html(_totalTime.toString());
+    this._previousSecond = _curTime;
+};
+
+/* 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.Widgets.Controller.prototype.playButtonUpdater = function() {
+    
+    var status = this.player.popcorn.media.paused;
+  
+    if (status) {
+    /* the background sprite is changed by adding/removing the correct classes */
+        this.$playButton
+            .attr("title", this.l10n.play)
+            .removeClass("Ldt-Ctrl-Play-PauseState")
+            .addClass("Ldt-Ctrl-Play-PlayState");
+    } else {
+        this.$playButton
+            .attr("title", this.l10n.pause)
+            .removeClass("Ldt-Ctrl-Play-PlayState")
+            .addClass("Ldt-Ctrl-Play-PauseState");
+    }
+};
+
+
+IriSP.Widgets.Controller.prototype.playHandler = function() {
+    
+    var status = this.player.popcorn.media.paused;
+  
+    if (status) {        
+        this.player.popcorn.play();   
+    } else {
+        this.player.popcorn.pause();
+    }  
+};
+
+IriSP.Widgets.Controller.prototype.muteHandler = function() {
+    this.player.popcorn.mute(!this.player.popcorn.muted());
+};
+
+IriSP.Widgets.Controller.prototype.volumeUpdater = function() {
+    var _muted = this.player.popcorn.muted(),
+        _vol = this.player.popcorn.volume();
+    if (_vol === false) {
+        _vol = .5;
+    }
+    var _soundCtl = this.$.find(".Ldt-Ctrl-Sound");
+    _soundCtl.removeClass("Ldt-Ctrl-Sound-Mute Ldt-Ctrl-Sound-Half Ldt-Ctrl-Sound-Full");
+    if (_muted) {        
+        _soundCtl.attr("title", this.l10n.unmute)
+            .addClass("Ldt-Ctrl-Sound-Mute");    
+    } else {
+        _soundCtl.attr("title", this.l10n.mute)
+            .addClass(_vol < .5 ? "Ldt-Ctrl-Sound-Half" : "Ldt-Ctrl-Sound-Full" )
+    }
+    this.$volumeBar.slider("value", _muted ? 0 : 100 * _vol);
+};
+
+IriSP.Widgets.Controller.prototype.showSearchBlock = function() {
+    this.$searchBlock.show("blind", { direction: "horizontal"}, 100);
+    this.$searchInput.css('background-color','#fff');
+   
+    this.$searchInput.focus();
+    
+    // we need this variable because some widgets can find a match in
+    // their data while at the same time others 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.player.popcorn.trigger("IriSP.search.open");
+};
+
+IriSP.Widgets.Controller.prototype.hideSearchBlock = function() {
+    this._searchLastValue = this.$searchInput.val();
+    this.$searchInput.val('');
+    this.$searchBlock.hide("blind", { direction: "horizontal"}, 75);
+
+    this._positiveMatch = false;
+    
+    this.player.popcorn.trigger("IriSP.search.closed");
+};
+
+/** react to clicks on the search button */
+IriSP.Widgets.Controller.prototype.searchButtonHandler = function() {
+    if ( this.$searchBlock.is(":hidden") ) {
+        this.showSearchBlock();
+        this.$searchInput.val(this._searchLastValue);      
+        this.player.popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural.
+	} else {
+        this.hideSearchBlock();
+    }
+};
+
+/** this handler is called whenever the content of the search
+   field changes */
+IriSP.Widgets.Controller.prototype.searchHandler = function() {
+    this._searchLastValue = this.$searchInput.val();
+    this._positiveMatch = false;
+  
+    // do nothing if the search field is empty, instead of highlighting everything.
+    if (this._searchLastValue == "") {
+        this.player.popcorn.trigger("IriSP.search.cleared");
+        this.$searchInput.css('background-color','');
+    } else {
+        this.player.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.Widgets.Controller.prototype.searchMatch = function() {
+    this._positiveMatch = true;
+    this.$searchInput.css('background-color','#e1ffe1');
+};
+
+/** the same, except that no value could be found */
+IriSP.Widgets.Controller.prototype.searchNoMatch = function() {
+    if (this._positiveMatch !== true) {
+        this.$searchInput.css('background-color', "#d62e3a");
+    }
+};
+
+/** react to an IriSP.Player.triggeredSearch - that is, when
+    a widget ask the.Player to do a search on his behalf */
+IriSP.Widgets.Controller.prototype.triggeredSearch = function(searchString) {
+    this.showSearchBlock();
+    this.$searchInput.attr('value', searchString);      
+    this.player.popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural.
+};
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/LdtPlayer-core.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,15 @@
+/* Base classes */
+
+.Ldt-Loader {
+    min-height: 128px;
+    background:url(img/loader.gif) center no-repeat;
+    text-indent: -9999px;
+    position: absolute;
+    width: 100%;
+}
+
+.Ldt-Widget {
+    font-family: Arial, Helvetica, sans-serif;
+    color: black;
+    font-size: 12px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/LdtPlayer-core.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,2045 @@
+/* 
+ * 	
+ *	Copyright 2010-2012 Institut de recherche et d'innovation 
+ *	contributor(s) : Karim Hamidou, Samuel Huron, Raphael Velt, Thibaut Cavalie
+ *	 
+ *	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(o){var K=o.$LAB,y="UseLocalXHR",z="AlwaysPreserveOrder",u="AllowDuplicates",A="CacheBust",B="BasePath",C=/^[^?#]*\//.exec(location.href)[0],D=/^\w+\:\/\/\/?[^\/]+/.exec(C)[0],i=document.head||document.getElementsByTagName("head"),L=(o.opera&&Object.prototype.toString.call(o.opera)=="[object Opera]")||("MozAppearance"in document.documentElement.style),q=document.createElement("script"),E=typeof q.preload=="boolean",r=E||(q.readyState&&q.readyState=="uninitialized"),F=!r&&q.async===true,M=!r&&!F&&!L;function G(a){return Object.prototype.toString.call(a)=="[object Function]"}function H(a){return Object.prototype.toString.call(a)=="[object Array]"}function N(a,c){var b=/^\w+\:\/\//;if(/^\/\/\/?/.test(a)){a=location.protocol+a}else if(!b.test(a)&&a.charAt(0)!="/"){a=(c||"")+a}return b.test(a)?a:((a.charAt(0)=="/"?D:C)+a)}function s(a,c){for(var b in a){if(a.hasOwnProperty(b)){c[b]=a[b]}}return c}function O(a){var c=false;for(var b=0;b<a.scripts.length;b++){if(a.scripts[b].ready&&a.scripts[b].exec_trigger){c=true;a.scripts[b].exec_trigger();a.scripts[b].exec_trigger=null}}return c}function t(a,c,b,d){a.onload=a.onreadystatechange=function(){if((a.readyState&&a.readyState!="complete"&&a.readyState!="loaded")||c[b])return;a.onload=a.onreadystatechange=null;d()}}function I(a){a.ready=a.finished=true;for(var c=0;c<a.finished_listeners.length;c++){a.finished_listeners[c]()}a.ready_listeners=[];a.finished_listeners=[]}function P(d,f,e,g,h){setTimeout(function(){var a,c=f.real_src,b;if("item"in i){if(!i[0]){setTimeout(arguments.callee,25);return}i=i[0]}a=document.createElement("script");if(f.type)a.type=f.type;if(f.charset)a.charset=f.charset;if(h){if(r){e.elem=a;if(E){a.preload=true;a.onpreload=g}else{a.onreadystatechange=function(){if(a.readyState=="loaded")g()}}a.src=c}else if(h&&c.indexOf(D)==0&&d[y]){b=new XMLHttpRequest();b.onreadystatechange=function(){if(b.readyState==4){b.onreadystatechange=function(){};e.text=b.responseText+"\n//@ sourceURL="+c;g()}};b.open("GET",c);b.send()}else{a.type="text/cache-script";t(a,e,"ready",function(){i.removeChild(a);g()});a.src=c;i.insertBefore(a,i.firstChild)}}else if(F){a.async=false;t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}else{t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}},0)}function J(){var l={},Q=r||M,n=[],p={},m;l[y]=true;l[z]=false;l[u]=false;l[A]=false;l[B]="";function R(a,c,b){var d;function f(){if(d!=null){d=null;I(b)}}if(p[c.src].finished)return;if(!a[u])p[c.src].finished=true;d=b.elem||document.createElement("script");if(c.type)d.type=c.type;if(c.charset)d.charset=c.charset;t(d,b,"finished",f);if(b.elem){b.elem=null}else if(b.text){d.onload=d.onreadystatechange=null;d.text=b.text}else{d.src=c.real_src}i.insertBefore(d,i.firstChild);if(b.text){f()}}function S(c,b,d,f){var e,g,h=function(){b.ready_cb(b,function(){R(c,b,e)})},j=function(){b.finished_cb(b,d)};b.src=N(b.src,c[B]);b.real_src=b.src+(c[A]?((/\?.*$/.test(b.src)?"&_":"?_")+~~(Math.random()*1E9)+"="):"");if(!p[b.src])p[b.src]={items:[],finished:false};g=p[b.src].items;if(c[u]||g.length==0){e=g[g.length]={ready:false,finished:false,ready_listeners:[h],finished_listeners:[j]};P(c,b,e,((f)?function(){e.ready=true;for(var a=0;a<e.ready_listeners.length;a++){e.ready_listeners[a]()}e.ready_listeners=[]}:function(){I(e)}),f)}else{e=g[0];if(e.finished){j()}else{e.finished_listeners.push(j)}}}function v(){var e,g=s(l,{}),h=[],j=0,w=false,k;function T(a,c){a.ready=true;a.exec_trigger=c;x()}function U(a,c){a.ready=a.finished=true;a.exec_trigger=null;for(var b=0;b<c.scripts.length;b++){if(!c.scripts[b].finished)return}c.finished=true;x()}function x(){while(j<h.length){if(G(h[j])){try{h[j++]()}catch(err){}continue}else if(!h[j].finished){if(O(h[j]))continue;break}j++}if(j==h.length){w=false;k=false}}function V(){if(!k||!k.scripts){h.push(k={scripts:[],finished:true})}}e={script:function(){for(var f=0;f<arguments.length;f++){(function(a,c){var b;if(!H(a)){c=[a]}for(var d=0;d<c.length;d++){V();a=c[d];if(G(a))a=a();if(!a)continue;if(H(a)){b=[].slice.call(a);b.unshift(d,1);[].splice.apply(c,b);d--;continue}if(typeof a=="string")a={src:a};a=s(a,{ready:false,ready_cb:T,finished:false,finished_cb:U});k.finished=false;k.scripts.push(a);S(g,a,k,(Q&&w));w=true;if(g[z])e.wait()}})(arguments[f],arguments[f])}return e},wait:function(){if(arguments.length>0){for(var a=0;a<arguments.length;a++){h.push(arguments[a])}k=h[h.length-1]}else k=false;x();return e}};return{script:e.script,wait:e.wait,setOptions:function(a){s(a,g);return e}}}m={setGlobalDefaults:function(a){s(a,l);return m},setOptions:function(){return v().setOptions.apply(null,arguments)},script:function(){return v().script.apply(null,arguments)},wait:function(){return v().wait.apply(null,arguments)},queueScript:function(){n[n.length]={type:"script",args:[].slice.call(arguments)};return m},queueWait:function(){n[n.length]={type:"wait",args:[].slice.call(arguments)};return m},runQueue:function(){var a=m,c=n.length,b=c,d;for(;--b>=0;){d=n.shift();a=a[d.type].apply(null,d.args)}return a},noConflict:function(){o.$LAB=K;return m},sandbox:function(){return J()}};return m}o.$LAB=J();(function(a,c,b){if(document.readyState==null&&document[a]){document.readyState="loading";document[a](c,b=function(){document.removeEventListener(c,b,false);document.readyState="complete"},false)}})("addEventListener","DOMContentLoaded")})(this);/* init.js - initialization and configuration of Popcorn and the widgets
+*/
+
+if (typeof window.IriSP === "undefined") {
+    IriSP = {};
+}
+
+/* The Metadataplayer Object, single point of entry, replaces IriSP.init_player */
+
+IriSP.Metadataplayer = function(config, video_metadata) {
+    for (var key in IriSP.guiDefaults) {
+        if (IriSP.guiDefaults.hasOwnProperty(key) && !config.gui.hasOwnProperty(key)) {
+            config.gui[key] = IriSP.guiDefaults[key]
+        }
+    }
+    var _container = document.getElementById(config.gui.container);
+    _container.innerHTML = '<h3 class="Ldt-Loader">Loading... Chargement...</h3>';
+    this.video_metadata = video_metadata;
+    this.sourceManager = new IriSP.Model.Directory();
+    this.config = config;
+    this.loadLibs();
+}
+
+IriSP.Metadataplayer.prototype.toString = function() {
+    return 'A Metadataplayer in DIV #' + this.config.gui.container;
+}
+
+IriSP.Metadataplayer.prototype.loadLibs = function() {
+    
+    var $L = $LAB.script(IriSP.getLib("underscore")).script(IriSP.getLib("Mustache")).script(IriSP.getLib("jQuery")).script(IriSP.getLib("swfObject")).wait().script(IriSP.getLib("jQueryUI"));
+
+    if(this.config.player.type === "jwplayer" || this.config.player.type === "allocine" || this.config.player.type === "dailymotion") {
+        // load our popcorn.js lookalike
+        $L.script(IriSP.getLib("jwplayer"));
+    } else {
+        // load the real popcorn
+        $L.script(IriSP.getLib("popcorn")).script(IriSP.getLib("popcorn.code"));
+        // load plugins if necessary
+        if(this.config.player.type === "youtube") {
+            $L.script(IriSP.getLib("popcorn.youtube"));
+        }
+        if(this.config.player.type === "vimeo"){
+            $L.script(IriSP.getLib("popcorn.vimeo"));
+        }
+    }
+
+    /* widget specific requirements */
+    for(var _i = 0; _i < this.config.gui.widgets.length; _i++) {
+        var _t = this.config.gui.widgets[_i].type;
+        if (typeof IriSP.widgetsRequirements[_t] !== "undefined" && typeof IriSP.widgetsRequirements[_t].requires !== "undefined") {
+            $L.script(IriSP.getLib(IriSP.widgetsRequirements[_t].requires));
+        }
+    }
+    
+    var _this = this;
+    
+    $L.wait(function() {
+        IriSP.jQuery = window.jQuery.noConflict();
+        IriSP._ = window._.noConflict();
+        
+        IriSP.loadCss(IriSP.getLib("cssjQueryUI"))
+        IriSP.loadCss(_this.config.gui.css);
+        
+        _this.onLibsLoaded();
+        
+    });
+}
+
+IriSP.Metadataplayer.prototype.onLibsLoaded = function() {
+    this.videoData = this.loadMetadata(this.video_metadata);
+    this.$ = IriSP.jQuery('#' + this.config.gui.container);
+    this.$.css({
+        "width": this.config.gui.width,
+        "clear": "both"
+    });
+    if (typeof this.config.gui.height !== "undefined") {
+        this.$.css("height", this.config.gui.height);
+    }
+      
+    var _this = this;
+    this.videoData.onLoad(function() {
+        _this.onVideoDataLoaded();
+    });
+}
+
+IriSP.Metadataplayer.prototype.loadMetadata = function(_metadataInfo) {
+    if (typeof _metadataInfo.serializer === "undefined" && typeof _metadataInfo.format !== "undefined") {
+        _metadataInfo.serializer = IriSP.serializers[_metadataInfo.format];
+    }
+    if (typeof _metadataInfo.url === "undefined" && typeof _metadataInfo.src !== "undefined") {
+        _metadataInfo.url = _metadataInfo.src;
+    }
+    if (typeof _metadataInfo.url !== "undefined" && typeof _metadataInfo.serializer !== "undefined") {
+        return this.sourceManager.remoteSource(_metadataInfo);
+    } else {
+        return this.sourceManager.newLocalSource(_metadataInfo);
+    }
+}
+
+IriSP.Metadataplayer.prototype.onVideoDataLoaded = function() {
+    if (typeof this.videoData !== "undefined" && typeof this.config.player.video === "undefined") {
+        var _media = this.videoData.currentMedia;
+        if (typeof _media !== "undefined") {
+            this.config.player.video = _media.video;
+            if (typeof _media.streamer !== "undefined") {
+                this.config.player.streamer = _media.streamer;
+                this.config.player.video = _media.video.replace(_media.streamer,'');
+            }
+        }
+        
+    }
+    this.configurePopcorn();
+    this.widgets = [];
+    var _this = this;
+    for(var i = 0; i < this.config.gui.widgets.length; i++) {
+        this.loadWidget(this.config.gui.widgets[i], function(_widget) {
+            _this.widgets.push(_widget)
+        });
+    };
+    this.$.find('.Ldt-Loader').detach();
+}
+
+IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) {
+    /* Creating containers if needed */
+    if (typeof _widgetConfig.container === "undefined") {
+        var _divs = this.layoutDivs(_widgetConfig.type);
+        _widgetConfig.container = _divs[0];
+    }
+    
+    var _this = this;
+    
+    if (typeof IriSP.Widgets[_widgetConfig.type] !== "undefined") {
+        IriSP._.defer(function() {
+            _callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig));
+        });
+    } else {
+        /* Loading Widget CSS */
+        if (typeof IriSP.widgetsRequirements[_widgetConfig.type] === "undefined" || typeof IriSP.widgetsRequirements[_widgetConfig.type].noCss === "undefined" || !IriSP.widgetsRequirements[_widgetConfig.type].noCss) {
+            IriSP.loadCss(IriSP.widgetsDir + '/' + _widgetConfig.type + '.css');
+        }
+        /* Loading Widget JS    */
+        $LAB.script(IriSP.widgetsDir + '/' + _widgetConfig.type + '.js').wait(function() {
+            _callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig));
+        });
+    }
+}
+
+IriSP.Metadataplayer.prototype.configurePopcorn = function() {
+    var pop,
+        ret = this.layoutDivs("video"),
+        containerDiv = ret[0],
+        spacerDiv = ret[1];
+
+    switch(this.config.player.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='" + this.config.player.video + "' id='" + tmpId + "'></video>");
+
+            if(options.hasOwnProperty("width"))
+                IriSP.jQuery("#" + containerDiv).css("width", this.config.player.width);
+
+            if(options.hasOwnProperty("height"))
+                IriSP.jQuery("#" + containerDiv).css("height", this.config.player.height);
+            pop = Popcorn("#" + tmpId);
+            break;
+
+        case "jwplayer":
+            var opts = IriSP.jQuery.extend({}, this.config.player);
+            delete opts.container;
+            delete opts.type;
+            opts.file = opts.video;
+            delete opts.video;
+
+            if(!opts.hasOwnProperty("flashplayer")) {
+                opts.flashplayer = IriSP.jwplayer_swf_path;
+            }
+
+            if(!opts.hasOwnProperty("controlbar.position")) {
+                opts["controlbar.position"] = "none";
+            }
+            pop = new IriSP.PopcornReplacement.jwplayer("#" + containerDiv, opts);
+            break;
+
+        case "youtube":
+            var opts = IriSP.jQuery.extend({}, this.config.player);
+            delete opts.container;
+            opts.controls = 0;
+            opts.autostart = false;
+            // Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
+            IriSP.jQuery("#" + containerDiv).css({
+                width : opts.width + "px",
+                height : opts.height + "px"
+            })
+            pop = Popcorn.youtube("#" + containerDiv, opts.video, opts);
+            break;
+
+        case "dailymotion":
+            pop = new IriSP.PopcornReplacement.dailymotion("#" + containerDiv, this.config.player);
+            break;
+
+        case "allocine":
+            /* pass the options as-is to the allocine player and let it handle everything */
+            pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, this.config.player);
+            break;
+        
+        default:
+            pop = undefined;
+    };
+
+    this.popcorn = pop;
+}
+
+/** create a subdiv with an unique id, and a spacer div as well.
+    @param widgetName the name of the widget.
+    @return an array of the form [createdivId, spacerdivId].
+*/
+IriSP.Metadataplayer.prototype.layoutDivs = function(_name) {
+    if (typeof(_name) === "undefined") {
+       _name = "";
+    }
+    var newDiv = IriSP._.uniqueId(this.config.gui.container + "_widget_" + _name + "_"),
+        spacerDiv = IriSP._.uniqueId("LdtPlayer_spacer_"),
+        divHtml = IriSP.jQuery('<div>')
+            .attr("id",newDiv)
+            .css({
+                width: this.config.gui.width + "px",
+                position: "relative",
+                clear: "both"
+            }),
+        spacerHtml = IriSP.jQuery('<div>')
+            .attr("id",spacerDiv)
+            .css({
+                width: this.config.gui.width + "px",
+                height: this.config.gui.spacer_div_height + "px",
+                position: "relative",
+                clear: "both"
+            });
+            
+    this.$.append(divHtml);
+    this.$.append(spacerHtml);
+
+    return [newDiv, spacerDiv];
+};
+/* utils.js - various utils that don't belong anywhere else */
+
+IriSP.jqEscape = function(_text) {
+    return text.replace(/(:|\.)/g,'\\$1');
+}
+
+IriSP.getLib = function(lib) {
+    if (IriSP.libFiles.useCdn && typeof IriSP.libFiles.cdn[lib] == "string") {
+        return IriSP.libFiles.cdn[lib];
+    }
+    if (typeof IriSP.libFiles.locations[lib] == "string") {
+        return IriSP.libFiles.locations[lib];
+    }
+    if (typeof IriSP.libFiles.inDefaultDir[lib] == "string") {
+        return IriSP.libFiles.defaultDir + '/' + IriSP.libFiles.inDefaultDir[lib];
+    }
+}
+
+IriSP.loadCss = function(_cssFile) {
+    IriSP.jQuery("<link>", {
+        rel : "stylesheet",
+        type : "text/css",
+        href : _cssFile
+    }).appendTo('head');
+}/* wrapper that simulates popcorn.js because
+   popcorn is a bit unstable at the time */
+
+IriSP.PopcornReplacement = {  
+};
+
+/** base class for our popcorn-compatible players.
+ */
+IriSP.PopcornReplacement.player = function(container, options) {
+  /* the jwplayer calls the callbacks in the global space so we need to 
+     preserve them this way */
+  if (typeof IriSP._ === "undefined") {
+      return;
+  }
+    
+  this.callbacks = {
+      onReady:  IriSP._.bind(this.__initApi, this),
+      onTime:   IriSP._.bind(this.__timeHandler, this),
+      onPlay:   IriSP._.bind(this.__playHandler, this),
+      onPause:  IriSP._.bind(this.__pauseHandler, this),
+      onSeek:   IriSP._.bind(this.__seekHandler, this) 
+  };
+  
+  this.media = { 
+    "paused": true,
+    "muted": false
+  };
+    
+  this.container = container.slice(1); //eschew the '#'
+  
+  this.msgPump = {}; /* dictionnary used to receive and send messages */
+  this.__codes = []; /* used to schedule the execution of a piece of code in 
+                        a segment (similar to the popcorn.code plugin). */
+  
+  this._options = options;
+                          
+};
+
+IriSP.PopcornReplacement.player.prototype.listen = function(msg, callback) {
+  if (!this.msgPump.hasOwnProperty(msg))
+    this.msgPump[msg] = [];
+
+  this.msgPump[msg].push(callback);
+};
+
+IriSP.PopcornReplacement.player.prototype.trigger = function(msg, params) {
+  if (!this.msgPump.hasOwnProperty(msg))
+    return;
+
+  var d = this.msgPump[msg];
+
+  for(var i = 0; i < d.length; i++) {
+    d[i].call(window, params);
+  }
+
+};
+
+IriSP.PopcornReplacement.player.prototype.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;
+};
+
+/** init the api after that flash player has been setup - called by the callback
+    defined by the embedded flash player 
+*/
+IriSP.PopcornReplacement.player.prototype.__initApi = function() {
+  this.trigger("loadedmetadata"); // we've done more than loading metadata of course,
+                                                      // but popcorn doesn't need to know more.
+  this.media.muted = this.playerFns.getMute();
+  /* some programmed segments are supposed to be run at the beginning */
+  var i = 0;
+  for(i = 0; i < this.__codes.length; i++) {
+    var c = this.__codes[i];
+    if (0 == c.start) {
+      c.onStart();
+    }
+    
+    if (0 == c.end) {
+      c.onEnd();
+    }
+  }
+};
+
+IriSP.PopcornReplacement.player.prototype.currentTime = function(time) {
+  if (typeof(time) === "undefined") {        
+      return this.playerFns.getPosition();            
+  } else {
+     var currentTime = +time;
+     this.playerFns.seek(currentTime);              
+     return currentTime;
+  }
+};
+
+IriSP.PopcornReplacement.player.prototype.play = function() {
+  this.media.paused = false;
+  this.trigger("play");
+  //IriSP.PopcornReplacement.trigger("playing");
+  this.playerFns.play();
+};
+    
+IriSP.PopcornReplacement.player.prototype.pause = function() {
+//  if ( !this.media.paused ) {
+    this.media.paused = true;
+    this.trigger( "pause" );
+    this.playerFns.pause();
+//  }
+};
+
+IriSP.PopcornReplacement.player.prototype.muted = function(val) {
+  if (typeof(val) !== "undefined") {
+
+    if (this.playerFns.getMute() !== val) {
+      if (val) {
+        this.playerFns.setMute(true);
+        this.media.muted = true;
+      } else {
+        this.playerFns.setMute(false);
+        this.media.muted = false;
+      }
+
+      this.trigger( "volumechange" );
+    }
+    
+    return this.playerFns.getMute();
+  } else {
+    return this.playerFns.getMute();
+  }
+};
+
+IriSP.PopcornReplacement.player.prototype.volume = function(val) {
+    if (typeof this.playerFns.getVolume == "undefined" || typeof this.playerFns.setVolume == "undefined") {
+        return false;
+    }
+    var _vol = this.playerFns.getVolume();
+    if (typeof(val) !== "undefined" && parseFloat(val) !== NaN) {
+        val = Math.max(0, Math.min(1, val));
+        if (parseFloat(val) != parseFloat(_vol)) {
+            this.playerFns.setVolume(val);
+            this.trigger("volumechange");
+            _vol = this.playerFns.getVolume();
+        }
+    }
+    return _vol;
+};
+
+IriSP.PopcornReplacement.player.prototype.mute = IriSP.PopcornReplacement.player.prototype.muted;
+
+IriSP.PopcornReplacement.player.prototype.code = function(options) {
+  this.__codes.push(options);
+  return this;
+};
+
+/* called everytime the player updates itself 
+   (onTime event)
+ */
+
+IriSP.PopcornReplacement.player.prototype.__timeHandler = function(event) {
+  var pos = event.position;
+
+  var i = 0;
+  for(i = 0; i < this.__codes.length; i++) {
+     var c = this.__codes[i];
+
+     if (pos >= c.start && pos < c.end && 
+         pos - 1 <= c.start) {       
+        c.onStart();
+     }
+ 
+     if (pos > c.start && pos > c.end && 
+         pos - 1 <= c.end) {
+         c.onEnd();
+     }
+   
+  }
+ 
+  this.trigger("timeupdate");
+};
+
+IriSP.PopcornReplacement.player.prototype.__seekHandler = function(event) {
+  var i = 0;
+  
+  for(i = 0; i < this.__codes.length; i++) {
+     var c = this.__codes[i];
+    
+     if (event.position >= c.start && event.position < c.end) {        
+        c.onEnd();
+     }         
+   }
+  
+   for(i = 0; i < this.__codes.length; i++) {
+     var c = this.__codes[i];
+
+     if (typeof(event.offset) === "undefined")
+       event.offset = 0;
+           
+     if (event.offset >= c.start && event.offset < c.end) { 
+       c.onStart();
+     }
+     
+   }
+  
+  /* this signal sends as an extra argument the position in the video.
+     As far as I know, this argument is not provided by popcorn */
+  this.trigger("seeked", event.offset);  
+};
+
+IriSP.PopcornReplacement.player.prototype.__playHandler = function(event) {
+  this.media.paused = false;
+  this.trigger("play");
+};
+
+IriSP.PopcornReplacement.player.prototype.__pauseHandler = function(event) {
+  this.media.paused = true;
+  this.trigger("pause");
+};
+
+IriSP.PopcornReplacement.player.prototype.roundTime = function() {
+  var currentTime = this.currentTime();
+  return Math.round(currentTime);
+};/* model.js is where data is stored in a standard form, whatever the serializer */
+
+IriSP.Model = {
+    _SOURCE_STATUS_EMPTY : 0,
+    _SOURCE_STATUS_WAITING : 1,
+    _SOURCE_STATUS_READY : 2,
+    _ID_AUTO_INCREMENT : 0,
+    getUID : function() {
+        return "autoid-" + (++this._ID_AUTO_INCREMENT);
+    },
+    regexpFromTextOrArray : function(_textOrArray) {
+        function escapeText(_text) {
+            return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
+        }
+        return new RegExp( '('
+            + (
+                typeof _textOrArray === "string"
+                ? escapeText(_textOrArray)
+                : IriSP._(_textOrArray).map(escapeText).join("|")
+            )
+            + ')',
+            'gim'
+        );
+    },
+    isoToDate : function(_str) {
+        // http://delete.me.uk/2005/03/iso8601.html
+        var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
+        var d = _str.match(new RegExp(regexp));
+    
+        var offset = 0;
+        var date = new Date(d[1], 0, 1);
+    
+        if (d[3]) { date.setMonth(d[3] - 1); }
+        if (d[5]) { date.setDate(d[5]); }
+        if (d[7]) { date.setHours(d[7]); }
+        if (d[8]) { date.setMinutes(d[8]); }
+        if (d[10]) { date.setSeconds(d[10]); }
+        if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
+        if (d[14]) {
+            offset = (Number(d[16]) * 60) + Number(d[17]);
+            offset *= ((d[15] == '-') ? 1 : -1);
+        }
+    
+        offset -= date.getTimezoneOffset();
+        time = (Number(date) + (offset * 60 * 1000));
+        var _res = new Date();
+        _res.setTime(Number(time));
+        return _res;
+    },
+    dateToIso : function(d) {  
+        function pad(n){return n<10 ? '0'+n : n}  
+        return d.getUTCFullYear()+'-'  
+            + pad(d.getUTCMonth()+1)+'-'  
+            + pad(d.getUTCDate())+'T'  
+            + pad(d.getUTCHours())+':'  
+            + pad(d.getUTCMinutes())+':'  
+            + pad(d.getUTCSeconds())+'Z'  
+    }
+}
+
+/*
+ * IriSP.Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID)
+ */
+IriSP.Model.List = function(_directory) {
+    Array.call(this);
+    this.directory = _directory;
+    this.idIndex = [];
+    if (typeof _directory == "undefined") {
+        throw "Error : new IriSP.Model.List(directory): directory is undefined";
+    }
+}
+
+IriSP.Model.List.prototype = new Array();
+
+IriSP.Model.List.prototype.getElement = function(_id) {
+    var _index = IriSP._(this.idIndex).indexOf(_id);
+    if (_index !== -1) {
+        return this[_index];
+    } else {
+        var _un = _id.replace(/.*:/);
+        return IriSP._(this.idIndex).find(function(_i) {
+            return _i.replace(/.*:/) === _un;
+        });
+    }
+}
+
+IriSP.Model.List.prototype.hasId = function(_id) {
+    return (IriSP._(this.idIndex).indexOf(_id) !== -1);
+}
+
+/* On recent browsers, forEach and map are defined and do what we want.
+ * Otherwise, we'll use the Underscore.js functions
+ */
+if (typeof Array.prototype.forEach === "undefined") {
+    IriSP.Model.List.prototype.forEach = function(_callback) {
+        var _this = this;
+        IriSP._(this).forEach(function(_value, _key) {
+            _callback(_value, _key, _this);
+        });
+    }
+}
+
+if (typeof Array.prototype.map === "undefined") {
+    IriSP.Model.List.prototype.map = function(_callback) {
+        var _this = this;
+        return IriSP._(this).map(function(_value, _key) {
+            return _callback(_value, _key, _this);
+        });
+    }
+}
+
+/* We override Array's filter function because it doesn't return an IriSP.Model.List
+ */
+IriSP.Model.List.prototype.filter = function(_callback) {
+    var _this = this,
+        _res = new IriSP.Model.List(this.directory);
+    _res.addElements(IriSP._(this).filter(function(_value, _key) {
+        return _callback(_value, _key, _this);
+    }));
+    return _res;
+}
+
+IriSP.Model.List.prototype.slice = function(_start, _end) {
+    var _res = new IriSP.Model.List(this.directory);
+    _res.addElements(Array.prototype.slice.call(this, _start, _end));
+    return _res;
+}
+
+IriSP.Model.List.prototype.splice = function(_start, _end) {
+    var _res = new IriSP.Model.List(this.directory);
+    _res.addElements(Array.prototype.splice.call(this, _start, _end));
+    this.idIndex.splice(_start, _end);
+    return _res;
+}
+
+/* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
+ * and won't return a new IriSP.Model.List
+ */
+IriSP.Model.List.prototype.sortBy = function(_callback) {
+    var _this = this,
+        _res = new IriSP.Model.List(this.directory);
+    _res.addElements(IriSP._(this).sortBy(function(_value, _key) {
+        return _callback(_value, _key, _this);
+    }));
+    return _res;
+}
+
+/* Title and Description are basic information for (almost) all element types,
+ * here we can search by these criteria
+ */
+IriSP.Model.List.prototype.searchByTitle = function(_text) {
+    var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
+    return this.filter(function(_element) {
+        return _rgxp.test(_element.title);
+    });
+}
+
+IriSP.Model.List.prototype.searchByDescription = function(_text) {
+    var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
+    return this.filter(function(_element) {
+        return _rgxp.test(_element.description);
+    });
+}
+
+IriSP.Model.List.prototype.searchByTextFields = function(_text) {
+    var _rgxp =  IriSP.Model.regexpFromTextOrArray(_text);
+    return this.filter(function(_element) {
+        return _rgxp.test(_element.description) || _rgxp.test(_element.title);
+    });
+}
+
+IriSP.Model.List.prototype.getTitles = function() {
+    return this.map(function(_el) {
+        return _el.title;
+    });
+}
+
+IriSP.Model.List.prototype.addId = function(_id) {
+    var _el = this.directory.getElement(_id)
+    if (!this.hasId(_id) && typeof _el !== "undefined") {
+        this.idIndex.push(_id);
+        Array.prototype.push.call(this, _el);
+    }
+}
+
+IriSP.Model.List.prototype.push = function(_el) {
+    if (typeof _el === "undefined") {
+        return;
+    }
+    var _index = (IriSP._(this.idIndex).indexOf(_el.id));
+    if (_index === -1) {
+        this.idIndex.push(_el.id);
+        Array.prototype.push.call(this, _el);
+    } else {
+        this[_index] = _el;
+    }
+}
+
+IriSP.Model.List.prototype.addIds = function(_array) {
+    var _l = _array.length,
+        _this = this;
+    IriSP._(_array).forEach(function(_id) {
+        _this.addId(_id);
+    });
+}
+
+IriSP.Model.List.prototype.addElements = function(_array) {
+    var _this = this;
+    IriSP._(_array).forEach(function(_el) {
+        _this.push(_el);
+    });
+}
+
+IriSP.Model.List.prototype.removeId = function(_id) {
+    var _index = (IriSP._(this.idIndex).indexOf(_id));
+    if (_index !== -1) {
+        this.splice(_index,1);
+    }
+}
+
+IriSP.Model.List.prototype.removeElement = function(_el) {
+    this.removeId(_el.id);
+}
+
+IriSP.Model.List.prototype.removeIds = function(_list) {
+    var _this = this;
+    IriSP._(_list).forEach(function(_id) {
+        _this.removeId(_id);
+    });
+}
+
+IriSP.Model.List.prototype.removeElements = function(_list) {
+    var _this = this;
+    IriSP._(_list).forEach(function(_el) {
+        _this.removeElement(_el);
+    });
+}
+
+/* A simple time management object, that helps converting millisecs to seconds and strings,
+ * without the clumsiness of the original Date object.
+ */
+
+IriSP.Model.Time = function(_milliseconds) {
+    this.milliseconds = parseInt(typeof _milliseconds !== "undefined" ? _milliseconds : 0);
+}
+
+IriSP.Model.Time.prototype.setSeconds = function(_seconds) {
+    this.milliseconds = 1000 * _seconds;
+}
+
+IriSP.Model.Time.prototype.getSeconds = function() {
+    return Math.floor(this.milliseconds / 1000);
+}
+
+IriSP.Model.Time.prototype.getHMS = function() {
+    var _totalSeconds = Math.abs(this.getSeconds());
+    return {
+        hours : Math.floor(_totalSeconds / 3600),
+        minutes : (Math.floor(_totalSeconds / 60) % 60),
+        seconds : _totalSeconds % 60
+    } 
+}
+
+IriSP.Model.Time.prototype.valueOf = function() {
+    return this.milliseconds;
+}
+
+IriSP.Model.Time.prototype.toString = function() {
+    function pad(_n) {
+        var _res = _n.toString();
+        while (_res.length < 2) {
+            _res = '0' + _res;
+        }
+        return _res;
+    }
+    var _hms = this.getHMS(),
+        _res = '';
+    if (_hms.hours) {
+        _res += pad(_hms.hours) + ':'
+    }
+    _res += pad(_hms.minutes) + ':' + pad(_hms.seconds);
+    return _res;
+}
+
+/* IriSP.Model.Reference handles references between elements
+ */
+
+IriSP.Model.Reference = function(_source, _idRef) {
+    this.source = _source;
+    if (typeof _idRef === "object") {
+        this.isList = true;
+        this.id = IriSP._(_idRef).map(function(_id) {
+            return _source.getNamespaced(_id).fullname;
+        });
+    } else {
+        this.isList = false;
+        this.id = _source.getNamespaced(_idRef).fullname;
+    }
+    this.refresh();
+}
+
+IriSP.Model.Reference.prototype.refresh = function() {
+    if (this.isList) {
+        this.contents = new IriSP.Model.List(this.source.directory);
+        this.contents.addIds(this.id);
+    } else {
+        this.contents = this.source.directory.getElement(this.id);
+    }
+    
+}
+
+IriSP.Model.Reference.prototype.getContents = function() {
+    if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) {
+        this.refresh();
+    }
+    return this.contents;
+}
+
+IriSP.Model.Reference.prototype.isOrHasId = function(_idRef) {
+    if (this.isList) {
+        return (IriSP._(this.id).indexOf(_idRef) !== -1)
+    } else {
+        return (this.id == _idRef);
+    }
+}
+
+/* */
+
+IriSP.Model.Element = function(_id, _source) {
+    this.elementType = 'element';
+    if (typeof _source === "undefined") {
+        return;
+    }
+    if (typeof _id === "undefined" || !_id) {
+        _id = IriSP.Model.getUID();
+    }
+    this.source = _source;
+    this.namespacedId = _source.getNamespaced(_id)
+    this.id = this.namespacedId.fullname;
+    this.title = "";
+    this.description = "";
+    this.source.directory.addElement(this);
+}
+
+IriSP.Model.Element.prototype.toString = function() {
+    return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
+}
+
+IriSP.Model.Element.prototype.setReference = function(_elementType, _idRef) {
+    this[_elementType] = new IriSP.Model.Reference(this.source, _idRef);
+}
+
+IriSP.Model.Element.prototype.getReference = function(_elementType) {
+    if (typeof this[_elementType] !== "undefined") {
+        return this[_elementType].getContents();
+    }
+}
+
+IriSP.Model.Element.prototype.getRelated = function(_elementType, _global) {
+    _global = (typeof _global !== "undefined" && _global);
+    var _this = this;
+    return this.source.getList(_elementType, _global).filter(function(_el) {
+        var _ref = _el[_this.elementType];
+        return _ref.isOrHasId(_this.id);
+    });
+}
+
+/* */
+
+IriSP.Model.Media = function(_id, _source) {
+    IriSP.Model.Element.call(this, _id, _source);
+    this.elementType = 'media';
+    this.duration = new IriSP.Model.Time();
+    this.video = '';
+}
+
+IriSP.Model.Media.prototype = new IriSP.Model.Element();
+
+IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
+    this.duration.milliseconds = _durationMs;
+}
+
+IriSP.Model.Media.prototype.getAnnotations = function() {
+    return this.getRelated("annotation");
+}
+
+/* */
+
+IriSP.Model.Tag = function(_id, _source) {
+    IriSP.Model.Element.call(this, _id, _source);
+    this.elementType = 'tag';
+}
+
+IriSP.Model.Tag.prototype = new IriSP.Model.Element();
+
+IriSP.Model.Tag.prototype.getAnnotations = function() {
+    return this.getRelated("annotation");
+}
+
+/* */
+
+IriSP.Model.AnnotationType = function(_id, _source) {
+    IriSP.Model.Element.call(this, _id, _source);
+    this.elementType = 'annotationType';
+}
+
+IriSP.Model.AnnotationType.prototype = new IriSP.Model.Element();
+
+IriSP.Model.AnnotationType.prototype.getAnnotations = function() {
+    return this.getRelated("annotation");
+}
+
+/* Annotation
+ * */
+
+IriSP.Model.Annotation = function(_id, _source) {
+    IriSP.Model.Element.call(this, _id, _source);
+    this.elementType = 'annotation';
+    this.begin = new IriSP.Model.Time();
+    this.end = new IriSP.Model.Time();
+}
+
+IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
+
+IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
+    this.begin.milliseconds = _beginMs;
+}
+
+IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
+    this.end.milliseconds = _beginMs;
+}
+
+IriSP.Model.Annotation.prototype.setMedia = function(_idRef) {
+    this.setReference("media", _idRef);
+}
+
+IriSP.Model.Annotation.prototype.getMedia = function() {
+    return this.getReference("media");
+}
+
+IriSP.Model.Annotation.prototype.setAnnotationType = function(_idRef) {
+    this.setReference("annotationType", _idRef);
+}
+
+IriSP.Model.Annotation.prototype.getAnnotationType = function() {
+    return this.getReference("annotationType");
+}
+
+IriSP.Model.Annotation.prototype.setTags = function(_idRefs) {
+    this.setReference("tag", _idRefs);
+}
+
+IriSP.Model.Annotation.prototype.getTags = function() {
+    return this.getReference("tag");
+}
+
+IriSP.Model.Annotation.prototype.getTagTexts = function() {
+    return this.getTags().getTitles();
+}
+
+/* */
+
+IriSP.Model.Source = function(_config) {
+    this.status = IriSP.Model._SOURCE_STATUS_EMPTY;
+    if (typeof _config !== "undefined") {
+        var _this = this;
+        IriSP._(_config).forEach(function(_v, _k) {
+            _this[_k] = _v;
+        })
+        this.callbackQueue = [];
+        this.contents = {};
+        if (typeof this.namespace === "undefined") {
+            this.namespace = "metadataplayer";
+        } else {
+            if (typeof this.namespaceUrl === "undefined" && typeof this.url !== "undefined") {
+                var _matches = this.url.match(/(^[^?&]+|[^?&][a-zA-Z0-9_%=?]+)/g),
+                    _url = _matches[0];
+                if (_matches.length > 1) {
+                    _matches = IriSP._(_matches.slice(1)).reject(function(_txt) {
+                        return /\?$/.test(_txt);
+                    });
+                }
+                if (_matches.length > 0) {
+                    _url += '?' + _matches.join('&');
+                }
+                this.namespaceUrl = _url;
+            }
+        }
+        if (typeof this.namespaceUrl === "undefined") {
+            this.namespaceUrl = "http://ldt.iri.centrepompidou.fr/";
+        }
+        this.directory.addNamespace(this.namespace, this.namespaceUrl);
+        this.get();
+    }
+}
+
+IriSP.Model.Source.prototype.getNamespaced = function(_id) {
+    var _tab = _id.split(':');
+    if (_tab.length > 1) {
+        return {
+            namespace : _tab[0],
+            name : _tab[1],
+            fullname : _id
+        }
+    } else {
+        return {
+            namespace : this.namespace,
+            name : _id,
+            fullname : this.namespace + ':' + _id
+        }
+    }
+}
+    
+IriSP.Model.Source.prototype.unNamespace = function(_id) {
+    if (typeof _id !== "undefined") {
+        return _id.replace(this.namespace + ':', '');
+    }
+}
+
+IriSP.Model.Source.prototype.addList = function(_listId, _contents) {
+    if (typeof this.contents[_listId] === "undefined") {
+        this.contents[_listId] = new IriSP.Model.List(this.directory);
+    }
+    this.contents[_listId].addElements(_contents);
+}
+
+IriSP.Model.Source.prototype.getList = function(_listId, _global) {
+    _global = (typeof _global !== "undefined" && _global);
+    if (_global || typeof this.contents[_listId] === "undefined") {
+        return this.directory.getGlobalList().filter(function(_e) {
+            return (_e.elementType === _listId);
+        });
+    } else {
+        return this.contents[_listId];
+    }
+}
+
+IriSP.Model.Source.prototype.forEach = function(_callback) {
+    var _this = this;
+    IriSP._(this.contents).forEach(function(_value, _key) {
+        _callback.call(_this, _value, _key);
+    })
+}
+
+IriSP.Model.Source.prototype.getElement = function(_elId) {
+    return this.directory.getElement(this.getNamespaced(_elId).fullname);
+}
+
+IriSP.Model.Source.prototype.setCurrentMediaId = function(_idRef) {
+    if (typeof _idRef !== "undefined") {
+        this.currentMedia = this.getMedias().getElement(this.getNamespaced(_idRef).fullname);
+    }
+}
+
+IriSP.Model.Source.prototype.setDefaultCurrentMedia = function() {
+    if (typeof this.currentMedia === "undefined" && this.getMedias().length) {
+        this.currentMedia = this.getMedias()[0];
+    }
+}
+
+IriSP.Model.Source.prototype.listNamespaces = function(_excludeSelf) {
+    var _this = this,
+        _nsls = [],
+        _excludeSelf = (typeof _excludeSelf !== "undefined" && _excludeSelf);
+    this.forEach(function(_list) {
+        IriSP._(_list).forEach(function(_el) {
+            var _ns = _el.id.replace(/:.*$/,'');
+            if (IriSP._(_nsls).indexOf(_ns) === -1 && (!_excludeSelf || _ns !== _this.namespace)) {
+                _nsls.push(_ns);
+            }
+        })
+    });
+    return _nsls;
+}
+
+IriSP.Model.Source.prototype.get = function() {
+    this.status = IriSP.Model._SOURCE_STATUS_WAITING;
+    this.handleCallbacks();
+}
+
+/* We defer the callbacks calls so they execute after the queue is cleared */
+IriSP.Model.Source.prototype.deferCallback = function(_callback) {
+    var _this = this;
+    IriSP._.defer(function() {
+        _callback.call(_this);
+    });
+}
+
+IriSP.Model.Source.prototype.handleCallbacks = function() {
+    this.status = IriSP.Model._SOURCE_STATUS_READY;
+    while (this.callbackQueue.length) {
+        this.deferCallback(this.callbackQueue.splice(0,1)[0]);
+    }
+}
+
+IriSP.Model.Source.prototype.onLoad = function(_callback) {
+    if (this.status === IriSP.Model._SOURCE_STATUS_READY) {
+        this.deferCallback(_callback);
+    } else {
+        this.callbackQueue.push(_callback);
+    }
+}
+
+IriSP.Model.Source.prototype.serialize = function() {
+    return this.serializer.serialize(this);
+}
+
+IriSP.Model.Source.prototype.deSerialize = function(_data) {
+    this.serializer.deSerialize(_data, this);
+}
+
+IriSP.Model.Source.prototype.getAnnotations = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("annotation", _global);
+}
+
+IriSP.Model.Source.prototype.getMedias = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("media", _global);
+}
+
+IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("annotationType", _global);
+}
+
+IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) {
+    _global = (typeof _global !== "undefined" && _global);
+    var _res = new IriSP.Model.List(this.directory),
+        _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title);
+    _annTypes.forEach(function(_annType) {
+        _res.addElements(_annType.getAnnotations(_global));
+    })
+    return _res;
+}
+
+IriSP.Model.Source.prototype.getDuration = function() {
+    var _m = this.currentMedia;
+    if (typeof _m !== "undefined") {
+        return this.currentMedia.duration;
+    }
+}
+
+/* */
+
+IriSP.Model.RemoteSource = function(_config) {
+    IriSP.Model.Source.call(this, _config);
+}
+
+IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source();
+
+IriSP.Model.RemoteSource.prototype.get = function() {
+    this.status = IriSP.Model._SOURCE_STATUS_WAITING;
+    var _this = this;
+    this.serializer.loadData(this.url, function(_result) {
+        _this.deSerialize(_result);
+        _this.handleCallbacks();
+    });
+}
+
+/* */
+
+IriSP.Model.Directory = function() {
+    this.remoteSources = {};
+    this.elements = {};
+    this.namespaces = {};
+}
+
+IriSP.Model.Directory.prototype.addNamespace = function(_namespace, _url) {
+    this.namespaces[_namespace] = _url;
+}
+
+IriSP.Model.Directory.prototype.remoteSource = function(_properties) {
+    var _config = IriSP._({ directory: this }).extend(_properties);
+    if (typeof this.remoteSources[_properties.url] === "undefined") {
+        this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config);
+    }
+    return this.remoteSources[_properties.url];
+}
+
+IriSP.Model.Directory.prototype.newLocalSource = function(_properties) {
+    var _config = IriSP._({ directory: this }).extend(_properties),
+        _res = new IriSP.Model.Source(_config);
+    return _res;
+}
+
+IriSP.Model.Directory.prototype.getElement = function(_id) {
+    var _res = this.elements[_id];
+    if (typeof _res === "undefined") {
+        var _un = _id.replace(/.*:/),
+            _keys = IriSP._(this.elements).keys();
+            _key = IriSP._(_keys).find(function(_i) {
+                return _i.replace(/.*:/) === _un;
+            });
+        if (typeof _key !== "undefined") {
+            _res = this.elements[_key];
+        }
+    }
+    return _res;
+}
+
+IriSP.Model.Directory.prototype.addElement = function(_element) {
+    this.elements[_element.id] = _element;
+}
+
+IriSP.Model.Directory.prototype.getGlobalList = function() {
+    var _res = new IriSP.Model.List(this);
+    _res.addIds(IriSP._(this.elements).keys());
+    return _res;
+}
+
+/* */
+IriSP.language = 'en';
+
+IriSP.libFiles = {
+    defaultDir : "js/libs/",
+    inDefaultDir : {
+        underscore : "underscore-min.js",
+        Mustache : "mustache.js",
+        jQuery : "jquery.min.js",
+        jQueryUI : "jquery-ui.min.js",
+        swfObject : "swfobject.js",
+        cssjQueryUI : "jquery-ui.css",
+        popcorn : "popcorn.js",
+        jwplayer : "jwplayer.js",
+        raphael : "raphael-min.js",
+        "popcorn.mediafragment" : "popcorn.mediafragment.js",
+        "popcorn.code" : "popcorn.code.js",
+        "popcorn.jwplayer" : "popcorn.jwplayer.js",
+        "popcorn.youtube" : "popcorn.youtube.js",
+        tracemanager : "tracemanager.js"
+    },
+    locations : {
+        // use to define locations outside defautl_dir
+    },
+    cdn : {
+        jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.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"
+    },
+    useCdn : false
+}
+
+IriSP.widgetsDir = 'widgets';
+
+IriSP.widgetsRequirements = {
+    Sparkline: {
+        noCss: true,
+        requires: "raphael"
+    },
+    Arrow: {
+        noCss: true,
+        requires: "raphael"
+    },
+    Mediafragment: {
+        noCss: true
+    },
+    Trace : {
+        noCss: true,
+        requires: "tracemanager"
+    }
+}
+
+IriSP.guiDefaults = {
+    width : 640,            
+    container : 'LdtPlayer',
+    spacer_div_height : 0
+}
+/* Definition of an ancestor for the Widget classes */
+
+if (typeof IriSP.Widgets === "undefined") {
+    IriSP.Widgets = {}
+}
+
+/**
+ * @class IriSP.Widget is an "abstract" class. It's mostly used to define some properties common to every widget.
+ *
+ *  Note that widget constructors are never called directly by the user. Instead, the widgets are instantiated by functions
+ *  defined in init.js
+ *
+ * @constructor
+ * @param player - a reference to the player widget
+ * @param config - configuration options for the widget
+ */
+
+
+IriSP.Widgets.Widget = function(player, config) {
+
+    if( typeof player === "undefined") {
+        /* Probably an abstract call of the class when
+         * individual widgets set their prototype */
+        return;
+    }
+    
+    /* Setting all the configuration options */
+    var _type = config.type,
+        _config = IriSP._.defaults({}, config, player.config.gui.default_options, this.defaults),
+        _this = this;
+    
+    IriSP._(_config).forEach(function(_value, _key) {
+       _this[_key] = _value;
+    });
+    
+    if (typeof this.width === "undefined") {
+        this.width = player.config.gui.width;
+    }
+    
+    /* Setting this.player at the end in case it's been overriden
+     * by a configuration option of the same name :-(
+     */
+    this.player = player;
+    
+    /* Getting metadata */
+    this.source = player.loadMetadata(this.metadata);
+    
+    /* Call draw when loaded */
+    this.source.onLoad(function() {
+        _this.draw();
+    });
+   
+    /* Adding classes and html attributes */
+    this.$ = IriSP.jQuery('#' + this.container);
+    this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type);
+    
+    /* Does the widget require other widgets ? */
+    if (typeof this.requires !== "undefined") {
+        for (var _i = 0; _i < this.requires.length; _i++) {
+            var _subconfig = this.requires[_i];
+            _subconfig.container = IriSP._.uniqueId(this.container + '_' + _subconfig.type + '_');
+            this.$.append(IriSP.jQuery('<div>').attr("id",_subconfig.container));
+            this.player.loadWidget(_subconfig, function(_widget) {
+                _this[_subconfig.type.replace(/^./,function(_s){return _s.toLowerCase();})] = _widget
+            });
+        }
+    }
+    
+    this.l10n = (typeof this.messages[IriSP.language] !== "undefined" ? this.messages[IriSP.language] : this.messages["en"]);
+    
+};
+
+IriSP.Widgets.Widget.prototype.defaults = {}
+
+IriSP.Widgets.Widget.prototype.template = '';
+
+IriSP.Widgets.Widget.prototype.messages = {"en":{}};
+
+IriSP.Widgets.Widget.prototype.templateToHtml = function(_template) {
+    return Mustache.to_html(_template, this);
+}
+
+IriSP.Widgets.Widget.prototype.renderTemplate = function() {
+    this.$.append(this.templateToHtml(this.template));
+}
+
+IriSP.Widgets.Widget.prototype.functionWrapper = function(_name) {
+    var _this = this,
+        _function = this[_name];
+    if (typeof _function !== "undefined") {
+        return function() {
+            return _function.apply(_this, Array.prototype.slice.call(arguments, 0));
+        }
+    } else {
+        console.log("Error, Unknown function IriSP." + this.type + "." + _name)
+    }
+}
+
+IriSP.Widgets.Widget.prototype.bindPopcorn = function(_popcornEvent, _functionName) {
+    this.player.popcorn.listen(_popcornEvent, this.functionWrapper(_functionName))
+}
+
+IriSP.Widgets.Widget.prototype.getWidgetAnnotations = function() {
+    return typeof this.annotation_type !== "undefined" && this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations();
+}
+
+/**
+ * This method responsible of drawing a widget on screen.
+ */
+IriSP.Widgets.Widget.prototype.draw = function() {
+    /* implemented by "sub-classes" */
+};
+/**
+ * Optional method if you want your widget to support redraws.
+ */
+IriSP.Widgets.Widget.prototype.redraw = function() {
+    /* implemented by "sub-classes" */
+};
+/* To wrap a player the develop should create a new class derived from
+the IriSP.PopcornReplacement.player and defining the correct functions */
+
+/** allocine player wrapper */
+IriSP.PopcornReplacement.allocine = function(container, options) {
+//    console.log("Calling allocine player");
+    /* appel du parent pour initialiser les structures communes à tous les players */
+    IriSP.PopcornReplacement.player.call(this, container, options);   
+    
+    var _this = this;
+
+    /* Définition des fonctions de l'API -  */
+
+    this.playerFns = {
+        play : function() {
+            return _this.apiCall("play");
+        },
+        pause : function() {
+            return _this.apiCall("pause");
+        },
+        getPosition : function() {
+            return _this.apiCall("getSeek","return") || 0;
+        },
+        seek : function(pos) {
+            return _this.apiCall("seek",pos);
+        },
+        getMute : function() {
+            return _this.apiCall("getMute","return");
+        },
+        setMute : function(p) {
+            return _this.apiCall("setMute", p);
+        }
+    }
+
+    window.onReady = IriSP.wrap(this, this.ready);
+    window.onAllocineStateChange = IriSP.wrap(this, this.stateHandler);
+    window.onTime = IriSP.wrap(this, this.progressHandler);
+    
+    var _flashVars = {
+        "streamFMS" : true,
+        "adVast" : false,
+        "lg" : "fr_cinecast",
+        "autoPlay" : options.autoPlay,
+        "directVideoTitle" : "",
+        "urlAcData" : options.urlAcData,
+        "directVideoPath" : options.video,
+        "host" : "http://allocine.fr"
+    }
+    
+    if (typeof IriSP.__jsonMetadata["medias"][0].meta == "object" && typeof IriSP.__jsonMetadata["medias"][0].meta.subtitles == "string") {
+        _flashVars.subTitlePath = IriSP.__jsonMetadata["medias"][0].meta.subtitles;
+    }
+    
+
+    var params = {
+        "allowScriptAccess" : "always",
+        "wmode": "opaque",
+        "flashvars" : IriSP.jQuery.param(_flashVars),
+        "allowfullscreen" : true
+    };
+    var atts = {
+        id : this.container
+    };
+    swfobject.embedSWF(options.acPlayerUrl, this.container, options.width, options.height, "10", null, null, params, atts);
+
+};
+
+IriSP.PopcornReplacement.allocine.prototype = new IriSP.PopcornReplacement.player("", {});
+
+IriSP.PopcornReplacement.allocine.prototype.ready = function() {
+    this.player = document.getElementById(this.container);
+    this.player.addEventListener("onStateChange", "onAllocineStateChange");
+    this.player.cueVideoByUrl(this._options.video);
+    this.callbacks.onReady();
+};
+
+IriSP.PopcornReplacement.allocine.prototype.progressHandler = function(progressInfo) {
+    this.callbacks.onTime({
+        position: progressInfo.mediaTime
+    });
+}
+
+
+IriSP.PopcornReplacement.allocine.prototype.apiCall = function(_method, _arg) {
+    if (this.player) {
+        try {
+            if (typeof _arg == "undefined") {
+                return this.player.sendToActionScript(_method);
+            } else {
+                return this.player.sendToActionScript(_method, _arg);
+            }
+        } catch(e) {
+            console.error('Exception while requesting AcPlayer for "' + _method + (typeof _arg == "undefined" ? '' : '" with argument "' + _arg ) + '"\n', e);
+            return false;
+        }
+    } else {
+        return false;
+    }
+}
+
+IriSP.PopcornReplacement.allocine.prototype.stateHandler = function(state) {
+    console.log("stateHandler");
+    switch(state) {
+        case 1:
+            this.callbacks.onPlay();
+            break;
+
+        case 2:
+            this.callbacks.onPause();
+            break;
+
+        case 3:
+            this.callbacks.onSeek({
+                position: this.player.getCurrentTime()
+            });
+            break;
+
+        /*
+        case 5:
+            this.callbacks.onReady();
+            break;
+        */
+    }
+    
+};/* To wrap a player the develop should create a new class derived from
+the IriSP.PopcornReplacement.player and defining the correct functions */
+
+/** jwplayer player wrapper */
+IriSP.PopcornReplacement.dailymotion = function(container, options) {
+    console.log("Calling");
+    /* appel du parent pour initialiser les structures communes à tous les players */
+    IriSP.PopcornReplacement.player.call(this, container, options);   
+    
+    var _this = this;
+
+    /* Définition des fonctions de l'API -  */
+
+    this.playerFns = {
+        play : function() {
+            if (_this.player) {
+                return _this.player.playVideo();
+            } else {
+                return false;
+            }
+        },
+        pause : function() {
+            if (_this.player) {
+                return _this.player.pauseVideo();
+            } else {
+                return false;
+            }
+        },
+        getPosition : function() {
+            if (_this.player) {
+                return _this.player.getCurrentTime();
+            } else {
+                return 0;
+            }
+        },
+        seek : function(pos) {
+            if (_this.player) {
+                return _this.player.seekTo(pos);
+            } else {
+                return false;
+            }
+        },
+        getMute : function() {
+            if (_this.player) {
+                return _this.player.isMuted();
+            } else {
+                return false;
+            }
+        },
+        setMute : function(p) {
+            if (_this.player) {
+                if (p) {
+                    _this.player.mute();
+                }
+                else {
+                    _this.player.unMute();
+                }
+            }
+        },
+        getVolume : function() {
+            if (_this.player) {
+                return _this.player.getVolume() / 100;
+            } else {
+                return false;
+            }
+        },
+        setVolume : function(p) {
+            if (_this.player) {
+                _this.player.setVolume(Math.floor(100 * p));
+            }
+        },
+    }
+
+    window.onDailymotionPlayerReady = IriSP.wrap(this, this.ready);
+    window.onDailymotionStateChange = IriSP.wrap(this, this.stateHandler);
+    window.onDailymotionVideoProgress = IriSP.wrap(this, this.progressHandler);
+
+    var params = {
+        "allowScriptAccess" : "always",
+        "wmode": "opaque"
+    };
+    var atts = {
+        id : this.container
+    };
+    swfobject.embedSWF("http://www.dailymotion.com/swf?chromeless=1&enableApi=1", this.container, options.width, options.height, "8", null, null, params, atts);
+
+};
+
+IriSP.PopcornReplacement.dailymotion.prototype = new IriSP.PopcornReplacement.player("", {});
+
+IriSP.PopcornReplacement.dailymotion.prototype.ready = function() {
+    
+    this.player = document.getElementById(this.container);
+    
+    this.player.addEventListener("onStateChange", "onDailymotionStateChange");
+    this.player.addEventListener("onVideoProgress", "onDailymotionVideoProgress");
+    this.player.cueVideoByUrl(this._options.video);
+    
+    this.callbacks.onReady();
+};
+
+IriSP.PopcornReplacement.dailymotion.prototype.progressHandler = function(progressInfo) {
+    
+    this.callbacks.onTime({
+        position: progressInfo.mediaTime
+    });
+}
+
+IriSP.PopcornReplacement.dailymotion.prototype.stateHandler = function(state) {
+    
+    switch(state) {
+        case 1:
+            this.callbacks.onPlay();
+            break;
+
+        case 2:
+            this.callbacks.onPause();
+            break;
+
+        case 3:
+            this.callbacks.onSeek({
+                position: this.player.getCurrentTime()
+            });
+            break;
+
+        /*
+        case 5:
+            this.callbacks.onReady();
+            break;
+        */
+    }
+    
+};/* To wrap a player the develop should create a new class derived from 
+   the IriSP.PopcornReplacement.player and defining the correct functions */
+
+/** jwplayer player wrapper */
+IriSP.PopcornReplacement.jwplayer = function(container, options) {
+  /* appel du parent pour initialiser les structures communes à tous les players */
+  IriSP.PopcornReplacement.player.call(this, container, options);
+  
+  this.media.duration = options.duration; /* optional */
+  
+  /* Définition des fonctions de l'API -  */
+  this.playerFns = {
+    play: function() { return jwplayer(this.container).play(); },
+    pause: function() { return jwplayer(this.container).pause(); },
+    getPosition: function() { return jwplayer(this.container).getPosition(); },
+    seek: function(pos) { return jwplayer(this.container).seek(pos); },
+    getMute: function() { return jwplayer(this.container).getMute() },
+    setMute: function(p) { return jwplayer(this.container).setMute(p); },
+    getVolume: function() { return jwplayer(this.container).getVolume() / 100; },
+    setVolume: function(p) { return jwplayer(this.container).setVolume(Math.floor(100*p)); }
+  }
+
+  options.events = this.callbacks;
+
+  jwplayer(this.container).setup(options);
+};
+
+IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
+/* Cinecast Cinelab Serializer */
+
+if (typeof IriSP.serializers === "undefined") {
+    IriSP.serializers = {}
+}
+
+IriSP.serializers.cinecast = {
+    types :  {
+        media : {
+            serialized_name : "medias",
+            model_name : "media",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Media(_data.id, _source);
+                _res.video = _data.url;
+                _res.title = _data.meta.title;
+                _res.description = _data.meta.synopsis;
+                _res.setDuration(_data.meta.duration);
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    url : _data.video,
+                    meta : {
+                        title : _data.title,
+                        synopsis : _data.description,
+                        duration : _data.duration.milliseconds
+                    }
+                }
+            }
+        },
+        tag : {
+            serialized_name : "tags",
+            model_name : "tag",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Tag(_data.id, _source);
+                _res.title = _data.meta.description;
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    meta : {
+                        description : _data.title
+                    }
+                }
+            }
+        },
+        annotationType : {
+            serialized_name : "annotation_types",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
+                _res.title = _source.getNamespaced(_data.id).name;
+                _res.description = _data.meta.description;
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    meta : {
+                        description : _data.description
+                    }
+                }
+            }
+        },
+        annotation : {
+            serialized_name : "annotations",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Annotation(_data.id, _source);
+                _res.title = _data.meta.creator_name;
+                _res.description = _data.content.data;
+                _res.created = IriSP.Model.isoToDate(_data.meta.created);
+                _res.setMedia(_data.media, _source);
+                _res.setAnnotationType(_data.type);
+                _res.setTags(IriSP._(_data.tags).map(function(_t) {
+                    if (typeof _source.contents.tag === "undefined") {
+                        _source.contents.tag = new IriSP.Model.List(_source.directory);
+                    }
+                    if (_source.contents.tag.hasId(_t)) {
+                        return _t;
+                    } else {
+                        var _id = _t.toLowerCase()
+                            .replace(/#/g,'')
+                            .replace(/^(\d)/,'_$1')
+                            .replace(/[áâäàã]/g,'a')
+                            .replace(/ç/g,'c')
+                            .replace(/[éèêë]/g,'e')
+                            .replace(/[íìîï]/g,'i')
+                            .replace(/ñ/g,'n')
+                            .replace(/[óòôöõ]/g,'o')
+                            .replace(/œ/g,'oe')
+                            .replace(/[úùûü]/g,'u')
+                            .replace(/ÿ/g,'y')
+                            .replace(/[^A-Za-z0-9_]/g,''),
+                            _tag = new IriSP.Model.Tag(_id, _source);
+                        _tag.title = _t;
+                        _source.contents.tag.push(_tag);
+                        return _id;
+                    }
+                }));
+                _res.setBegin(_data.begin);
+                _res.setEnd(_data.end);
+                _res.creator = _data.meta.creator;
+                return _res;
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    content : {
+                        data : _data.description
+                    },
+                    begin : _data.begin.milliseconds,
+                    end : _data.begin.milliseconds,
+                    media : _source.unNamespace(_data.media.id),
+                    type : _source.unNamespace(_data.annotationType.id),
+                    meta : {
+                        created : IriSP.Model.dateToIso(_data.created),
+                        creator : _data.creator,
+                        creator_name : _data.title
+                    },
+                    tags : _data.tag.id.map(function(_id) {
+                        return _source.unNamespace(_id)
+                    })
+                }
+            }
+        }
+    },
+    serialize : function(_source) {
+        var _res = {
+                format : "http://advene.org/ns/cinelab/"
+            },
+            _this = this,
+            _nsls = _source.listNamespaces(true);
+        _res.imports = [];
+        for (var _i = 0; _i < _nsls.length; _i++) {
+           if (typeof _source.directory.namespaces[_nsls[_i]] !== "undefined") {
+               _res.imports.push({
+                   id : _nsls[_i],
+                   url : _source.directory.namespaces[_nsls[_i]]
+               })
+           } 
+        }
+        _source.forEach(function(_list, _typename) {
+            if (typeof _this.types[_typename] !== "undefined") {
+                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
+                    return _this.types[_typename].serializer(_el, _source);
+                });
+            }
+        });
+        return _res;
+    },
+    loadData : function(_url, _callback) {
+        IriSP.jQuery.getJSON(_url, _callback)
+    },
+    deSerialize : function(_data, _source) {
+        if (typeof _data !== "object" || _data === null) {
+            return;
+        }
+        if (typeof _data.imports !== "undefined") {
+            IriSP._(_data.imports).forEach(function(_import) {
+                _source.directory.namespaces[_import.id] = _import.url;
+            })
+        }
+        IriSP._(this.types).forEach(function(_type, _typename) {
+            var _listdata = _data[_type.serialized_name];
+            if (typeof _listdata !== "undefined" && _listdata !== null) {
+                var _list = new IriSP.Model.List(_source.directory);
+                if (_listdata.hasOwnProperty("length")) {
+                    var _l = _listdata.length;
+                    for (var _i = 0; _i < _l; _i++) {
+                        _list.push(_type.deserializer(_listdata[_i], _source));
+                    }
+                } else {
+                    _list.push(_type.deserializer(_listdata, _source));
+                }
+                _source.addList(_typename, _list);
+            }
+        });
+        
+        if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
+            _source.setCurrentMediaId(_data.meta.id);
+        }
+        _source.setDefaultCurrentMedia();
+    }
+}
+
+/* LDT Platform Serializer */
+
+if (typeof IriSP.serializers === "undefined") {
+    IriSP.serializers = {}
+}
+
+IriSP.serializers.ldt = {
+    types :  {
+        media : {
+            serialized_name : "medias",
+            model_name : "media",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Media(_data.id, _source);
+                _res.video = (
+                    typeof _data.url !== "undefined"
+                    ? _data.url
+                    : (
+                        typeof _data.href !== "undefined"
+                        ? _data.href
+                        : null
+                    )
+                );
+                if (typeof _data.meta.item !== "undefined" && _data.meta.item.name === "streamer") {
+                    _res.streamer = _data.meta.item.value;
+                }
+                _res.title = _data.meta["dc:title"];
+                _res.description = _data.meta["dc:description"];
+                _res.setDuration(_data.meta["dc:duration"]);
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    url : _data.video,
+                    meta : {
+                        "dc:title" : _data.title,
+                        "dc:description" : _data.description,
+                        "dc:duration" : _data.duration.milliseconds
+                    }
+                }
+            }
+        },
+        tag : {
+            serialized_name : "tags",
+            model_name : "tag",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Tag(_data.id, _source);
+                _res.title = _data.meta["dc:title"];
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    meta : {
+                        "dc:title" : _data.title
+                    }
+                }
+            }
+        },
+        annotationType : {
+            serialized_name : "annotation-types",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
+                _res.title = _data["dc:title"];
+                _res.description = _data["dc:description"];
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    "dc:title" : _data.title,
+                    "dc:description" : _data.description
+                }
+            }
+        },
+        annotation : {
+            serialized_name : "annotations",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Annotation(_data.id, _source);
+                _res.title = _data.content.title || "";
+                _res.description = _data.content.description || "";
+                if (typeof _data.content.img !== "undefined" && _data.content.img.src !== "undefined") {
+                    _res.thumbnail = _data.content.img.src;
+                }
+                _res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]);
+                if (typeof _data.color !== "undefined") {
+                    var _c = parseInt(_data.color).toString(16);
+                    while (_c.length < 6) {
+                        _c = '0' + _c;
+                    }
+                    _res.color = '#' + _c;
+                }
+                _res.setMedia(_data.media, _source);
+                _res.setAnnotationType(_data.meta["id-ref"]);
+                _res.setTags(IriSP._(_data.tags).pluck("id-ref"));
+                _res.setBegin(_data.begin);
+                _res.setEnd(_data.end);
+                _res.creator = _data.meta["dc:creator"] || "";
+                _res.project = _data.meta.project || "";
+                if (typeof _data.meta["dc:source"] !== "undefined" && typeof _data.meta["dc:source"].content !== "undefined") {
+                    _res.source = JSON.parse(_data.meta["dc:source"].content);
+                }
+                return _res;
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    content : {
+                        title : _data.title,
+                        description : _data.description
+                    },
+                    media : _source.unNamespace(_data.media.id),
+                    meta : {
+                        "id-ref" : _source.unNamespace(_data.annotationType.id),
+                        "dc:created" : IriSP.Model.dateToIso(_data.created),
+                        "dc:creator" : _data.creator,
+                        project : _source.projectId
+                    },
+                    tags : IriSP._(_data.tag.id).map(function(_d) {
+                       return {
+                           "id-ref" : _source.unNamespace(_id)
+                       } 
+                    })
+                }
+            }
+        }
+    },
+    serialize : function(_source) {
+        var _res = {},
+            _this = this;
+        _source.forEach(function(_list, _typename) {
+            if (typeof _this.types[_typename] !== "undefined") {
+                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
+                    return _this.types[_typename].serializer(_el, _source);
+                });
+            }
+        });
+        return _res;
+    },
+    loadData : function(_url, _callback) {
+        IriSP.jQuery.getJSON(_url, _callback)
+    },
+    deSerialize : function(_data, _source) {
+        if (typeof _data !== "object" || _data === null) {
+            return;
+        }
+        IriSP._(this.types).forEach(function(_type, _typename) {
+            var _listdata = _data[_type.serialized_name];
+            if (typeof _listdata !== "undefined" && _listdata !== null) {
+                var _list = new IriSP.Model.List(_source.directory);
+                if (_listdata.hasOwnProperty("length")) {
+                    var _l = _listdata.length;
+                    for (var _i = 0; _i < _l; _i++) {
+                        _list.push(_type.deserializer(_listdata[_i], _source));
+                    }
+                } else {
+                    _list.push(_type.deserializer(_listdata, _source));
+                }
+                _source.addList(_typename, _list);
+            }
+        });
+        
+        if (typeof _data.meta !== "undefined") {
+            _source.projectId = _data.meta.id;
+        }
+        
+        if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
+            _source.setCurrentMediaId(_data.meta.main_media["id-ref"]);
+        }
+        _source.setDefaultCurrentMedia();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Mediafragment.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,77 @@
+IriSP.Widgets.Mediafragment = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.last_hash = "";
+    window.onhashchange = this.functionWrapper("goToHash");
+    if (typeof window.addEventListener !== "undefined") {
+        window.addEventListener('message', function(_msg) {
+            if (_msg.data.type === "hashchange") {
+                document.location.hash = _msg.data.hash;
+            }
+        })
+    };
+    this.bindPopcorn("pause","setHashToTime");
+    this.bindPopcorn("seeked","setHashToTime");
+    this.bindPopcorn("IriSP.Mediafragment.setHashToAnnotation","setHashToAnnotation");
+    this.blocked = false;
+}
+
+IriSP.Widgets.Mediafragment.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Mediafragment.prototype.draw = function() {
+    this.goToHash();
+}
+
+IriSP.Widgets.Mediafragment.prototype.goToHash = function() {
+    if (document.location.hash !== this.last_hash) {
+        this.last_hash = document.location.hash;
+        var _tab = this.last_hash.split("=");
+        if (_tab[0] === '#id') {
+            var _annotation = this.source.getElement(_tab[1]);
+            if (typeof _annotation !== "undefined") {
+                this.player.popcorn.currentTime(_annotation.begin.getSeconds());
+            }
+        }
+        if (_tab[0] === '#t') {
+            this.player.popcorn.currentTime(_tab[1]);
+        }
+    }
+}
+
+IriSP.Widgets.Mediafragment.prototype.setHashToAnnotation = function(_annotationId) {
+    this.setHash( '#id=' + this.source.unNamespace(_annotationId) );
+}
+
+IriSP.Widgets.Mediafragment.prototype.setHashToTime = function(_time) {
+    _time = (typeof _time !== "undefined" ? _time : this.player.popcorn.currentTime() );
+    this.setHash( '#t=' + _time );
+}
+
+IriSP.Widgets.Mediafragment.prototype.setHash = function(_hash) {
+    if (!this.blocked && this.last_hash !== _hash) {
+        this.last_hash = _hash;
+        document.location.hash = _hash;
+        if (window.parent !== window) {
+            window.parent.postMessage({
+                type: "hashchange",
+                hash: _hash
+            })
+        }
+        this.block();
+    }
+}
+
+IriSP.Widgets.Mediafragment.prototype.unblock = function() {
+    if (typeof this.blockTimeout !== "undefined") {
+        window.clearTimeout(this.blockTimeout);
+    }
+    this.blockTimeout = undefined;
+    this.blocked = false;
+}
+
+IriSP.Widgets.Mediafragment.prototype.block = function() {
+    if (typeof this.blockTimeout !== "undefined") {
+        window.clearTimeout(this.blockTimeout);
+    }
+    this.blocked = true;
+    this.blockTimeout = window.setTimeout(this.functionWrapper("unblock"), 1000);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Polemic.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,22 @@
+/*
+ * Polemic Widget CSS
+ */
+
+.Ldt-Polemic {
+    border-style: solid none; border-color: #cccccc; border-width: 1px;
+}
+
+.Ldt-Polemic-Position {
+    background: #fc00ff;
+    position: absolute;
+    top: 0;
+    left: 0;
+    margin-left: -1px;
+    width: 2px;
+    height: 100%;
+}
+
+.Ldt-Polemic-TweetDiv {
+    position: absolute;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Polemic.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,304 @@
+IriSP.Widgets.Polemic = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+};
+
+IriSP.Widgets.Polemic.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Polemic.prototype.messages = {
+    fr: {
+        from_: "de ",
+        _to_: " à ",
+        _annotations: " annotation(s)"
+    },
+    en: {
+        from_: "from ",
+        _to_: " to ",
+        _annotations: " annotation(s)"
+    }
+}
+IriSP.Widgets.Polemic.prototype.defaults = {
+    element_width : 5,
+    element_height : 5,
+    max_elements : 15,
+    annotation_type : "tweet",
+    defaultcolor : "#585858",
+    foundcolor : "#fc00ff",
+    polemics : [
+        {
+            "keywords" : [ "++" ],
+            "description" : "positif",
+            "color" : "#1D973D"
+        },
+        {
+            "keywords" : [ "--" ],
+            "description" : "negatif",
+            "color" : "#CE0A15"
+        },
+        {
+            "keywords" : [ "==" ],
+            "description" : "reference",
+            "color" : "#C5A62D"  
+        },
+        {
+            "keywords" : [ "??" ],
+            "description" : "question",
+            "color" : "#036AAE"
+        }
+    ],
+    requires : [
+        {
+            type: "Tooltip"
+        }
+    ]
+};
+
+IriSP.Widgets.Polemic.prototype.onSearch = function(searchString) {
+    this.searchString = typeof searchString !== "undefined" ? searchString : '';
+    var _found = 0,
+        _re = IriSP.Model.regexpFromTextOrArray(searchString),
+        _this = this;
+    this.$tweets.each(function() {
+        var _el = IriSP.jQuery(this);
+        if (_this.searchString) {
+            if (_re.test(_el.attr("tweet-title"))) {
+                _el.css({
+                    "background" : _this.foundcolor,
+                    "opacity" : 1
+                });
+                _found++;
+            } else {
+                _el.css({
+                    "background" : _el.attr("polemic-color"),
+                    "opacity" : .5
+                });
+            }
+        } else {
+            _el.css({
+                "background" : _el.attr("polemic-color"),
+                "opacity" : 1
+            });
+        }
+    });
+    if (this.searchString) {
+        if (_found) {
+            this.player.popcorn.trigger("IriSP.search.matchFound");
+        } else {
+            this.player.popcorn.trigger("IriSP.search.noMatchFound");
+        }
+    }
+}
+
+IriSP.Widgets.Polemic.prototype.draw = function() {
+    
+    this.bindPopcorn("timeupdate", "onTimeupdate");
+    this.$zone = IriSP.jQuery('<div>');
+    this.$zone.addClass("Ldt-Polemic");
+    this.$.append(this.$zone);
+    
+    this.$elapsed = IriSP.jQuery('<div>')
+        .css({
+            background: '#cccccc',
+            position: "absolute",
+            top: 0,
+            left: 0,
+            width: 0,
+            height: "100%"
+        });
+        
+    this.$zone.append(this.$elapsed);
+    
+    var _slices = [],
+        _slice_count = Math.floor( this.width / this.element_width ),
+        _duration = this.source.getDuration(),
+        _max = 0,
+        _list = this.getWidgetAnnotations(),
+        _this = this;
+    
+    for (var _i = 0; _i < _slice_count; _i++) {
+        var _begin = new IriSP.Model.Time( _i * _duration / _slice_count ),
+            _end = new IriSP.Model.Time( ( _i + 1 ) * _duration / _slice_count ),
+            _count = 0,
+            _res = {
+                begin : _begin.toString(),
+                end : _end.toString(),
+                annotations : _list.filter(function(_annotation) {
+                    return _annotation.begin >= _begin && _annotation.end < _end;
+                }),
+                polemicStacks : []
+            }
+            
+        for (var _j = 0; _j < this.polemics.length; _j++) {
+            var _polemic = _res.annotations.searchByDescription(this.polemics[_j].keywords);
+            _count += _polemic.length;
+            _res.polemicStacks.push(_polemic);
+        }
+        for (var _j = 0; _j < this.polemics.length; _j++) {
+            _res.annotations.removeElements(_res.polemicStacks[_j]);
+        }
+        _count += _res.annotations.length;
+        _max = Math.max(_max, _count);
+        _slices.push(_res);
+    }
+    if (_max < this.max_elements) {
+        this.is_stackgraph = false;
+        if (_max) {
+                    
+            this.height = (2 + _max) * this.element_height;
+            this.$zone.css({
+                width: this.width + "px",
+                height: this.height + "px",
+                position: "relative"
+            });
+            
+            var _x = 0,
+                _html = '';
+            
+            function displayElement(_x, _y, _color, _id, _title) {
+                _html += Mustache.to_html(
+                    '<div class="Ldt-Polemic-TweetDiv" annotation-id="{{id}}" tweet-title="{{title}}" pos-x="{{posx}}" pos-y="{{top}}" polemic-color="{{color}}"'
+                    + ' style="width: {{width}}px; height: {{height}}px; top: {{top}}px; left: {{left}}px; background: {{color}}"></div>',
+                {
+                    id: _id,
+                    title: _title,
+                    posx: Math.floor(_x + (_this.element_width - 1) / 2),
+                    left: _x,
+                    top: _y,
+                    color: _color,
+                    width: (_this.element_width-1),
+                    height: _this.element_height
+                });
+            }
+            
+            IriSP._(_slices).forEach(function(_slice) {
+                var _y = _this.height;
+                _slice.annotations.forEach(function(_annotation) {
+                    _y -= _this.element_height;
+                    displayElement(_x, _y, _this.defaultcolor, _annotation.id, _annotation.title);
+                });
+                IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) {
+                    var _color = _this.polemics[_j].color;
+                    _annotations.forEach(function(_annotation) {
+                        _y -= _this.element_height;
+                        displayElement(_x, _y, _color, _annotation.id, _annotation.title);
+                    });
+                });
+                _x += _this.element_width;
+            });
+            
+            this.$zone.append(_html);
+            
+            this.$tweets = this.$.find(".Ldt-Polemic-TweetDiv");
+            
+            this.$tweets
+                .mouseover(function() {
+                    var _el = IriSP.jQuery(this);
+                    _this.tooltip.show(_el.attr("pos-x"), _el.attr("pos-y"), _el.attr("tweet-title"), _el.attr("polemic-color"));
+                })
+                .mouseout(function() {
+                    _this.tooltip.hide();
+                })
+                .click(function() {
+                    var _id = IriSP.jQuery(this).attr("annotation-id");
+                    _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToAnnotation", _id);
+                    _this.player.popcorn.trigger("IriSP.Tweet.show", _id);
+                });
+            
+            this.bindPopcorn("IriSP.search", "onSearch");
+            this.bindPopcorn("IriSP.search.closed", "onSearch");
+            this.bindPopcorn("IriSP.search.cleared", "onSearch");
+            
+        } else {
+            this.$zone.hide();
+        }
+    } else {
+        this.is_stackgraph = true;
+        
+        this.height = (2 + this.max_elements) * this.element_height;
+        this.$zone.css({
+            width: this.width + "px",
+            height: this.height + "px",
+            position: "relative"
+        });
+        
+        var _x = 0,
+            _html = '',
+            _scale = this.max_elements * this.element_height / _max;
+            
+        function displayElement(_x, _y, _h, _color, _nums, _begin, _end) {
+            _html += Mustache.to_html(
+                '<div class="Ldt-Polemic-TweetDiv" pos-x="{{posx}}" pos-y="{{top}}" annotation-counts="{{nums}}" begin-time="{{begin}}" end-time="{{end}}"'
+                + ' style="width: {{width}}px; height: {{height}}px; top: {{top}}px; left: {{left}}px; background: {{color}}"></div>',
+            {
+                nums: _nums,
+                posx: Math.floor(_x + (_this.element_width - 1) / 2),
+                left: _x,
+                top: _y,
+                color: _color,
+                width: (_this.element_width-1),
+                height: _h,
+                begin: _begin,
+                end: _end
+            });
+        }
+        
+        IriSP._(_slices).forEach(function(_slice) {
+            var _y = _this.height,
+                _nums = _slice.annotations.length + "," + IriSP._(_slice.polemicStacks).map(function(_annotations) {
+                    return _annotations.length
+                }).join(",");
+            if (_slice.annotations.length) {
+                var _h = Math.ceil(_scale * _slice.annotations.length);
+                _y -= _h;
+                displayElement(_x, _y, _h, _this.defaultcolor, _nums, _slice.begin, _slice.end);
+            }
+            IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) {
+                if (_annotations.length) {
+                    var _color = _this.polemics[_j].color,
+                        _h = Math.ceil(_scale * _annotations.length);
+                    _y -= _h;
+                    displayElement(_x, _y, _h, _color, _nums, _slice.begin, _slice.end);
+                }
+            });
+            _x += _this.element_width;
+        });
+        
+        this.$zone.append(_html);
+        
+        this.$tweets = this.$.find(".Ldt-Polemic-TweetDiv");
+        
+        this.$tweets
+            .mouseover(function() {
+                var _el = IriSP.jQuery(this),
+                    _nums = _el.attr("annotation-counts").split(","),
+                    _html = '<p>' + _this.l10n.from_ + _el.attr("begin-time") + _this.l10n._to_ + _el.attr("end-time") + '</p>';
+                for (var _i = 0; _i <= _this.polemics.length; _i++) {
+                    var _color = _i ? _this.polemics[_i - 1].color : _this.defaultcolor;
+                    _html += '<div class="Ldt-Tooltip-Color" style="background: ' + _color + '"></div><p>' + _nums[_i] + _this.l10n._annotations + '</p>'
+                }
+                _this.tooltip.show(_el.attr("pos-x"), _el.attr("pos-y"), _html);
+            })
+            .mouseout(function() {
+                _this.tooltip.hide();
+            })
+            
+    }
+    
+    this.$position = IriSP.jQuery('<div>').addClass("Ldt-Polemic-Position");
+        
+    this.$zone.append(this.$position);
+    
+    this.$zone.click(function(_e) {
+        var _x = _e.pageX - _this.$zone.offset().left;
+        _this.player.popcorn.currentTime(_this.source.getDuration().getSeconds() * _x / _this.width);
+    });
+}
+
+IriSP.Widgets.Polemic.prototype.onTimeupdate = function() {
+    var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds());
+    this.$elapsed.css({
+        width:  _x + "px"
+    });
+    this.$position.css({
+        left: _x + "px"
+    })
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Segments.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,29 @@
+/*
+ * Segments Widget
+ */
+
+.Ldt-Segments-List {
+    width: 100%; height: 100%;
+}
+
+.Ldt-Segments-Segment {
+    position: absolute; height: 100%; opacity: .5; filter:alpha(opacity=50); margin-left: -1px; border-left: 1px solid #ffffff;
+}
+
+.Ldt-Segments-Segment.inactive, .Ldt-Segments-Segment.unfound {
+    opacity: .2; filter:alpha(opacity=20);
+}
+
+.Ldt-Segments-Segment.active, .Ldt-Segments-Segment.found {
+    opacity: 1; filter:alpha(opacity=100);
+}
+
+.Ldt-Segments-Position {
+    background: #fc00ff;
+    position: absolute;
+    top: 0;
+    left: 0;
+    margin-left: -1px;
+    width: 2px;
+    height: 100%;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Segments.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,105 @@
+// TODO: Trigger IriSP.SegmentsWidget.click and IriSP.Mediafragment.showAnnotation
+
+IriSP.Widgets.Segments = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+};
+
+IriSP.Widgets.Segments.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Segments.prototype.defaults = {
+    annotation_type : "chap",
+    colors: ["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],
+    requires : [
+        {
+            type: "Tooltip"
+        }
+    ],
+    height: 10
+};
+
+IriSP.Widgets.Segments.prototype.template =
+    '<div class="Ldt-Segments-List">{{#segments}}'
+    + '<div class="Ldt-Segments-Segment" segment-id="{{id}}" segment-text="{{text}}" segment-color="{{color}}" center-pos="{{center}}" begin-seconds="{{beginseconds}}"'
+    + 'style="left:{{left}}px; width:{{width}}px; background:{{color}}"></div>'
+    + '{{/segments}}</div>'
+    + '<div class="Ldt-Segments-Position"></div>';
+
+IriSP.Widgets.Segments.prototype.draw = function() {
+    this.bindPopcorn("IriSP.search", "onSearch");
+    this.bindPopcorn("IriSP.search.closed", "onSearch");
+    this.bindPopcorn("IriSP.search.cleared", "onSearch");
+    this.bindPopcorn("timeupdate", "onTimeupdate");
+    
+    var _list = this.getWidgetAnnotations(),
+        _this = this,
+        _scale = this.width / this.source.getDuration();
+    this.$.css({
+        width : this.width + "px",
+        height : (this.height - 2) + "px",
+        margin : "1px 0"
+    });
+    this.$.append(Mustache.to_html(this.template, {
+        segments : _list.map(function(_annotation, _k) {
+            var _left = _annotation.begin * _scale,
+                _width = ( _annotation.end - _annotation.begin ) * _scale,
+                _center = _left + _width / 2;
+            return {
+                text : _annotation.title + ( _annotation.description ? '<br />' + _annotation.description.replace(/(^.{120,140})[\s].+$/,'$1&hellip;') : ''),
+                color : ( typeof _annotation.color !== "undefined" && _annotation.color ? _annotation.color : _this.colors[_k % _this.colors.length] ),
+                beginseconds : _annotation.begin.getSeconds() ,
+                left : Math.floor( _left ),
+                width : Math.floor( _width ),
+                center : Math.floor( _center ),
+                id : _annotation.namespacedId.name
+            }
+        })
+    }));
+    this.$segments = this.$.find('.Ldt-Segments-Segment');
+    
+    this.$segments.mouseover(function() {
+        var _el = IriSP.jQuery(this);
+        _this.$segments.removeClass("active").addClass("inactive");
+        _this.tooltip.show( _el.attr("center-pos"), 0, _el.attr("segment-text"), _el.attr("segment-color"));
+        _el.removeClass("inactive").addClass("active");
+    })
+    .mouseout(function() {
+        _this.tooltip.hide();
+        _this.$segments.removeClass("inactive active");
+    })
+    .click(function() {
+        var _el = IriSP.jQuery(this);
+        _this.player.popcorn.currentTime(_el.attr("begin-seconds"));
+        _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToAnnotation", _el.attr("segment-id"));
+    });
+}
+
+IriSP.Widgets.Segments.prototype.onSearch = function(searchString) {
+    this.searchString = typeof searchString !== "undefined" ? searchString : '';
+    var _found = 0,
+        _re = IriSP.Model.regexpFromTextOrArray(searchString);
+    if (this.searchString) {
+        this.$segments.each(function() {
+            var _el = IriSP.jQuery(this);
+            if (_re.test(_el.attr("segment-text"))) {
+                _el.removeClass("unfound").addClass("found");
+                _found++;
+            } else {
+                _el.removeClass("found").addClass("unfound");
+            }
+        });
+        if (_found) {
+            this.player.popcorn.trigger("IriSP.search.matchFound");
+        } else {
+            this.player.popcorn.trigger("IriSP.search.noMatchFound");
+        }
+    } else {
+        this.$segments.removeClass("found unfound");
+    }
+}
+
+IriSP.Widgets.Segments.prototype.onTimeupdate = function() {
+    var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds());
+    this.$.find('.Ldt-Segments-Position').css({
+        left: _x + "px"
+    })
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Slider.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,14 @@
+/* Slider Widget */
+
+.Ldt-Slider {
+    border: none; border-radius: 0; padding: 0; margin: 0; background: #B6B8B8;
+}
+
+.Ldt-Slider .ui-slider-handle {
+    border-radius: 8px; top: -2px; background: #fc00ff; border: 1px solid #ffffff;
+}
+
+.Ldt-Slider .ui-slider-range {
+    background: #747474;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Slider.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,114 @@
+/*
+ The Slider Widget fits right under the video
+ */
+
+IriSP.Widgets.Slider = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.bindPopcorn("timeupdate","onTimeupdate");
+    this.bindPopcorn("IriSP.PlayerWidget.MouseOver","onMouseover");
+    this.bindPopcorn("IriSP.PlayerWidget.MouseOut","onMouseout");
+};
+
+IriSP.Widgets.Slider.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Slider.prototype.defaults = {
+    minimized_height : 4,
+    maximized_height : 10,
+    minimize_timeout : 1500 // time before minimizing slider after mouseout
+};
+
+IriSP.Widgets.Slider.prototype.draw = function() {
+    
+    this.$slider = IriSP.jQuery('<div>')
+        .addClass("Ldt-Slider")
+        .css(this.calculateSliderCss(this.minimized_height));
+    
+    this.$.append(this.$slider);
+    
+    var _this = this;
+    
+    this.$slider.slider({
+        range: "min",
+        value: 0,
+        min: 0,
+        max: this.source.getDuration().getSeconds(),
+        slide: function(event, ui) {
+            _this.player.popcorn.currentTime(ui.value);
+            _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
+        }
+    });
+    
+    this.$handle = this.$slider.find('.ui-slider-handle');
+    
+    this.$handle.css(this.calculateHandleCss(this.minimized_height));
+    
+    this.$
+        .mouseover(this.functionWrapper("onMouseover"))
+        .mouseout(this.functionWrapper("onMouseout"));
+    
+    this.maximized = false;
+    this.timeoutId = false;
+};
+
+IriSP.Widgets.Slider.prototype.onTimeupdate = function() {
+    var _time = this.player.popcorn.currentTime();
+    this.$slider.slider("value",_time);
+    this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
+}
+
+IriSP.Widgets.Slider.prototype.onMouseover = function() {
+    if (this.timeoutId) {
+        window.clearTimeout(this.timeoutId);
+        this.timeoutId = false;
+    }
+    if (!this.maximized) {
+       this.animateToHeight(this.maximized_height);
+       this.maximized = true;
+    }
+}
+
+IriSP.Widgets.Slider.prototype.onMouseout = function() {
+    if (this.timeoutId) {
+        window.clearTimeout(this.timeoutId);
+        this.timeoutId = false;
+    }
+    var _this = this;
+    this.timeoutId = window.setTimeout(function() {
+        if (_this.maximized) {
+            _this.animateToHeight(_this.minimized_height);
+            _this.maximized = false;
+        }
+        _this.timeoutId = false;
+    }, this.minimize_timeout);
+    
+}
+
+IriSP.Widgets.Slider.prototype.animateToHeight = function(_height) {
+    this.$slider.stop().animate(
+        this.calculateSliderCss(_height),
+        500,
+        function() {
+            IriSP.jQuery(this).css("overflow","visible");
+        });
+    this.$handle.stop().animate(
+        this.calculateHandleCss(_height),
+        500,
+        function() {
+            IriSP.jQuery(this).css("overflow","visible");
+        });
+}
+
+IriSP.Widgets.Slider.prototype.calculateSliderCss = function(_size) {
+    return {
+        height: _size + "px",
+        "margin-top": (this.minimized_height - _size) + "px"
+    };
+}
+
+IriSP.Widgets.Slider.prototype.calculateHandleCss = function(_size) {
+    return {
+        height: (2 + _size) + "px",
+        width: (2 + _size) + "px",
+        "margin-left": -Math.ceil(2 + _size / 2) + "px" 
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tagcloud.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,28 @@
+/*
+ * 
+ */
+.Ldt-Tagcloud-Container {
+    font-family: "Open Sans", Arial, Helvetica, sans-serif;
+}
+
+ul.Ldt-Tagcloud-List {
+    padding: 5px;
+    margin: 0;
+    list-style: none;
+    text-align: center;
+}
+
+li.Ldt-Tagcloud-item {
+    display: inline-block;
+    margin: 2px;
+    cursor: pointer;
+}
+
+li.Ldt-Tagcloud-item:hover {
+    color: #0099ff;
+}
+
+.Ldt-Tagcloud-active {
+    color: #c000c0;
+    padding: 0; margin: 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tagcloud.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,101 @@
+IriSP.Widgets.Tagcloud = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.stopwords = IriSP._.uniq([].concat(this.custom_stopwords).concat(this.stopword_lists[this.stopword_language]));
+}
+
+IriSP.Widgets.Tagcloud.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Tagcloud.prototype.template =
+    '<div class="Ldt-Tagcloud-Container"><ul class="Ldt-Tagcloud-List">'
+    + '{{#words}}<li class="Ldt-Tagcloud-item" content="{{word}}" style="font-size: {{size}}px">{{word}}</li>{{/words}}'
+    + '</ul></div>';
+
+IriSP.Widgets.Tagcloud.prototype.defaults = {
+    include_titles: true,
+    include_descriptions: true,
+    tag_count: 30,
+    stopword_language: "fr",
+    custom_stopwords: [],
+    exclude_pattern: false,
+    annotation_type: false,
+    min_font_size: 10,
+    max_font_size: 26
+}
+
+IriSP.Widgets.Tagcloud.prototype.stopword_lists = {
+    "fr" : [
+        'aussi', 'avec', 'aux', 'bien', 'car', 'cette', 'comme', 'dans', 'des', 'donc', 'dont', 'elle', 'encore', 'entre', 'est',
+        'être', 'eux', 'faire', 'fait', 'http', 'ici', 'ils', 'les', 'leur', 'leurs', 'mais', 'mes', 'même', 'mon', 'notre',
+        'non', 'nos', 'nous', 'ont', 'par', 'pas', 'peu', 'peut', 'plus', 'pour', 'quand', 'que', 'qui', 'quoi', 'sans',
+        'ses' ,'son', 'sont', 'sur', 'tes', 'très', 'the', 'ton', 'tous', 'tout', 'une', 'votre', 'vos', 'vous'
+    ],
+    "en" : [
+        'about', 'again', 'are', 'and', 'because', 'being', 'but', 'can', 'done', 'have', 'for', 'from',
+        'get', 'here', 'http', 'like', 'more', 'one', 'our', 'she', 'that', 'the', 'their', 'then', 'there',
+        'they', 'this', 'very', 'what', 'when', 'where', 'who', 'why', 'will', 'with', 'www', 'you', 'your'
+    ]
+}
+
+IriSP.Widgets.Tagcloud.prototype.draw = function() {
+    
+    var _urlRegExp = /https?:\/\/[0-9a-zA-Z\.%\/-_]+/g,
+        _regexpword = /[^\s\.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g,
+        _words = {},
+        _this = this;
+    this.getWidgetAnnotations().forEach(function(_annotation) {
+       var _txt = (_this.include_titles ? _annotation.title : '') + ' ' + (_this.include_descriptions ? _annotation.description : '');
+       IriSP._(_txt.toLowerCase().replace(_urlRegExp, '').match(_regexpword)).each(function(_word) {
+           if (IriSP._(_this.stopwords).indexOf(_word) == -1 && (!_this.exclude_pattern || !_this.exclude_pattern.test(_word))) {
+               _words[_word] = 1 + (_words[_word] || 0);
+           }
+       })
+    });
+    _words = IriSP._(_words)
+        .chain()
+        .map(function(_v, _k) {
+            return {
+                "word" : _k,
+                "count" : _v
+            }
+        })
+        .filter(function(_v) {
+            return _v.count > 2;
+        })
+        .sortBy(function(_v) {
+            return - _v.count;
+        })
+        .first(this.tag_count)
+        .value();
+    var _max = _words[0].count,
+        _min = Math.min(_words[_words.length - 1].count, _max - 1),
+        _scale = (this.max_font_size - this.min_font_size) / Math.sqrt(_max - _min);
+    IriSP._(_words).each(function(_word) {
+            _word.size = Math.floor( _this.min_font_size + _scale * Math.sqrt(_word.count - _min) );
+        });
+    this.words = _words;
+    this.renderTemplate();
+    this.$words = this.$.find(".Ldt-Tagcloud-item");
+    this.$words.click(function() {
+        var _txt = IriSP.jQuery(this).attr("content");
+        _this.player.popcorn.trigger("IriSP.search.triggeredSearch", _txt);
+    });
+    this.bindPopcorn("IriSP.search", "onSearch");
+    this.bindPopcorn("IriSP.search.closed", "onSearch");
+    this.bindPopcorn("IriSP.search.cleared", "onSearch");
+}
+
+IriSP.Widgets.Tagcloud.prototype.onSearch = function(searchString) {
+    searchString = typeof searchString !== "undefined" ? searchString : '';
+    if (searchString) {
+        var _rgxp = IriSP.Model.regexpFromTextOrArray(searchString);
+    }
+    this.$words.each(function() {
+        var _el = IriSP.jQuery(this),
+            _txt = _el.attr("content");
+        if (searchString) {
+            _el.html(_txt.replace(_rgxp, '<span class="Ldt-Tagcloud-active">$1</span>'));
+        } else {
+            _el.html(_txt);
+        }
+    });
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tooltip.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,29 @@
+/* ToolTip Widget */
+
+.Ldt-Tooltip {
+  position: absolute;
+  padding : 3px;
+  z-index: 10000000000;
+  max-width: 200px;
+  background: transparent url("img/white_arrow_long.png");
+  font-size: 12px;
+  height: 115px;
+  width: 180px;
+  padding: 15px 15px 20px;
+  color: black;
+  font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
+  overflow:hidden;
+}
+
+.Ldt-Tooltip-Color {
+    float: left; margin: 2px 4px 2px 0; width: 10px; height: 10px;
+}
+
+.Ldt-Tooltip img {
+    max-width: 140px; max-height: 70px; margin: 0 20px;
+}
+
+.Ldt-Tooltip p {
+    margin: 2px 0;
+  font-size: 12px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tooltip.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,42 @@
+/* this widget displays a small tooltip */
+IriSP.Widgets.Tooltip = function(Popcorn, config, Serializer) {
+    IriSP.Widgets.Widget.call(this, Popcorn, config, Serializer);
+};
+
+IriSP.Widgets.Tooltip.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Tooltip.prototype.template = '<div class="Ldt-Tooltip"><div class="Ldt-Tooltip-Color"></div><div class="Ldt-Tooltip-Text"></div></div>';
+
+IriSP.Widgets.Tooltip.prototype.draw = function() {
+    _this = this;
+    this.$.html(this.template);
+    this.$.parent().css({
+        "position" : "relative"
+    });
+    this.$tip = this.$.find(".Ldt-Tooltip");
+    this.$.mouseover(function() {
+        _this.$tip.hide();
+    });
+    this.hide();
+};
+
+IriSP.Widgets.Tooltip.prototype.show = function(x, y, text, color) {
+    
+    if (typeof color !== "undefined") {
+        this.$.find(".Ldt-Tooltip-Color").show().css("background-color", color);
+    } else {
+        this.$.find(".Ldt-Tooltip-Color").hide();
+    }
+
+    this.$.find(".Ldt-Tooltip-Text").html(text);
+
+    this.$tip.show();
+    this.$tip.css({
+        "left" : Math.floor(x - this.$tip.outerWidth() / 2) + "px",
+        "top" : Math.floor(y - this.$tip.outerHeight()) + "px"
+    });
+};
+
+IriSP.Widgets.Tooltip.prototype.hide = function() {
+    this.$tip.hide();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Trace.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,148 @@
+IriSP.Widgets.Trace = function(player, config) {
+  IriSP.Widgets.Widget.call(this, player, config);
+    
+}
+
+IriSP.Widgets.Trace.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Trace.prototype.defaults = {
+    js_console : false,
+    url: "http://traces.advene.org:5000/",
+    requestmode: 'GET',
+    syncmode: "sync"
+}
+
+IriSP.Widgets.Trace.prototype.draw = function() {
+  this.lastEvent = "";
+  if (typeof window.tracemanager === "undefined") {
+      console.log("Tracemanager not found");
+      return;
+  }
+  var _this = this,
+    _listeners = {
+        "IriSP.createAnnotationWidget.addedAnnotation" : 0,
+        "IriSP.search.open" : 0,
+        "IriSP.search.closed" : 0,
+        "IriSP.search" : 0,
+        "IriSP.search.cleared" : 0,
+        "IriSP.search.matchFound" : 0,
+        "IriSP.search.noMatchFound" : 0,
+        "IriSP.search.triggeredSearch" : 0,
+        "IriSP.TraceWidget.MouseEvents" : 0,
+        "play" : 0,
+        "pause" : 0,
+        "volumechange" : 0,
+        "seeked" : 0,
+        "play" : 0,
+        "pause" : 0,
+        "timeupdate" : 2000
+    };
+    IriSP._(_listeners).each(function(_ms, _listener) {
+        var _f = function(_arg) {
+            _this.eventHandler(_listener, _arg);
+        }
+        if (_ms) {
+            _f = IriSP._.throttle(_f, _ms);
+        }
+        _this.player.popcorn.listen(_listener, _f);
+    });
+    this.player.popcorn.listen("timeupdate", IriSP._.throttle(function(_arg) {
+        _this.eventHandler(_listener, _arg);
+    }));
+    
+    this.tracer = window.tracemanager.init_trace("test", {
+        url: this.url,
+        requestmode: this.requestmode,
+        syncmode: this.syncmode
+    });
+    this.tracer.set_default_subject("metadataplayer");
+    this.tracer.trace("StartTracing", {});
+    
+    this.mouseLocation = '';
+    IriSP.jQuery(".Ldt-Widget").bind("click mouseover mouseout dragstart dragstop", function(_e) {
+        var _widget = IriSP.jQuery(this).attr("widget-type"),
+            _class = _e.target.className;
+        var _data = {
+            "type": _e.type,
+            "x": _e.clientX,
+            "y": _e.clientY,
+            "widget": _widget
+        }
+        if (typeof _class == "string" && _class.indexOf('Ldt-TraceMe') != -1) {
+            var _name = _e.target.localName,
+                _id = _e.target.id,
+                _text = _e.target.textContent.trim(),
+                _title = _e.target.title,
+                _value = _e.target.value;
+            _data.target = _name + (_id.length ? '#' + IriSP.jqEscape(_id) : '') + (_class.length ? ('.' + IriSP.jqEscape(_class).replace(/\s/g,'.')).replace(/\.Ldt-(Widget|TraceMe)/g,'') : '');
+            if (typeof _title == "string" && _title.length && _title.length < 140) {
+                _data.title = _title;
+            }
+            if (typeof _text == "string" && _text.length && _text.length < 140) {
+                _data.text = _text;
+            }
+            if (typeof _value == "string" && _value.length) {
+                _data.value = _value;
+            }
+            this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+        } else {
+            //console.log(_e.type+','+_this.mouseLocation+','+_widget);
+            if (_e.type == "mouseover") {
+                if (_this.mouseLocation != _widget) {
+                    _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+                } else {
+                    if (typeof _this.moTimeout != "undefined") {
+                        clearTimeout(_this.moTimeout);
+                        delete _this.moTimeout;
+                    }
+                }
+            }
+            if (_e.type == "click") {
+                _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+            }
+            if (_e.type == "mouseout") {
+                if (typeof _this.moTimeout != "undefined") {
+                    clearTimeout(_this.moTimeout);
+                }
+                _this.moTimeout = setTimeout(function() {
+                   if (_data.widget != _this.mouseLocation) {
+                       _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+                   }
+                },100);
+            }
+        }
+        _this.mouseLocation = _widget;
+    });
+}
+
+IriSP.Widgets.Trace.prototype.eventHandler = function(_listener, _arg) {
+    var _traceName = 'Mdp_';
+    if (typeof _arg == "string" || typeof _arg == "number") {
+        _arg = { "value" : _arg }
+    }
+    if (typeof _arg == "undefined") {
+        _arg = {}
+    }
+    switch(_listener) {
+        case 'IriSP.TraceWidget.MouseEvents':
+            _traceName += _arg.widget + '_' + _arg.type;
+            delete _arg.widget;
+            delete _arg.type;
+        break;
+        case 'timeupdate':
+        case 'play':
+        case 'pause':
+            _arg.time = this.player.popcorn.currentTime() * 1000;
+        case 'seeked':
+        case 'volumechange':
+            _traceName += 'Popcorn_' + _listener;
+        break;
+        default:
+            _traceName += _listener.replace('IriSP.','').replace('.','_');
+    }
+    this.lastEvent = _traceName;
+    this.tracer.trace(_traceName, _arg);
+    if (this.js_console) {
+        console.log("tracer.trace('" + _traceName + "', " + JSON.stringify(_arg) + ");");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tweet.css	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,105 @@
+.Ldt-Tweet-Widget {
+    border: 1px solid #b7b7b7;
+    padding: 1px;
+    margin: 0;
+    font-family: Helvetica, Arial, sans-serif;
+}
+
+.Ldt-Tweet-Inner {
+    background: url(img/pinstripe.png);
+    padding: 5px;
+    margin: 0;
+    min-height: 50px;
+}
+
+.Ldt-Tweet-PinClose-Buttons {
+    float: right;
+}
+
+.Ldt-Tweet-PinClose-Buttons a {
+    display: inline-block; width: 17px; height: 17px; margin: 2px;
+    background: url(img/widget-control.png);
+}
+
+a.Ldt-Tweet-Pin {
+    background-position: 0 -17px;
+}
+
+a.Ldt-Tweet-Pin:hover, a.Ldt-Tweet-Pin.active {
+    background-position: -17px -17px;
+}
+
+a.Ldt-Tweet-Pin.active:hover {
+    background-position: 0 -17px;
+}
+
+a.Ldt-Tweet-Close:hover {
+    background-position: -17px 0;
+}
+
+.Ldt-Tweet-AvatarContainer {
+    float: left; width: 48px; height: 48px; margin: 2px 4px 2px 0;
+}
+
+.Ldt-Tweet-Avatar {
+    border: none; width: 48px; height: 48px;
+}
+
+.Ldt-Tweet-Inner h3 {
+    margin: 2px 0 5px 52px;
+    font-size: 14px;
+}
+
+a.Ldt-Tweet-ScreenName {
+    color: #0068c4;
+    text-decoration: none;
+}
+
+a.Ldt-Tweet-ScreenName:hover {
+    color: #000000;
+    text-decoration: underline;
+}
+
+p.Ldt-Tweet-Contents {
+    margin: 5px 0 5px 52px;
+    font-size: 12px;
+}
+
+.Ldt-Tweet-Bottom {
+    margin: 5px 0 0;
+    font-size: 12px;
+    text-align: right;
+}
+
+.Ldt-Tweet-Time {
+    display: inline-block;
+}
+
+.Ldt-Tweet-Bottom a {
+    display: inline-block;
+    margin-left: 12px;
+    color: #000000;
+    text-decoration: none;
+}
+
+.Ldt-Tweet-Bottom a:hover {
+    text-decoration: underline;
+}
+
+.Ldt-Tweet-Icon {
+    display: inline-block; width: 16px; height: 16px;
+    margin: 0 2px -2px;
+    background: url(img/twitter_sprites.png);
+}
+
+.Ldt-Tweet-Retweet .Ldt-Tweet-Icon {
+    background-position: -80px 0;
+}
+
+.Ldt-Tweet-Retweet:hover .Ldt-Tweet-Icon {
+    background-position: -96px 0;
+}
+
+.Ldt-Tweet-Reply:hover .Ldt-Tweet-Icon {
+    background-position: -16px 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/res/metadataplayer/Tweet.js	Thu May 03 17:52:07 2012 +0200
@@ -0,0 +1,196 @@
+IriSP.Widgets.Tweet = function(player, config) {
+    IriSP.Widgets.Widget.call(this, player, config);
+    this.lastAnnotation = false;
+};
+
+IriSP.Widgets.Tweet.prototype = new IriSP.Widgets.Widget();
+
+IriSP.Widgets.Tweet.prototype.defaults = {
+    hide_timeout: 5000,
+    polemics : [
+        {
+            "keywords" : [ "++" ],
+            "description" : "positif",
+            "color" : "#30d765"
+        },
+        {
+            "keywords" : [ "--" ],
+            "description" : "negatif",
+            "color" : "#f51123"
+        },
+        {
+            "keywords" : [ "==" ],
+            "description" : "reference",
+            "color" : "#f1e24a"  
+        },
+        {
+            "keywords" : [ "??" ],
+            "description" : "question",
+            "color" : "#05aae6"
+        }
+    ]
+}
+
+IriSP.Widgets.Tweet.prototype.messages = {
+    "fr": {
+        retweet: "Retweeter",
+        reply: "Répondre",
+        keep_visible: "Garder visible",
+        dont_keep_visible: "Permettre la fermeture automatique",
+        close_widget: "Fermer l'affichage du tweet",
+        original_time: "Heure d'envoi&nbsp; ",
+        video_time: "Temps de la vidéo&nbsp;: "
+    },
+    "en": {
+        retweet: "Retweet",
+        reply: "Reply",
+        keep_visible: "Keep visible",
+        dont_keep_visible: "Don't keep visible",
+        close_widget: "Close tweet display",
+        original_time: "Tweet sent at: ",
+        video_time: "Video time: "
+    }
+}
+
+IriSP.Widgets.Tweet.prototype.template =
+    '<div class="Ldt-Tweet-Widget"><div class="Ldt-Tweet-Inner"><div class="Ldt-Tweet-PinClose-Buttons">'
+    + '<a href="#" class="Ldt-Tweet-Pin" title="{{l10n.keep_visible}}"></a>'
+    + '<a href="#" class="Ldt-Tweet-Close" title="{{l10n.close_widget}}"></a>'
+    + '</div><div class="Ldt-Tweet-AvatarContainer"><a href="#" class="Ldt-Tweet-ProfileLink" target="_blank">'
+    + '<img src="" class="Ldt-Tweet-Avatar"/></a></div><h3><a href="#" class="Ldt-Tweet-ProfileLink Ldt-Tweet-ScreenName" target="_blank">'
+    + '</a> (<span class="Ldt-Tweet-FullName"></span>)</h3><p class="Ldt-Tweet-Contents"></p><div class="Ldt-Tweet-Bottom">'
+    + '<span class="Ldt-Tweet-Time"></span><a href="" target="_blank" class="Ldt-Tweet-Retweet"><div class="Ldt-Tweet-Icon"></div>{{l10n.retweet}}</a>'
+    + '<a href="" target="_blank" class="Ldt-Tweet-Reply"><div class="Ldt-Tweet-Icon"></div>{{l10n.reply}}</a></div></div></div>';
+    
+
+IriSP.Widgets.Tweet.prototype.draw = function() {
+    this.renderTemplate();
+    this.bindPopcorn("IriSP.Tweet.show","show");
+    this.pinned = false;
+    var _this = this;
+    this.$.find(".Ldt-Tweet-Pin").click(function() {
+        _this.pinned = !_this.pinned;
+        var _el = IriSP.jQuery(this)
+        if (_this.pinned) {
+            _el.addClass("active").attr("title",_this.l10n.dont_keep_visible);
+            _this.cancelTimeout();
+        } else {
+            _el.removeClass("active").attr("title",_this.l10n.keep_visible);
+            _this.hideTimeout();
+        }
+    });
+    this.$.find(".Ldt-Tweet-Close").click(function() {
+        _this.hide();
+    });
+    this.$.hide();
+}
+
+IriSP.Widgets.Tweet.prototype.show = function(_id) {
+    var _tweet = this.source.getElement(_id);
+    if (typeof _tweet !== "undefined" && typeof _tweet.source !== "undefined") {
+        var _entities = [];
+        for (var _i = 0; _i < _tweet.source.entities.hashtags.length; _i++) {
+            var _hash = _tweet.source.entities.hashtags[_i];
+            _entities.push({
+                is_link: true,
+                text: '#' + _hash.text,
+                url: 'http://twitter.com/search?q=%23' + encodeURIComponent(_hash.text),
+                indices: _hash.indices
+            });
+        }
+        for (var _i = 0; _i < _tweet.source.entities.urls.length; _i++) {
+            var _url = _tweet.source.entities.urls[_i],
+                _displayurl = (typeof _url.display_url !== "undefined" && _url.display_url !== null ? _url.display_url : _url.url),
+                _linkurl = (typeof _url.expanded_url !== "undefined" && _url.expanded_url !== null ? _url.expanded_url : _url.url);
+            _displayurl = _displayurl.replace(/^\w+:\/\//,'');
+            if (!/^\w+:\/\//.test(_linkurl)) {
+                _linkurl = 'http://' + _linkurl;
+            }
+            _entities.push({
+                is_link: true,
+                text: _displayurl,
+                url: _linkurl,
+                indices: _url.indices
+            });
+        }
+        for (var _i = 0; _i < _tweet.source.entities.user_mentions.length; _i++) {
+            var _user = _tweet.source.entities.user_mentions[_i];
+            _entities.push({
+                is_link: true,
+                text: '@' + _user.screen_name,
+                url: 'http://twitter.com/' + encodeURIComponent(_user.screen_name),
+                indices: _user.indices
+            });
+        }
+        for (var _i = 0; _i < this.polemics.length; _i++) {
+            for (var _j = 0; _j < this.polemics[_i].keywords.length; _j++) {
+                var _p = _tweet.source.text.indexOf(this.polemics[_i].keywords[_j]);
+                while (_p !== -1) {
+                    var _end = (_p + this.polemics[_i].keywords[_j].length);
+                    _entities.push({
+                        is_link: false,
+                        text: this.polemics[_i].keywords[_j],
+                        color: this.polemics[_i].color,
+                        indices: [_p, _end]
+                    });
+                    _p = _tweet.source.text.indexOf(this.polemics[_i].keywords[_j], _end);
+                }
+            }
+        }
+        _entities = IriSP._(_entities).sortBy(function(_entity) {
+            return _entity.indices[0];
+        });
+        var _currentPos = 0,
+            _txt = '';
+        for (var _i = 0; _i < _entities.length; _i++) {
+            if (_entities[_i].indices[0] >= _currentPos) {
+                _txt += _tweet.source.text.substring(_currentPos, _entities[_i].indices[0]);
+                _currentPos = _entities[_i].indices[1];
+                if (_entities[_i].is_link) {
+                    _txt += '<a href="' + _entities[_i].url + '" target="_blank">';
+                } else {
+                    _txt += '<span style="background:' + _entities[_i].color + '">';
+                }
+                _txt += _entities[_i].text;
+                if (_entities[_i].is_link) {
+                    _txt += '</a>';
+                } else {
+                    _txt += '</span>';
+                }
+            }
+        }
+        _txt += _tweet.source.text.substring(_currentPos);
+        this.$.find(".Ldt-Tweet-Avatar").attr("src",_tweet.source.user.profile_image_url);
+        this.$.find(".Ldt-Tweet-ScreenName").html('@'+_tweet.source.user.screen_name);
+        this.$.find(".Ldt-Tweet-ProfileLink").attr("href", "http://twitter.com/" + _tweet.source.user.screen_name);
+        this.$.find(".Ldt-Tweet-FullName").html(_tweet.source.user.name);
+        this.$.find(".Ldt-Tweet-Contents").html(_txt);
+        this.$.find(".Ldt-Tweet-Time").html(this.l10n.original_time + new Date(_tweet.source.created_at).toLocaleTimeString() + " / " + this.l10n.video_time + _tweet.begin.toString());
+        this.player.popcorn.trigger("IriSP.Annotation.minimize");
+        this.$.slideDown();
+        this.cancelTimeout();
+        if (!this.pinned) {
+            this.hideTimeout();
+        }
+    } else {
+        this.hide();
+    }
+}
+
+IriSP.Widgets.Tweet.prototype.hide = function() {
+    this.player.popcorn.trigger("IriSP.Annotation.maximize");
+    this.$.slideUp();
+    this.cancelTimeout();
+}
+
+IriSP.Widgets.Tweet.prototype.cancelTimeout = function() {
+    if (typeof this.hide_timer !== "undefined") {
+        window.clearTimeout(this.hide_timer);
+        this.hide_timer = undefined;
+    }  
+}
+
+IriSP.Widgets.Tweet.prototype.hideTimeout = function() {
+    this.cancelTimeout();
+    this.hide_timer = window.setTimeout(this.functionWrapper("hide"), this.hide_timeout);
+}
Binary file web/res/metadataplayer/img/loader.gif has changed
Binary file web/res/metadataplayer/img/pinstripe-grey.png has changed
Binary file web/res/metadataplayer/img/pinstripe.png has changed
Binary file web/res/metadataplayer/img/player-sprites.png has changed
Binary file web/res/metadataplayer/img/player_gradient.png has changed
Binary file web/res/metadataplayer/img/slice-handles.png has changed
Binary file web/res/metadataplayer/img/socialbuttons.png has changed
Binary file web/res/metadataplayer/img/twitter_sprites.png has changed
Binary file web/res/metadataplayer/img/white_arrow_long.png has changed
Binary file web/res/metadataplayer/img/widget-control.png has changed