]> git.mjollnir.org Git - moodle.git/commitdiff
Flash-based filters are now strrrrrrrict AND accessible! MDL-7889
authormoodler <moodler>
Mon, 8 Jan 2007 11:55:18 +0000 (11:55 +0000)
committermoodler <moodler>
Mon, 8 Jan 2007 11:55:18 +0000 (11:55 +0000)
Unfortunately this is only possible using Javascript to rewrite the DOM, so this means Flash content won't work without Javascript on.

   MDL-7861

filter/mediaplugin/filter.php
lib/javascript.php
lib/ufo.js [new file with mode: 0644]

index 52e466609b4aaefc5a63efbb840e6d22131ed294..fb4fb6d24327d7a426a260115ee166ffb835b4bb 100644 (file)
 function mediaplugin_filter($courseid, $text) {
     global $CFG, $THEME;
 
+    static $count = 0;
+
+    $count++;
+
     include "defaultsettings.php";
 
     if ($CFG->filter_mediaplugin_enable_mp3) {
@@ -30,23 +34,21 @@ function mediaplugin_filter($courseid, $text) {
                 $c = 'bgColour=000000&amp;btnColour=ffffff&amp;btnBorderColour=cccccc&amp;iconColour=000000&amp;iconOverColour=00cc00&amp;trackColour=cccccc&amp;handleColour=ffffff&amp;loaderColour=ffffff&amp;waitForPlay=yes&amp;';
             }
         }
-        // $c = htmlentities($c);  // Commented out pending bug 5223
         $search = '/<a(.*?)href=\"([^<]+)\.mp3\"([^>]*)>(.*?)<\/a>/is';
 
-        $replace  = '\\0&nbsp;<object class="mediaplugin mp3" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
-        $replace .= ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
-        $replace .= ' width="90" height="15" id="mp3player">';
-        $replace .= " <param name=\"movie\" value=\"$CFG->wwwroot/filter/mediaplugin/mp3player.swf?src=\\2.mp3\" />";
-        $replace .= ' <param name="quality" value="high" />';
-        $replace .= ' <param name="bgcolor" value="#333333" />';
-        $replace .= ' <param name="flashvars" value="'.$c.'" />';
-        $replace .= " <embed src=\"$CFG->wwwroot/filter/mediaplugin/mp3player.swf?src=\\2.mp3\" ";
-        $replace .= "  quality=\"high\" bgcolor=\"#333333\" width=\"90\" height=\"15\" name=\"mp3player\" ";
-        $replace .= ' type="application/x-shockwave-flash" ';
-        $replace .= ' flashvars="'.$c.'" ';
-        $replace .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
-        $replace .= '</embed>';
-        $replace .= '</object>&nbsp;';
+        // We're using the UFO technique to attain XHTML Strict 1.0
+        // See: http://www.bobbyvandersluis.com/ufo/
+
+        $replace = '<script type="text/javascript">'."\n".
+                   '//<![CDATA['."\n".
+                   'var FO'.$count.' = { movie:"'.$CFG->wwwroot.'/filter/mediaplugin/mp3player.swf?src=\\2.mp3",'.
+                   'width:"90", height:"15", majorversion:"6", build:"40", flashvars:"'.$c.'", quality: "high" };'."\n".
+                   'UFO.create(FO'.$count.', "filtermp3'.$count.'");'."\n".
+                   '//]]>'."\n".
+                   '</script>'."\n".
+                   '\\0&nbsp;<span class="mediaplugin mp3" id="filtermp3'.$count.'">'.
+                   '('.get_string('mp3audio', 'mediaplugin').')'.
+                   '</span>'."\n";
     
         $text = preg_replace($search, $replace, $text);
     }
@@ -59,52 +61,62 @@ function mediaplugin_filter($courseid, $text) {
 
         $replace = array();
 
-        $replace[0]  = '\\0<p class="mediaplugin swf"><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
-        $replace[0] .= ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
-        $replace[0] .= ' width="\\3" height="\\4" id="mp3player">';
-        $replace[0] .= " <param name=\"movie\" value=\"\\2.swf\" />";
-        $replace[0] .= ' <param name="quality" value="high" />';
-        $replace[0] .= ' <param name="AllowScriptAccess" value="never" />';
-        $replace[0] .= " <embed src=\"\\2.swf\" ";
-        $replace[0] .= '  quality="high" width="\\3" height="\\4" name="flashfilter" AllowScriptAccess="never" ';
-        $replace[0] .= ' type="application/x-shockwave-flash" ';
-        $replace[0] .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
-        $replace[0] .= '</embed>';
-        $replace[0] .= '</object></p>';
-
-        $replace[1]  = '\\0<p class="mediaplugin swf"><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
-        $replace[1] .= ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
-        $replace[1] .= ' width="400" height="300" id="mp3player">';
-        $replace[1] .= " <param name=\"movie\" value=\"\\2.swf\" />";
-        $replace[1] .= ' <param name="quality" value="high" />';
-        $replace[1] .= ' <param name="AllowScriptAccess" value="never" />';
-        $replace[1] .= " <embed src=\"\\2.swf\" ";
-        $replace[1] .= '  quality="high" width="400" height="300" name="flashfilter" AllowScriptAccess="never" ';
-        $replace[1] .= ' type="application/x-shockwave-flash" ';
-        $replace[1] .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
-        $replace[1] .= '</embed>';
-        $replace[1] .= '</object></p>';
+        $replace[0] = '<script type="text/javascript">'."\n".
+                      '//<![CDATA['."\n".
+                      'var FO'.$count.' = { movie:"\\2.swf", width:"\\3", height:"\\4", majorversion:"6", build:"40", '.
+                      'allowscriptaccess:"never", quality: "high" };'."\n".
+                      'UFO.create(FO'.$count.', "filterswf'.$count.'");'."\n".
+                      '//]]>'."\n".
+                      '</script>'."\n".
+                      '\\0&nbsp;<span class="mediaplugin swf" id="filterswf'.$count.'">'.
+                      '('.get_string('flashanimation', 'mediaplugin').')'.
+                      '</span>'."\n";
+
+        $replace[1] = '<script type="text/javascript">'."\n".
+                      '//<![CDATA['."\n".
+                      'var FO'.$count.' = { movie:"\\2.swf", width:"400", height:"300", majorversion:"6", build:"40", '.
+                      'allowscriptaccess:"never", quality: "high" };'."\n".
+                      'UFO.create(FO'.$count.', "filterswf'.$count.'");'."\n".
+                      '//]]>'."\n".
+                      '</script>'."\n".
+                      '\\0&nbsp;<span class="mediaplugin swf" id="filterswf'.$count.'">'.
+                      '('.get_string('flashanimation', 'mediaplugin').')'.
+                      '</span>'."\n";
 
         $text = preg_replace($search, $replace, $text);
 
     }
 
     if ($CFG->filter_mediaplugin_enable_flv) {
-        $search = '/<a(.*?)href=\"([^<]+)\.flv\"([^>]*)>(.*?)<\/a>/is';
+        $search = array(
+                '/<a(.*?)href=\"([^<]+)\.flv\?d=([\d]{1,3}%?)x([\d]{1,3}%?)\"([^>]*)>(.*?)<\/a>/is',
+                '/<a(.*?)href=\"([^<]+)\.flv\"([^>]*)>(.*?)<\/a>/is'
+                );
             
-        $replace  = '\\0&nbsp;<object class="mediaplugin flv" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
-        $replace .= ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
-        $replace .= ' width="480" height="360" id="flvplayer">';
-        $replace .= " <param name=\"movie\" value=\"$CFG->wwwroot/filter/mediaplugin/flvplayer.swf?file=\\2.flv\" />";
-        $replace .= ' <param name="quality" value="high" />';
-        $replace .= ' <param name="bgcolor" value="#FFFFFF" />';
-        $replace .= " <embed src=\"$CFG->wwwroot/filter/mediaplugin/flvplayer.swf?file=\\2.flv\" ";
-        $replace .= "  quality=\"high\" bgcolor=\"#FFFFFF\" width=\"480\" height=\"360\" name=\"flvplayer\" ";
-        $replace .= ' type="application/x-shockwave-flash" ';
-        $replace .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
-        $replace .= '</embed>';
-        $replace .= '</object>&nbsp;';
-    
+        $replace[1] = '<script type="text/javascript">'."\n".
+                      '//<![CDATA['."\n".
+                      'var FO'.$count.' = { movie:"'.$CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf?file=\\2.flv", '.
+                      'width:"\\3", height:"\\4", majorversion:"6", build:"40", '.
+                      'allowscriptaccess:"never", quality: "high" };'."\n".
+                      'UFO.create(FO'.$count.', "filterflv'.$count.'");'."\n".
+                      '//]]>'."\n".
+                      '</script>'."\n".
+                      '\\0&nbsp;<span class="mediaplugin flv" id="filterflv'.$count.'">'.
+                      '('.get_string('flashvideo', 'mediaplugin').')'.
+                      '</span>'."\n";
+
+        $replace[1] = '<script type="text/javascript">'."\n".
+                      '//<![CDATA['."\n".
+                      'var FO'.$count.' = { movie:"'.$CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf?file=\\2.flv", '.
+                      'width:"480", height:"360", majorversion:"6", build:"40", '.
+                      'allowscriptaccess:"never", quality: "high" };'."\n".
+                      'UFO.create(FO'.$count.', "filterflv'.$count.'");'."\n".
+                      '//]]>'."\n".
+                      '</script>'."\n".
+                      '\\0&nbsp;<span class="mediaplugin flv" id="filterflv'.$count.'">'.
+                      '('.get_string('flashvideo', 'mediaplugin').')'.
+                      '</span>'."\n";
+
         $text = preg_replace($search, $replace, $text);
     }
 
@@ -115,16 +127,11 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '        codebase="http://www.apple.com/qtactivex/qtplugin.cab" ';
         $replace .= '        height="300" width="400"';
         $replace .= '        id="quicktime" type="application/x-oleobject">';
-        $replace .= "<param name=\"src\" value=\"\\2.mov\" />";
+        $replace .= '<param name="src" value="\\2.mov" />';
         $replace .= '<param name="autoplay" value="false" />';
         $replace .= '<param name="loop" value="true" />';
         $replace .= '<param name="controller" value="true" />';
         $replace .= '<param name="scale" value="aspect" />';
-        $replace .= "\n<embed src=\"\\2.mov\" name=\"quicktime\" type=\"video/quicktime\" ";
-        $replace .= ' height="300" width="400" scale="aspect" ';
-        $replace .= ' autoplay="false" controller="true" loop="true" ';
-        $replace .= ' pluginspage="http://quicktime.apple.com/">';
-        $replace .= '</embed>';
         $replace .= '</object></p>';
 
         $text = preg_replace($search, $replace, $text);
@@ -137,7 +144,7 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= ' codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701" ';
         $replace .= ' standby="Loading Microsoft® Windows® Media Player components..." ';
         $replace .= ' id="msplayer" type="application/x-oleobject">';
-        $replace .= "<param name=\"Filename\" value=\"\\2.wmv\" />";
+        $replace .= '<param name="Filename" value="\\2.wmv" />';
         $replace .= '<param name="ShowControls" value="true" />';
         $replace .= '<param name="AutoRewind" value="true" />';
         $replace .= '<param name="AutoStart" value="false" />';
@@ -147,11 +154,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="AnimationAtStart" value="false" />';
         $replace .= '<param name="ShowGotoBar" value="false" />';
         $replace .= '<param name="EnableFullScreenControls" value="true" />';
-        $replace .= "\n<embed src=\"\\2.wmv\" name=\"msplayer\" type=\"video/x-ms\" ";
-        $replace .= ' ShowControls="1" AutoRewind="1" AutoStart="0" Autosize="0" EnableContextMenu="1"';
-        $replace .= ' TransparentAtStart="0" AnimationAtStart="0" ShowGotoBar="0" EnableFullScreenControls="1"';
-        $replace .= ' pluginspage="http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/">';
-        $replace .= '</embed>';
         $replace .= '</object></p>';
 
         $text = preg_replace($search, $replace, $text);
@@ -164,7 +166,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="src" value="\\2.\\3" />';
         $replace .= '<param name="controller" value="true" />';
         $replace .= '<param name="autoplay" value="false" />';
-        $replace .= '<embed src="\\2.\\3" width="240" height="180" controller="true" autoplay="false"> </embed>';
         $replace .= '</object></p>';
         
         $text = preg_replace($search, $replace, $text);
@@ -177,7 +178,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="src" value="\\2.avi" />';
         $replace .= '<param name="controller" value="true" />';
         $replace .= '<param name="autoplay" value="false" />';
-        $replace .= '<embed src="\\2.avi" width="240" height="180" controller="true" autoplay="false"> </embed>';
         $replace .= '</object></p>';
     
         $text = preg_replace($search, $replace, $text);
@@ -192,8 +192,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="controls" value="imagewindow" />';
         $replace .= '<param name="console" value="video" />';
         $replace .= '<param name="loop" value="true" />';
-        $replace .= '<embed src="\\2.rm" width=240" height="180" loop="true" type="audio/x-pn-realaudio-plugin" controls="imagewindow" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object><br />';
 
         $replace .= '<object width="320" height="30">';
@@ -201,8 +199,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="autostart" value="true" />';
         $replace .= '<param name="controls" value="ControlPanel" />';
         $replace .= '<param name="console" value="video" />';
-        $replace .= '<embed src="\\2.rm" width="240" height="30" controls="ControlPanel" type="audio/x-pn-realaudio-plugin" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object></p>';
 
         $text = preg_replace($search, $replace, $text);
@@ -217,8 +213,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="controls" value="imagewindow" />';
         $replace .= '<param name="console" value="video" />';
         $replace .= '<param name="loop" value="true" />';
-        $replace .= '<embed src="\\2.rm" width=240" height="180" loop="true" type="audio/x-pn-realaudio-plugin" controls="imagewindow" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object><br />';
 
         $replace .= '<object width="320" height="30">';
@@ -226,8 +220,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="autostart" value="true" />';
         $replace .= '<param name="controls" value="ControlPanel" />';
         $replace .= '<param name="console" value="video" />';
-        $replace .= '<embed src="\\2.rm" width="240" height="30" controls="ControlPanel" type="audio/x-pn-realaudio-plugin" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object></p>';
 
         $text = preg_replace($search, $replace, $text);
@@ -242,8 +234,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="controls" value="imagewindow" />';
         $replace .= '<param name="console" value="video" />';
         $replace .= '<param name="loop" value="true" />';
-        $replace .= '<embed src="\\2.rm" width=240" height="180" loop="true" type="audio/x-pn-realaudio-plugin" controls="imagewindow" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object><br />';
 
         $replace .= '<object width="320" height="30">';
@@ -251,8 +241,6 @@ function mediaplugin_filter($courseid, $text) {
         $replace .= '<param name="autostart" value="true" />';
         $replace .= '<param name="controls" value="ControlPanel" />';
         $replace .= '<param name="console" value="video" />';
-        $replace .= '<embed src="\\2.rm" width="240" height="30" controls="ControlPanel" type="audio/x-pn-realaudio-plugin" console="video" autostart="true">';
-        $replace .= '</embed>';
         $replace .= '</object></p>';
 
         $text = preg_replace($search, $replace, $text);
index bff9eea60629994e88c7e2490c00ae14e0ff33f0..00db0ccaa34b4546c198470fd80ced9e475175c9 100644 (file)
@@ -22,6 +22,7 @@
 <script type="text/javascript" src="<?php echo $CFG->httpswwwroot ?>/lib/javascript-mod.php"></script>
 <script type="text/javascript" src="<?php echo $CFG->httpswwwroot ?>/lib/overlib.js"></script>
 <script type="text/javascript" src="<?php echo $CFG->httpswwwroot ?>/lib/cookies.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot ?>/lib/ufo.js"></script>
 
 <script type="text/javascript" defer="defer">
 
diff --git a/lib/ufo.js b/lib/ufo.js
new file mode 100644 (file)
index 0000000..4aa8ef4
--- /dev/null
@@ -0,0 +1,286 @@
+/*     Unobtrusive Flash Objects (UFO) v3.20 <http://www.bobbyvandersluis.com/ufo/>
+       Copyright 2005, 2006 Bobby van der Sluis
+       This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
+*/
+
+var UFO = {
+       req: ["movie", "width", "height", "majorversion", "build"],
+       opt: ["play", "loop", "menu", "quality", "scale", "salign", "wmode", "bgcolor", "base", "flashvars", "devicefont", "allowscriptaccess", "seamlesstabbing"],
+       optAtt: ["id", "name", "align"],
+       optExc: ["swliveconnect"],
+       ximovie: "ufo.swf",
+       xiwidth: "215",
+       xiheight: "138",
+       ua: navigator.userAgent.toLowerCase(),
+       pluginType: "",
+       fv: [0,0],
+       foList: [],
+               
+       create: function(FO, id) {
+               if (!UFO.uaHas("w3cdom") || UFO.uaHas("ieMac")) return;
+               UFO.getFlashVersion();
+               UFO.foList[id] = UFO.updateFO(FO);
+               UFO.createCSS("#" + id, "visibility:hidden;");
+               UFO.domLoad(id);
+       },
+
+       updateFO: function(FO) {
+               if (typeof FO.xi != "undefined" && FO.xi == "true") {
+                       if (typeof FO.ximovie == "undefined") FO.ximovie = UFO.ximovie;
+                       if (typeof FO.xiwidth == "undefined") FO.xiwidth = UFO.xiwidth;
+                       if (typeof FO.xiheight == "undefined") FO.xiheight = UFO.xiheight;
+               }
+               FO.mainCalled = false;
+               return FO;
+       },
+
+       domLoad: function(id) {
+               var _t = setInterval(function() {
+                       if ((document.getElementsByTagName("body")[0] != null || document.body != null) && document.getElementById(id) != null) {
+                               UFO.main(id);
+                               clearInterval(_t);
+                       }
+               }, 250);
+               if (typeof document.addEventListener != "undefined") {
+                       document.addEventListener("DOMContentLoaded", function() { UFO.main(id); clearInterval(_t); } , null); // Gecko, Opera 9+
+               }
+       },
+
+       main: function(id) {
+               var _fo = UFO.foList[id];
+               if (_fo.mainCalled) return;
+               UFO.foList[id].mainCalled = true;
+               document.getElementById(id).style.visibility = "hidden";
+               if (UFO.hasRequired(id)) {
+                       if (UFO.hasFlashVersion(parseInt(_fo.majorversion, 10), parseInt(_fo.build, 10))) {
+                               if (typeof _fo.setcontainercss != "undefined" && _fo.setcontainercss == "true") UFO.setContainerCSS(id);
+                               UFO.writeSWF(id);
+                       }
+                       else if (_fo.xi == "true" && UFO.hasFlashVersion(6, 65)) {
+                               UFO.createDialog(id);
+                       }
+               }
+               document.getElementById(id).style.visibility = "visible";
+       },
+       
+       createCSS: function(selector, declaration) {
+               var _h = document.getElementsByTagName("head")[0]; 
+               var _s = UFO.createElement("style");
+               if (!UFO.uaHas("ieWin")) _s.appendChild(document.createTextNode(selector + " {" + declaration + "}")); // bugs in IE/Win
+               _s.setAttribute("type", "text/css");
+               _s.setAttribute("media", "screen"); 
+               _h.appendChild(_s);
+               if (UFO.uaHas("ieWin") && document.styleSheets && document.styleSheets.length > 0) {
+                       var _ls = document.styleSheets[document.styleSheets.length - 1];
+                       if (typeof _ls.addRule == "object") _ls.addRule(selector, declaration);
+               }
+       },
+       
+       setContainerCSS: function(id) {
+               var _fo = UFO.foList[id];
+               var _w = /%/.test(_fo.width) ? "" : "px";
+               var _h = /%/.test(_fo.height) ? "" : "px";
+               UFO.createCSS("#" + id, "width:" + _fo.width + _w +"; height:" + _fo.height + _h +";");
+               if (_fo.width == "100%") {
+                       UFO.createCSS("body", "margin-left:0; margin-right:0; padding-left:0; padding-right:0;");
+               }
+               if (_fo.height == "100%") {
+                       UFO.createCSS("html", "height:100%; overflow:hidden;");
+                       UFO.createCSS("body", "margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; height:100%;");
+               }
+       },
+
+       createElement: function(el) {
+               return (UFO.uaHas("xml") && typeof document.createElementNS != "undefined") ?  document.createElementNS("http://www.w3.org/1999/xhtml", el) : document.createElement(el);
+       },
+
+       createObjParam: function(el, aName, aValue) {
+               var _p = UFO.createElement("param");
+               _p.setAttribute("name", aName); 
+               _p.setAttribute("value", aValue);
+               el.appendChild(_p);
+       },
+
+       uaHas: function(ft) {
+               var _u = UFO.ua;
+               switch(ft) {
+                       case "w3cdom":
+                               return (typeof document.getElementById != "undefined" && typeof document.getElementsByTagName != "undefined" && (typeof document.createElement != "undefined" || typeof document.createElementNS != "undefined"));
+                       case "xml":
+                               var _m = document.getElementsByTagName("meta");
+                               var _l = _m.length;
+                               for (var i = 0; i < _l; i++) {
+                                       if (/content-type/i.test(_m[i].getAttribute("http-equiv")) && /xml/i.test(_m[i].getAttribute("content"))) return true;
+                               }
+                               return false;
+                       case "ieMac":
+                               return /msie/.test(_u) && !/opera/.test(_u) && /mac/.test(_u);
+                       case "ieWin":
+                               return /msie/.test(_u) && !/opera/.test(_u) && /win/.test(_u);
+                       case "gecko":
+                               return /gecko/.test(_u) && !/applewebkit/.test(_u);
+                       case "opera":
+                               return /opera/.test(_u);
+                       case "safari":
+                               return /applewebkit/.test(_u);
+                       default:
+                               return false;
+               }
+       },
+       
+       getFlashVersion: function() {
+               if (UFO.fv[0] != 0) return;  
+               if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
+                       UFO.pluginType = "npapi";
+                       var _d = navigator.plugins["Shockwave Flash"].description;
+                       if (typeof _d != "undefined") {
+                               _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
+                               var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
+                               var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
+                               UFO.fv = [_m, _r];
+                       }
+               }
+               else if (window.ActiveXObject) {
+                       UFO.pluginType = "ax";
+                       try { // avoid fp 6 crashes
+                               var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+                       }
+                       catch(e) {
+                               try { 
+                                       var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+                                       UFO.fv = [6, 0];
+                                       _a.AllowScriptAccess = "always"; // throws if fp < 6.47 
+                               }
+                               catch(e) {
+                                       if (UFO.fv[0] == 6) return;
+                               }
+                               try {
+                                       var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+                               }
+                               catch(e) {}
+                       }
+                       if (typeof _a == "object") {
+                               var _d = _a.GetVariable("$version"); // bugs in fp 6.21/6.23
+                               if (typeof _d != "undefined") {
+                                       _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
+                                       UFO.fv = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
+                               }
+                       }
+               }
+       },
+
+       hasRequired: function(id) {
+               var _l = UFO.req.length;
+               for (var i = 0; i < _l; i++) {
+                       if (typeof UFO.foList[id][UFO.req[i]] == "undefined") return false;
+               }
+               return true;
+       },
+       
+       hasFlashVersion: function(major, release) {
+               return (UFO.fv[0] > major || (UFO.fv[0] == major && UFO.fv[1] >= release)) ? true : false;
+       },
+
+       writeSWF: function(id) {
+               var _fo = UFO.foList[id];
+               var _e = document.getElementById(id);
+               if (UFO.pluginType == "npapi") {
+                       if (UFO.uaHas("gecko") || UFO.uaHas("xml")) {
+                               while(_e.hasChildNodes()) {
+                                       _e.removeChild(_e.firstChild);
+                               }
+                               var _obj = UFO.createElement("object");
+                               _obj.setAttribute("type", "application/x-shockwave-flash");
+                               _obj.setAttribute("data", _fo.movie);
+                               _obj.setAttribute("width", _fo.width);
+                               _obj.setAttribute("height", _fo.height);
+                               var _l = UFO.optAtt.length;
+                               for (var i = 0; i < _l; i++) {
+                                       if (typeof _fo[UFO.optAtt[i]] != "undefined") _obj.setAttribute(UFO.optAtt[i], _fo[UFO.optAtt[i]]);
+                               }
+                               var _o = UFO.opt.concat(UFO.optExc);
+                               var _l = _o.length;
+                               for (var i = 0; i < _l; i++) {
+                                       if (typeof _fo[_o[i]] != "undefined") UFO.createObjParam(_obj, _o[i], _fo[_o[i]]);
+                               }
+                               _e.appendChild(_obj);
+                       }
+                       else {
+                               var _emb = "";
+                               var _o = UFO.opt.concat(UFO.optAtt).concat(UFO.optExc);
+                               var _l = _o.length;
+                               for (var i = 0; i < _l; i++) {
+                                       if (typeof _fo[_o[i]] != "undefined") _emb += ' ' + _o[i] + '="' + _fo[_o[i]] + '"';
+                               }
+                               _e.innerHTML = '<embed type="application/x-shockwave-flash" src="' + _fo.movie + '" width="' + _fo.width + '" height="' + _fo.height + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' + _emb + '></embed>';
+                       }
+               }
+               else if (UFO.pluginType == "ax") {
+                       var _objAtt = "";
+                       var _l = UFO.optAtt.length;
+                       for (var i = 0; i < _l; i++) {
+                               if (typeof _fo[UFO.optAtt[i]] != "undefined") _objAtt += ' ' + UFO.optAtt[i] + '="' + _fo[UFO.optAtt[i]] + '"';
+                       }
+                       var _objPar = "";
+                       var _l = UFO.opt.length;
+                       for (var i = 0; i < _l; i++) {
+                               if (typeof _fo[UFO.opt[i]] != "undefined") _objPar += '<param name="' + UFO.opt[i] + '" value="' + _fo[UFO.opt[i]] + '" />';
+                       }
+                       var _p = window.location.protocol == "https:" ? "https:" : "http:";
+                       _e.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + _objAtt + ' width="' + _fo.width + '" height="' + _fo.height + '" codebase="' + _p + '//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + _fo.majorversion + ',0,' + _fo.build + ',0"><param name="movie" value="' + _fo.movie + '" />' + _objPar + '</object>';
+               }
+       },
+               
+       createDialog: function(id) {
+               var _fo = UFO.foList[id];
+               UFO.createCSS("html", "height:100%; overflow:hidden;");
+               UFO.createCSS("body", "height:100%; overflow:hidden;");
+               UFO.createCSS("#xi-con", "position:absolute; left:0; top:0; z-index:1000; width:100%; height:100%; background-color:#fff; filter:alpha(opacity:75); opacity:0.75;");
+               UFO.createCSS("#xi-dia", "position:absolute; left:50%; top:50%; margin-left: -" + Math.round(parseInt(_fo.xiwidth, 10) / 2) + "px; margin-top: -" + Math.round(parseInt(_fo.xiheight, 10) / 2) + "px; width:" + _fo.xiwidth + "px; height:" + _fo.xiheight + "px;");
+               var _b = document.getElementsByTagName("body")[0];
+               var _c = UFO.createElement("div");
+               _c.setAttribute("id", "xi-con");
+               var _d = UFO.createElement("div");
+               _d.setAttribute("id", "xi-dia");
+               _c.appendChild(_d);
+               _b.appendChild(_c);
+               var _mmu = window.location;
+               if (UFO.uaHas("xml") && UFO.uaHas("safari")) {
+                       var _mmd = document.getElementsByTagName("title")[0].firstChild.nodeValue = document.getElementsByTagName("title")[0].firstChild.nodeValue.slice(0, 47) + " - Flash Player Installation";
+               }
+               else {
+                       var _mmd = document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+               }
+               var _mmp = UFO.pluginType == "ax" ? "ActiveX" : "PlugIn";
+               var _uc = typeof _fo.xiurlcancel != "undefined" ? "&xiUrlCancel=" + _fo.xiurlcancel : "";
+               var _uf = typeof _fo.xiurlfailed != "undefined" ? "&xiUrlFailed=" + _fo.xiurlfailed : "";
+               UFO.foList["xi-dia"] = { movie:_fo.ximovie, width:_fo.xiwidth, height:_fo.xiheight, majorversion:"6", build:"65", flashvars:"MMredirectURL=" + _mmu + "&MMplayerType=" + _mmp + "&MMdoctitle=" + _mmd + _uc + _uf };
+               UFO.writeSWF("xi-dia");
+       },
+
+       expressInstallCallback: function() {
+               var _b = document.getElementsByTagName("body")[0];
+               var _c = document.getElementById("xi-con");
+               _b.removeChild(_c);
+               UFO.createCSS("body", "height:auto; overflow:auto;");
+               UFO.createCSS("html", "height:auto; overflow:auto;");
+       },
+
+       cleanupIELeaks: function() {
+               var _o = document.getElementsByTagName("object");
+               var _l = _o.length
+               for (var i = 0; i < _l; i++) {
+                       _o[i].style.display = "none";
+                       for (var x in _o[i]) {
+                               if (typeof _o[i][x] == "function") {
+                                       _o[i][x] = null;
+                               }
+                       }
+               }
+       }
+
+};
+
+if (typeof window.attachEvent != "undefined" && UFO.uaHas("ieWin")) {
+       window.attachEvent("onunload", UFO.cleanupIELeaks);
+}