]> git.parisson.com Git - telemeta.git/commitdiff
eztelemeta: bundle SoundManager2 v294a-20090206
authorolivier <>
Fri, 10 Apr 2009 14:32:40 +0000 (14:32 +0000)
committerolivier <>
Fri, 10 Apr 2009 14:32:40 +0000 (14:32 +0000)
tools/eztelemeta/datatypes/eztelemetaitem/eztelemetaitemtype.php
tools/eztelemeta/design/standard/javascript/init.js [new file with mode: 0644]
tools/eztelemeta/design/standard/javascript/page-player.js [new file with mode: 0644]
tools/eztelemeta/design/standard/javascript/soundmanager2-nodebug-jsmin.js [new file with mode: 0644]
tools/eztelemeta/design/standard/javascript/soundmanager2.js [new file with mode: 0644]
tools/eztelemeta/design/standard/stylesheets/page-player.css [new file with mode: 0644]
tools/eztelemeta/design/standard/swf/soundmanager2.swf [new file with mode: 0644]
tools/eztelemeta/design/standard/swf/soundmanager2_flash9.swf [new file with mode: 0644]
tools/eztelemeta/settings/design.ini.append

index 3cfb8642d3e1ed68187eb0fbaa8acf617e7809eb..089e1bf106364a794ba896b4c44f22ca15758d20 100755 (executable)
@@ -8,7 +8,6 @@
  * @license     CeCILL Free Software License Agreement
  */
 
-
 /**
  * Class definining the Telemeta Item datatype
  *
@@ -31,8 +30,8 @@ class eZTelemetaItemType extends eZDataType
         $idvar   = "{$base}_itemid_" . $attribute->attribute('id');
         $urlvar  = "{$base}_url_" . $attribute->attribute('id');
         if ($http->hasPostVariable($idvar)) {
-            $itemId = trim($http->postVariable($idvar));
-            $url    = trim($http->postVariable($urlvar));
+            $itemId         = trim($http->postVariable($idvar));
+            $url            = trim($http->postVariable($urlvar));
             $classAttribute = $attribute->contentClassAttribute();
             if ($classAttribute->attribute("is_required")) {
                 if (!$itemId) {
@@ -151,9 +150,9 @@ class eZTelemetaItemType extends eZDataType
     function metaData($attribute)
     {
         $data = unserialize($attribute->attribute("data_text"));
-        $words = array();
-        $src = $data['title'] . ' ' . $data['description'];
-        $cut = split('[ =+()[{}_,.:;\\/"\'*#%!?&-]+', $src);
+        $words  = array();
+        $src    = $data['title'] . ' ' . $data['description'];
+        $cut    = split('[ =+()[{}_,.:;\\/"\'*#%!?&-]+', $src);
         foreach ($cut as $w) {
             if (strlen($w) >= 3) {
                 $words[] = $w;
diff --git a/tools/eztelemeta/design/standard/javascript/init.js b/tools/eztelemeta/design/standard/javascript/init.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/eztelemeta/design/standard/javascript/page-player.js b/tools/eztelemeta/design/standard/javascript/page-player.js
new file mode 100644 (file)
index 0000000..fee5449
--- /dev/null
@@ -0,0 +1,1014 @@
+/*\r
+\r
+  SoundManager 2 Demo: "Page as playlist"\r
+  ----------------------------------------------\r
+  http://schillmania.com/projects/soundmanager2/\r
+\r
+  An example of a Muxtape.com-style UI, where an\r
+  unordered list of MP3 links becomes a playlist\r
+\r
+  Flash 9 "MovieStar" edition supports MPEG4\r
+  audio and video as well.\r
+\r
+  Requires SoundManager 2 Javascript API.\r
+\r
+*/\r
+\r
+function PagePlayer(oConfigOverride) {\r
+  var self = this;\r
+  var pl = this;\r
+  var sm = soundManager; // soundManager instance\r
+  // sniffing for favicon stuff/IE workarounds\r
+  var isIE = navigator.userAgent.match(/msie/i);\r
+  var isOpera = navigator.userAgent.match(/opera/i);\r
+  var isFirefox = navigator.userAgent.match(/firefox/i);\r
+\r
+  sm.url = '../../swf/'; // path to directory containing SM2 SWF\r
+\r
+  this.config = {\r
+    flashVersion: 8,        // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.\r
+    usePeakData: false,     // [Flash 9 only]: show peak data\r
+    useWaveformData: false, // [Flash 9 only]: enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire.\r
+    useEQData: false,       // [Flash 9 only]: enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive.\r
+    fillGraph: false,       // [Flash 9 only]: draw full lines instead of only top (peak) spectrum points\r
+    allowRightClick:true,   // let users right-click MP3 links ("save as...", etc.) or discourage (can't prevent.)\r
+    useThrottling: false,   // try to rate-limit potentially-expensive calls (eg. dragging position around)\r
+    autoStart: false,       // begin playing first sound when page loads\r
+    playNext: true,         // stop after one sound, or play through list until end\r
+    updatePageTitle: true,  // change the page title while playing sounds\r
+    emptyTime: '-:--',      // null/undefined timer values (before data is available)\r
+    useFavIcon: false       // try to show peakData in address bar (Firefox + Opera)\r
+  }\r
+\r
+  sm.debugMode = (window.location.href.toString().match(/debug=1/i)?true:false); // enable with #debug=1 for example\r
+\r
+  this._mergeObjects = function(oMain,oAdd) {\r
+    // non-destructive merge\r
+    var o1 = {}; // clone o1\r
+    for (var i in oMain) {\r
+      o1[i] = oMain[i];\r
+    }\r
+    var o2 = (typeof oAdd == 'undefined'?{}:oAdd);\r
+    for (var o in o2) {\r
+      if (typeof o1[o] == 'undefined') o1[o] = o2[o];\r
+    }\r
+    return o1;\r
+  }\r
+\r
+  if (typeof oConfigOverride != 'undefined' && oConfigOverride) {\r
+    // allow overriding via arguments object\r
+    this.config = this._mergeObjects(oConfigOverride,this.config);\r
+  }\r
+\r
+  this.css = {             // CSS class names appended to link during various states\r
+    sDefault: 'sm2_link',  // default state\r
+    sLoading: 'sm2_loading',\r
+    sPlaying: 'sm2_playing',\r
+    sPaused: 'sm2_paused'\r
+  }\r
+\r
+  // apply externally-defined override, if applicable\r
+  this.cssBase = []; // optional features added to ul.playlist\r
+  if (this.config.usePeakData) this.cssBase.push('use-peak');\r
+  if (this.config.useWaveformData || this.config.useEQData) this.cssBase.push('use-spectrum');\r
+  this.cssBase = this.cssBase.join(' ');\r
+\r
+  // apply some items to SM2\r
+  sm.flashVersion = this.config.flashVersion;\r
+  if (sm.flashVersion >= 9) {\r
+    sm.useMovieStar = this.config.useMovieStar; // enable playing FLV, MP4 etc.\r
+    sm.movieStarOptions.useVideo = this.config.useVideo;\r
+    sm.defaultOptions.usePeakData = this.config.usePeakData;\r
+    sm.defaultOptions.useWaveformData = this.config.useWaveformData;\r
+    sm.defaultOptions.useEQData = this.config.useEQData;\r
+  }\r
+\r
+  this.links = [];\r
+  this.sounds = [];\r
+  this.soundsByObject = [];\r
+  this.lastSound = null;\r
+  this.soundCount = 0;\r
+  this.strings = [];\r
+  this.dragActive = false;\r
+  this.dragExec = new Date();\r
+  this.dragTimer = null;\r
+  this.pageTitle = document.title;\r
+  this.lastWPExec = new Date();\r
+  this.xbmImages = [];\r
+  this.oControls = null;\r
+\r
+  this.addEventHandler = function(o,evtName,evtHandler) {\r
+    typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);\r
+  }\r
+\r
+  this.removeEventHandler = function(o,evtName,evtHandler) {\r
+    typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);\r
+  }\r
+\r
+  this.hasClass = function(o,cStr) {\r
+    return (typeof(o.className)!='undefined'?new RegExp('(^|\\s)'+cStr+'(\\s|$)').test(o.className):false);\r
+  }\r
+\r
+  this.addClass = function(o,cStr) {\r
+    if (!o || !cStr) return false; // safety net\r
+    if (self.hasClass(o,cStr)) return false;\r
+    o.className = (o.className?o.className+' ':'')+cStr;\r
+  }\r
+\r
+  this.removeClass = function(o,cStr) {\r
+    if (!o || !cStr) return false; // safety net\r
+    if (!self.hasClass(o,cStr)) return false;\r
+    o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');\r
+  }\r
+\r
+  this.getElementsByClassName = function(className,tagNames,oParent) {\r
+    var doc = (oParent||document);\r
+    var matches = [];\r
+    var i,j;\r
+    var nodes = [];\r
+    if (typeof(tagNames)!='undefined' && typeof(tagNames)!='string') {\r
+      for (i=tagNames.length; i--;) {\r
+        if (!nodes || !nodes[tagNames[i]]) {\r
+          nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);\r
+        }\r
+      }\r
+    } else if (tagNames) {\r
+      nodes = doc.getElementsByTagName(tagNames);\r
+    } else {\r
+      nodes = doc.all||doc.getElementsByTagName('*');\r
+    }\r
+    if (typeof(tagNames)!='string') {\r
+      for (i=tagNames.length; i--;) {\r
+        for (j=nodes[tagNames[i]].length; j--;) {\r
+          if (self.hasClass(nodes[tagNames[i]][j],className)) {\r
+            matches[matches.length] = nodes[tagNames[i]][j];\r
+          }\r
+        }\r
+      }\r
+    } else {\r
+      for (i=0; i<nodes.length; i++) {\r
+        if (self.hasClass(nodes[i],className)) {\r
+          matches[matches.length] = nodes[i];\r
+        }\r
+      }\r
+    }\r
+    return matches;\r
+  }\r
+  \r
+  this.getOffX = function(o) {\r
+    // http://www.xs4all.nl/~ppk/js/findpos.html\r
+    var curleft = 0;\r
+    if (o.offsetParent) {\r
+      while (o.offsetParent) {\r
+        curleft += o.offsetLeft;\r
+        o = o.offsetParent;\r
+      }\r
+    }\r
+    else if (o.x) curleft += o.x;\r
+    return curleft;\r
+  }\r
+\r
+  this.isChildOfClass = function(oChild,oClass) {\r
+    if (!oChild || !oClass) return false;\r
+    while (oChild.parentNode && !self.hasClass(oChild,oClass)) {\r
+      oChild = oChild.parentNode;\r
+    }\r
+    return (self.hasClass(oChild,oClass));\r
+  }\r
+\r
+  this.getParentByNodeName = function(oChild,sParentNodeName) {\r
+    if (!oChild || !sParentNodeName) return false;\r
+    sParentNodeName = sParentNodeName.toLowerCase();\r
+    while (oChild.parentNode && sParentNodeName != oChild.parentNode.nodeName.toLowerCase()) {\r
+      oChild = oChild.parentNode;\r
+    }\r
+    return (oChild.parentNode && sParentNodeName == oChild.parentNode.nodeName.toLowerCase()?oChild.parentNode:null);\r
+  }\r
+  \r
+  this.getTime = function(nMSec,bAsString) {\r
+    // convert milliseconds to mm:ss, return as object literal or string\r
+    var nSec = Math.floor(nMSec/1000);\r
+    var min = Math.floor(nSec/60);\r
+    var sec = nSec-(min*60);\r
+    // if (min == 0 && sec == 0) return null; // return 0:00 as null\r
+    return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});\r
+  }\r
+\r
+  this.getSoundByObject = function(o) {\r
+    return (typeof self.soundsByObject[o.rel] != 'undefined'?self.soundsByObject[o.rel]:null);\r
+  }\r
+\r
+  this.getSoundIndex = function(o) {\r
+    for (var i=self.links.length; i--;) {\r
+      if (self.links[i].rel == o.rel) return i;\r
+    }\r
+    return -1;\r
+  }\r
+\r
+  this.setPageTitle = function(sTitle) {\r
+    if (!self.config.updatePageTitle) return false;\r
+    try {\r
+      document.title = (sTitle?sTitle+' - ':'')+self.pageTitle;\r
+    } catch(e) {\r
+      // oh well\r
+      self.setPageTitle = function() {return false;}\r
+    }\r
+  }\r
+\r
+  this.events = {\r
+\r
+    // handlers for sound events as they're started/stopped/played\r
+\r
+    play: function() {\r
+      pl.removeClass(this._data.oLI,this._data.className);\r
+      this._data.className = pl.css.sPlaying;\r
+      pl.addClass(this._data.oLI,this._data.className);\r
+      self.setPageTitle(this._data.originalTitle);\r
+    },\r
+\r
+    stop: function() {\r
+      pl.removeClass(this._data.oLI,this._data.className);\r
+      this._data.className = '';\r
+      this._data.oPosition.style.width = '0px';\r
+      self.setPageTitle();\r
+      self.resetPageIcon();\r
+    },\r
+\r
+    pause: function() {\r
+      if (pl.dragActive) return false;\r
+      pl.removeClass(this._data.oLI,this._data.className);\r
+      this._data.className = pl.css.sPaused;\r
+      pl.addClass(this._data.oLI,this._data.className);\r
+      self.setPageTitle();\r
+      self.resetPageIcon();\r
+    },\r
+\r
+    resume: function() {\r
+      if (pl.dragActive) return false;\r
+      pl.removeClass(this._data.oLI,this._data.className);\r
+      this._data.className = pl.css.sPlaying;\r
+      pl.addClass(this._data.oLI,this._data.className);\r
+    },\r
+\r
+    finish: function() {\r
+      pl.removeClass(this._data.oLI,this._data.className);\r
+      this._data.className = '';\r
+      this._data.oPosition.style.width = '0px';\r
+      // play next if applicable\r
+      if (self.config.playNext && this._data.nIndex<pl.links.length-1) {\r
+        pl.handleClick({target:pl.links[this._data.nIndex+1]}); // fake a click event - aren't we sneaky. ;)\r
+      } else {\r
+        self.setPageTitle();\r
+        self.resetPageIcon();\r
+      }\r
+    },\r
+\r
+    whileloading: function() {\r
+      this._data.oLoading.style.width = (((this.bytesLoaded/this.bytesTotal)*100)+'%'); // theoretically, this should work.\r
+      if (!this._data.didRefresh && this._data.metadata) {\r
+        this._data.didRefresh = true;\r
+        this._data.metadata.refresh();\r
+      }\r
+    },\r
+\r
+    onload: function() {\r
+      if (!this.loaded) {\r
+               var oTemp = this._data.oLI.getElementsByTagName('a')[0];\r
+               var oString = oTemp.innerHTML;\r
+               var oThis = this;\r
+               oTemp.innerHTML = oString+' <span style="font-size:0.5em"> | Load failed, d\'oh! '+(sm.sandbox.noRemote?' Possible cause: Flash sandbox is denying remote URL access.':(sm.sandbox.noLocal?'Flash denying local filesystem access':'404?'))+'</span>';\r
+               setTimeout(function(){\r
+                 oTemp.innerHTML = oString;\r
+                 // pl.events.finish.apply(oThis); // load next\r
+               },5000);\r
+         } else {\r
+        if (this._data.metadata) {\r
+          this._data.metadata.refresh();\r
+        }\r
+      }\r
+    },\r
+\r
+       metadata: function() {\r
+         // video-only stuff\r
+         sm._wD('video metadata: '+this.width+'x'+this.height);\r
+      // set the SWF dimensions to match\r
+         sm.oMC.style.width = this.width+'px'; \r
+         sm.oMC.style.height = this.height+'px';\r
+       },\r
+\r
+    whileplaying: function() {\r
+      var d = null;\r
+      if (pl.dragActive || !pl.config.useThrottling) {\r
+        self.updateTime.apply(this);\r
+           if (sm.flashVersion >= 9) {\r
+          if (pl.config.usePeakData && this.instanceOptions.usePeakData) self.updatePeaks.apply(this);\r
+             if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {\r
+               self.updateGraph.apply(this);\r
+             }\r
+           }\r
+        if (this._data.metadata) {\r
+          d = new Date();\r
+          if (d && d-self.lastWPExec>500) {\r
+            self.refreshMetadata(this);\r
+            self.lastWPExec = d;\r
+          }\r
+        }\r
+        this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');\r
+      } else {\r
+        d = new Date();\r
+        if (d-self.lastWPExec>500) {\r
+          self.updateTime.apply(this);\r
+             if (sm.flashVersion >= 9) {\r
+            if (pl.config.usePeakData && this.instanceOptions.usePeakData) {\r
+                 self.updatePeaks.apply(this);\r
+               }\r
+               if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {\r
+                     self.updateGraph.apply(this);\r
+                       }\r
+          }\r
+          if (this._data.metadata) self.refreshMetadata(this);\r
+          this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');\r
+          self.lastWPExec = d;\r
+        }\r
+      }\r
+    }\r
+       \r
+  } // events{}\r
+\r
+  this.setPageIcon = function(sDataURL) {\r
+       if (!self.config.useFavIcon || !self.config.usePeakData || !sDataURL) return false;\r
+    var link = document.getElementById('favicon');\r
+    if (!link) {\r
+         link = document.createElement('link');\r
+         link.id = 'favicon';\r
+         link.rel = 'shortcut icon';\r
+         link.type = 'image/x-bitmap';\r
+         link.href = sDataURL;\r
+       } else {\r
+      link.href = sDataURL;\r
+    }\r
+    document.getElementsByTagName('head')[0].appendChild(link);\r
+  }\r
+\r
+  this.resetPageIcon = function() {\r
+       if (!self.config.useFavIcon) return false;\r
+    var link = document.getElementById('favicon');\r
+    if (link) {\r
+         link.href = '/favicon.ico';\r
+    }\r
+  }\r
+\r
+  this.updatePeaks = function() {\r
+    var o = this._data.oPeak;\r
+    var oSpan = o.getElementsByTagName('span');\r
+    oSpan[0].style.marginTop = (13-(Math.floor(15*this.peakData.left))+'px');\r
+    oSpan[1].style.marginTop = (13-(Math.floor(15*this.peakData.right))+'px');\r
+       // highly experimental\r
+    if (self.config.flashVersion > 8 && self.config.useFavIcon && self.config.usePeakData) {\r
+         if (!isOpera) {\r
+           self.setPageIcon(self.xbmImages[parseInt(15*this.peakData.left)][parseInt(15*this.peakData.right)]);\r
+         } else {\r
+       self.setPageIcon(self.xbmImages[1+parseInt(14*this.peakData.left)][1+parseInt(14*this.peakData.right)]);\r
+         }\r
+       }\r
+  }\r
+  \r
+  this.updateGraph = function() {\r
+    if ((!pl.config.useWaveformData && !pl.config.useEQData) || pl.config.flashVersion<9) return false;\r
+    var sbC = this._data.oGraph.getElementsByTagName('div');\r
+    if (pl.config.useWaveformData) {\r
+      // raw waveform\r
+      var scale = 8; // Y axis (+/- this distance from 0)\r
+      for (var i=255; i--;) {\r
+        sbC[255-i].style.marginTop = (1+scale+Math.ceil(this.waveformData[i]*-scale))+'px';\r
+      }\r
+    } else {\r
+         // eq spectrum\r
+      var offset = 9;\r
+      for (var i=255; i--;) {\r
+        sbC[255-i].style.marginTop = ((offset*2)-1+Math.ceil(this.eqData[i]*-offset))+'px';\r
+      }\r
+    }\r
+  }\r
+  \r
+  this.resetGraph = function() {\r
+    if (!pl.config.useEQData || pl.config.flashVersion<9) return false;\r
+    var sbC = this._data.oGraph.getElementsByTagName('div');\r
+    var scale = (!pl.config.useEQData?'9px':'17px');\r
+    var nHeight = (!pl.config.fillGraph?'1px':'32px');\r
+    for (var i=255; i--;) {\r
+      sbC[255-i].style.marginTop = scale; // EQ scale\r
+      sbC[255-i].style.height = nHeight;\r
+    }\r
+  }\r
+\r
+  this.refreshMetadata = function(oSound) {\r
+    // Display info as appropriate\r
+    var index = null;\r
+    var now = oSound.position;\r
+    var metadata = oSound._data.metadata.data;\r
+    for (var i=0, j=metadata.length; i<j; i++) {\r
+      if (now >= metadata[i].startTimeMS && now <= metadata[i].endTimeMS) {\r
+        index = i;\r
+        break;\r
+      }\r
+    }\r
+    if (index != metadata.currentItem) {\r
+      // update\r
+      oSound._data.oLink.innerHTML = metadata.mainTitle+' <span class="metadata"><span class="sm2_divider"> | </span><span class="sm2_metadata">'+metadata[index].title+'</span></span>';\r
+      self.setPageTitle(metadata[index].title+' | '+metadata.mainTitle);\r
+      metadata.currentItem = index;\r
+    }\r
+  }\r
+  \r
+  this.updateTime = function() {\r
+    var str = self.strings['timing'].replace('%s1',self.getTime(this.position,true));\r
+    str = str.replace('%s2',self.getTime(self.getDurationEstimate(this),true));\r
+    this._data.oTiming.innerHTML = str;\r
+  }\r
+\r
+  this.getTheDamnTarget = function(e) {\r
+    return (e.target||e.srcElement||window.event.srcElement);\r
+  }\r
+  \r
+  this.withinStatusBar = function(o) {\r
+    return (self.isChildOfClass(o,'controls'));\r
+  }\r
+\r
+  this.handleClick = function(e) {\r
+    // a sound (or something) was clicked - determine what and handle appropriately\r
+    if (e.button == 2) {\r
+      if (!pl.config.allowRightClick) pl.stopEvent(e);\r
+      return (pl.config.allowRightClick); // ignore right-clicks\r
+    }\r
+    var o = self.getTheDamnTarget(e);\r
+    if (self.dragActive) self.stopDrag(); // to be safe\r
+    if (self.withinStatusBar(o)) {\r
+      // self.handleStatusClick(e);\r
+      return false;\r
+    }\r
+    if (o.nodeName.toLowerCase() != 'a') {\r
+      o = self.getParentByNodeName(o,'a');\r
+    }\r
+    if (!o) {\r
+      // not a link\r
+      return true;\r
+    }\r
+    var sURL = o.getAttribute('href');\r
+    if (!o.href || (!sm.canPlayURL(o.href) && !self.hasClass(o,'playable')) || self.hasClass(o,'exclude')) {\r
+      if (isIE && o.onclick) {\r
+        return false; // IE will run this handler before .onclick(), everyone else is cool?\r
+      }\r
+      return true; // pass-thru for non-MP3/non-links\r
+    }\r
+    var soundURL = o.href;\r
+    var thisSound = self.getSoundByObject(o);\r
+    if (thisSound) {\r
+      // sound already exists\r
+      self.setPageTitle(thisSound._data.originalTitle);\r
+      if (thisSound == self.lastSound) {\r
+        // ..and was playing (or paused) and isn't in an error state\r
+               if (thisSound.readyState != 2) {\r
+                 if (thisSound.playState != 1) {\r
+                       // not yet playing\r
+                       thisSound.play();\r
+                 } else {\r
+            thisSound.togglePause();\r
+          }\r
+               } else {\r
+                 sm._writeDebug('Warning: sound failed to load (security restrictions, 404 or bad format)',2);\r
+               }\r
+      } else {\r
+        // ..different sound\r
+        if (self.lastSound) self.stopSound(self.lastSound);\r
+        thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));\r
+        thisSound.togglePause(); // start playing current\r
+      }\r
+    } else {\r
+      // create sound\r
+      thisSound = sm.createSound({\r
+        id:'pagePlayerMP3Sound'+(self.soundCount++),\r
+        url:soundURL,\r
+        onplay:self.events.play,\r
+        onstop:self.events.stop,\r
+        onpause:self.events.pause,\r
+        onresume:self.events.resume,\r
+        onfinish:self.events.finish,\r
+        whileloading:self.events.whileloading,\r
+        whileplaying:self.events.whileplaying,\r
+               onmetadata:self.events.metadata,\r
+        onload:self.events.onload\r
+      });\r
+      // append control template\r
+      var oControls = self.oControls.cloneNode(true);\r
+      o.parentNode.appendChild(oControls);\r
+      o.parentNode.appendChild(document.getElementById('spectrum-container'));\r
+      self.soundsByObject[o.rel] = thisSound;\r
+      // tack on some custom data\r
+      thisSound._data = {\r
+        oLink: o, // DOM reference within SM2 object event handlers\r
+        oLI: o.parentNode,\r
+        oControls: self.getElementsByClassName('controls','div',o.parentNode)[0],\r
+        oStatus: self.getElementsByClassName('statusbar','div',o.parentNode)[0],\r
+        oLoading: self.getElementsByClassName('loading','div',o.parentNode)[0],\r
+        oPosition: self.getElementsByClassName('position','div',o.parentNode)[0],\r
+        oTimingBox: self.getElementsByClassName('timing','div',o.parentNode)[0],\r
+        oTiming: self.getElementsByClassName('timing','div',o.parentNode)[0].getElementsByTagName('div')[0],\r
+        oPeak: self.getElementsByClassName('peak','div',o.parentNode)[0],\r
+        oGraph: self.getElementsByClassName('spectrum-box','div',o.parentNode)[0],\r
+        nIndex: self.getSoundIndex(o),\r
+        className: self.css.sPlaying,\r
+        originalTitle: o.innerHTML,\r
+        metadata: null\r
+      };\r
+      thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));\r
+      // "Metadata"\r
+      if (thisSound._data.oLI.getElementsByTagName('ul').length) {\r
+        thisSound._data.metadata = new Metadata(thisSound);\r
+      }\r
+      // set initial timer stuff (before loading)\r
+      var str = self.strings['timing'].replace('%s1',self.config.emptyTime);\r
+      str = str.replace('%s2',self.config.emptyTime);\r
+      thisSound._data.oTiming.innerHTML = str;\r
+      self.sounds.push(thisSound);\r
+      if (self.lastSound) self.stopSound(self.lastSound);\r
+      self.resetGraph.apply(thisSound);\r
+      thisSound.play();\r
+    }\r
+    self.lastSound = thisSound; // reference for next call\r
+    return self.stopEvent(e);\r
+  }\r
+  \r
+  this.handleMouseDown = function(e) {\r
+    // a sound link was clicked\r
+    if (e.button == 2) {\r
+      if (!pl.config.allowRightClick) pl.stopEvent(e);\r
+      return (pl.config.allowRightClick); // ignore right-clicks\r
+    }\r
+    var o = self.getTheDamnTarget(e);\r
+    if (!self.withinStatusBar(o)) return true;\r
+    self.dragActive = true;\r
+    self.lastSound.pause();\r
+    self.setPosition(e);\r
+    self.addEventHandler(document,'mousemove',self.handleMouseMove);\r
+    self.addClass(self.lastSound._data.oControls,'dragging');\r
+    self.stopEvent(e);\r
+    return false;\r
+  }\r
+  \r
+  this.handleMouseMove = function(e) {\r
+    // set position accordingly\r
+    if (self.dragActive) {\r
+      if (self.config.useThrottling) {\r
+        // be nice to CPU/externalInterface\r
+        var d = new Date();\r
+        if (d-self.dragExec>20) {\r
+          self.setPosition(e);\r
+        } else {\r
+          window.clearTimeout(self.dragTimer);\r
+          self.dragTimer = window.setTimeout(function(){self.setPosition(e)},20);\r
+        }\r
+        self.dragExec = d;\r
+      } else {\r
+        // oh the hell with it\r
+        self.setPosition(e);\r
+      }\r
+    } else {\r
+      self.stopDrag();\r
+    }\r
+       return false;\r
+  }\r
+  \r
+  this.stopDrag = function(e) {\r
+    if (self.dragActive) {\r
+      self.removeClass(self.lastSound._data.oControls,'dragging');\r
+      self.removeEventHandler(document,'mousemove',self.handleMouseMove);\r
+      // self.removeEventHandler(document,'mouseup',self.stopDrag);\r
+      if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) {\r
+        self.lastSound.resume();\r
+      }\r
+      self.dragActive = false;\r
+      self.stopEvent(e);\r
+      return false;\r
+    }\r
+  }\r
+  \r
+  this.handleStatusClick = function(e) {\r
+    self.setPosition(e);\r
+    if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) self.resume();\r
+    return self.stopEvent(e);\r
+  }\r
+  \r
+  this.stopEvent = function(e) {\r
+   if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {\r
+      e.preventDefault();\r
+    } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {\r
+      event.returnValue = false;\r
+    }\r
+    return false;\r
+  }\r
\r
+  this.setPosition = function(e) {\r
+    // called from slider control\r
+    var oThis = self.getTheDamnTarget(e);\r
+    var oControl = oThis;\r
+    while (!self.hasClass(oControl,'controls') && oControl.parentNode) {\r
+      oControl = oControl.parentNode;\r
+    }\r
+    var oSound = self.lastSound;\r
+    var x = parseInt(e.clientX);\r
+    // play sound at this position\r
+    var nMsecOffset = Math.floor((x-self.getOffX(oControl)-4)/(oControl.offsetWidth)*self.getDurationEstimate(oSound));\r
+    if (!isNaN(nMsecOffset)) nMsecOffset = Math.min(nMsecOffset,oSound.duration);\r
+    if (!isNaN(nMsecOffset)) oSound.setPosition(nMsecOffset);\r
+  }\r
+\r
+  this.stopSound = function(oSound) {\r
+    sm._writeDebug('stopping sound: '+oSound.sID);\r
+    sm.stop(oSound.sID);\r
+    sm.unload(oSound.sID);\r
+  }\r
+\r
+  this.getDurationEstimate = function(oSound) {\r
+    if (oSound.instanceOptions.isMovieStar) {\r
+         return (oSound.duration);\r
+    } else {\r
+      return (!oSound._data.metadata || !oSound._data.metadata.data.givenDuration?oSound.durationEstimate:oSound._data.metadata.data.givenDuration);\r
+    }\r
+  }\r
+\r
+  // XBM support\r
+\r
+       // xbmDraw.js XBM drawing library\r
+       // (c)2002 David L. Blackledge\r
+       // http://David.Blackledge.com\r
+       // Written April, 2002\r
+       // You may use this if you keep this copyright notice intact\r
+       //\r
+       // See http://David.Blackledge.com/XBMDrawLibrary.html\r
+       // Some unused functions removed, see site for complete library\r
+\r
+       function array_copy(o_array) {\r
+        var ret_array = new Array();\r
+        if(typeof(ret_array.concat) == "function")\r
+         return ret_array.concat(o_array);\r
+        for(var j = 0 ; j < o_array.length ; ++j) {\r
+         ret_array[ret_array.length] = o_array[j];\r
+        }\r
+        return ret_array;\r
+       }\r
+\r
+       function XBMImage_body() {\r
+        var bod = "";\r
+        for(var i = 0 ; i < this.height ; ++i) {\r
+         for(var j = 0 ; j < this.width/8 ; ++j) {\r
+          if(typeof(this.data[i]) != "undefined" && typeof(this.data[i][j]) != "undefined") {\r
+           // must be reversed to work right, apparently.\r
+           var bool = 0;\r
+           bool = this.data[i][j];\r
+           var hex = (new Number(bool)).toString(16);\r
+           if(hex.length == 1)\r
+            hex = "0"+hex;\r
+           bod += "0x"+hex+",";\r
+          } else {\r
+           bod += "0x00,";\r
+          }\r
+         }\r
+        }\r
+        if(bod.length > 0) // remove trailing comma\r
+         bod = bod.substring(0,bod.length-1);\r
+        return bod;\r
+       }\r
+\r
+       function XBMImage_draw(x,y) {\r
+        if(!(x > -1 && x < this.width && y > -1 && y < this.height))\r
+         return;\r
+        if(typeof(this.data[y]) == "undefined")\r
+          this.data[y] = new Array();\r
+        var bit = x%8;\r
+        var byt = (x-bit)/8;\r
+        if(typeof(this.data[y][byt]) == "undefined")\r
+          this.data[y][byt] = 0;\r
+        this.data[y][byt] |= (0x01<<bit);\r
+       }\r
+\r
+       // attempt to do a fast horizontal line algorithm.\r
+       function XBMImage_drawHLine(x1,y1,x2) {\r
+        if(!(y1 > -1 && y1 < this.height))\r
+         return;\r
+        if(x1 > x2){\r
+         var xs = x1;x1=Math.max(0,x2);x2=Math.min(this.width,xs);\r
+        }\r
+        var filled = 0xFF;\r
+        var startbits = x1%8;\r
+        var startbyt = (x1-x1%8)/8;\r
+        var endbits = 8-x2%8;\r
+        var endbyt = (x2-x2%8)/8;\r
+        if(startbyt == endbyt) {\r
+         this.data[y1][startbyt]|=(filled <<startbits)&(filled>>endbits);\r
+         return;\r
+        }\r
+        for(var i = startbyt+1 ; i < endbyt ; ++i) {\r
+         this.data[y1][i] = filled;\r
+        }\r
+        for(var j=x1; j < (x1+(8-x1%8)) ; ++j)\r
+         this.draw(j,y1);\r
+        this.data[y1][endbyt] |= (filled >>endbits);\r
+       }\r
+       \r
+       function XBMImage_drawVLine(x1,y1,y2) {\r
+        if(!(x1 > -1 && x1 < this.width))\r
+         return;\r
+        if(y1 > y2){\r
+         var ys = y1;y1=Math.max(0,y2);y2=Math.min(this.height,ys);\r
+        }\r
+        var bit = x1%8;\r
+        var byt = (x1-bit)/8;\r
+        var bitmask = (0x01<<bit);\r
+        for(var y = y1 ; y <= y2 ; ++y)\r
+         this.data[y][byt] |= bitmask;\r
+       }\r
+       \r
+       function XBMImage_drawLine(x1,y1,x2,y2) {\r
+        if(x1 > x2) {\r
+         var xx = x1; x1 = x2; x2 = xx;\r
+         var yy = y1; y1 = y2; y2 = yy;\r
+        }\r
+        var y = y1;\r
+        if(y1 == y2)\r
+          if(x1 == x2)\r
+                return this.draw(x1,y1);\r
+          else\r
+                return this.drawHLine(x1,y1,x2);\r
+        if(x1 == x2) return this.drawVLine(x1,y1,y2);\r
+        var slope=(y1-y2)/(x1-x2);\r
+        var yint = y1-Math.floor(slope*x1); // y-intercept\r
+        for(var x = x1; x < x2; ++x) {\r
+         if(slope > 0) { //y1<y2 (top to bottom)\r
+          for(y = Math.floor(slope*x)+yint ; y < (Math.floor(slope*(x+1))+yint) ; ++y) {\r
+           this.draw(x,y);\r
+          }\r
+          if(Math.floor(slope*x) == Math.floor(slope*(x+1)))\r
+           this.draw(x,y);\r
+          if(x==x2-1) {\r
+           for(y ; y <= y2 ; ++y) {\r
+            this.draw(x,y);\r
+           }  \r
+          }\r
+         } else { //y1>y2 (bottom to top)\r
+          for(y = Math.floor(slope*x)+yint ; y > (Math.floor(slope*(x+1))+yint) ; --y) {\r
+           this.draw(x,y);\r
+          }\r
+          if(Math.floor(slope*x) == Math.floor(slope*(x+1)))\r
+           this.draw(x,y);\r
+          if(x==x2-1) {\r
+           for(y ; y >= y2 ; --y) {\r
+            this.draw(x,y);\r
+           }  \r
+          }\r
+         }\r
+        }\r
+        return null;\r
+       }\r
+\r
+       function XBMImage_drawBoxFilled(x1,y1,x2,y2) {\r
+        for(var y = y1; y <= y2; ++y)\r
+         this.drawHLine(x1,y,x2);\r
+       }\r
+\r
+       function XBMImage_getXBM() {\r
+        return this.header + this.body() + this.footer;\r
+       }\r
+\r
+       function XBMImage_setXBM(str){\r
+        var xbmdata = str.substring(str.indexOf("{")+1,str.lastIndexOf("}"));\r
+        var a_data = xbmdata.split(",");\r
+        for(var j = 0 ; j < this.height ; ++j) {\r
+         this.data[j] = new Array();\r
+         for(var i = 0 ; i < Math.floor(this.width/8) ; ++i) {\r
+          var a_idx = i+j*(Math.floor(this.width/8));\r
+          if(a_idx < a_data.length)\r
+           this.data[j][i] = (new Number(parseInt(a_data[a_idx],16))).valueOf();//parseInt(a_data[a_idx]);\r
+         }\r
+        }\r
+       }\r
+\r
+       function XBMImage(width,height,name) {\r
+        this.name = name;\r
+        this.width = width+((width%8)>0?(8-(width%8)):0); //expand to a multiple of 8\r
+        this.height = height;\r
+        this.header = "#define "+name+"_width "+this.width+"\n"+\r
+          "#define "+name+"_height "+this.height+"\n"+\r
+          "static char "+name+"_bits[] = {\n";\r
+        this.footer = "};";\r
+        this.data = new Array(this.height);\r
+        for(var i = 0 ; i < this.data.length ; ++i) {\r
+         this.data[i] = new Array(this.width);\r
+         for(var j = 0 ; j < this.data[i].length ; ++j) {\r
+          this.data[i][j] = 0;\r
+         }\r
+        }\r
+        this.frames = new Array(); // store copies of this.data;\r
+        this.body = XBMImage_body;\r
+        this.draw = XBMImage_draw;\r
+        this.drawLine = XBMImage_drawLine;\r
+        this.drawHLine = XBMImage_drawHLine;\r
+        this.drawVLine = XBMImage_drawVLine;\r
+        this.drawBoxFilled = XBMImage_drawBoxFilled;\r
+        this.getXBM = XBMImage_getXBM;\r
+        this.setXBM = XBMImage_setXBM;\r
+        this.xbm = this.getXBM();\r
+  }\r
+\r
+  this.createXBMData = function() {\r
+    var ico = null;\r
+    var i=0;\r
+    var j=0;\r
+    for (i=0; i<16; i++) {\r
+      self.xbmImages[i] = [];\r
+    }\r
+    for (var i=0; i<16; i++) {\r
+      for (j=0; j<16; j++) {\r
+        ico = new XBMImage(16,16,'img'+i+'x'+j);\r
+        ico.drawBoxFilled(0,16-i,7,16-(i-16));\r
+        ico.drawBoxFilled(9,16-j,16,16-(j-16));\r
+        // self.xbmImages[i][j] = 'data:image/x-bitmap;base64,'+Base64.encode(ico.getXBM()); // using Base64 library\r
+        self.xbmImages[i][j] = 'data:image/x-bitmap,'+encodeURI(ico.getXBM()); // hat tip: @p01\r
+      }\r
+    }\r
+  }\r
+\r
+  if (this.config.useFavIcon) {\r
+       if (isFirefox || isOpera) {\r
+         this.createXBMData();\r
+       } else {\r
+         // browser doesn't support doing this\r
+         this.config.useFavIcon = false;\r
+       }\r
+  }\r
+\r
+  this.init = function() {\r
+    sm._writeDebug('pagePlayer.init()');\r
+    var oLinks = document.getElementsByTagName('a');\r
+    // grab all links, look for .mp3\r
+    var foundItems = 0;\r
+    for (var i=0; i<oLinks.length; i++) {\r
+      if ((sm.canPlayURL(oLinks[i].href) || self.hasClass(oLinks[i],'playable')) && !self.hasClass(oLinks[i],'exclude')) {\r
+        oLinks[i].rel = 'pagePlayerMP3Sound'+i;\r
+        self.links[self.links.length] = oLinks[i];\r
+        self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration\r
+        foundItems++;\r
+      }\r
+    }\r
+    if (foundItems>0) {\r
+      var oTiming = document.getElementById('sm2_timing');\r
+      self.strings['timing'] = oTiming.innerHTML;\r
+      oTiming.innerHTML = '';\r
+      oTiming.id = '';\r
+      self.addEventHandler(document,'click',self.handleClick);\r
+      self.addEventHandler(document,'mousedown',self.handleMouseDown);\r
+      self.addEventHandler(document,'mouseup',self.stopDrag);\r
+      self.addEventHandler(window,'unload',function(){}); // force page reload when returning here via back button (Opera tries to remember old state, etc.)\r
+    }\r
+    sm._writeDebug('pagePlayer.init(): Found '+foundItems+' relevant items.');\r
+    if (self.config.autoStart) {\r
+      pl.handleClick({target:pl.links[0]});\r
+    }\r
+  }\r
+\r
+var Metadata = function(oSound) {\r
+  var self = this;\r
+  var oLI = oSound._data.oLI;\r
+  var o = oLI.getElementsByTagName('ul')[0];\r
+  var oItems = o.getElementsByTagName('li');\r
+  var oTemplate = document.createElement('div');\r
+  oTemplate.innerHTML = '<span>&nbsp;</span>';\r
+  oTemplate.className = 'annotation';\r
+  var oTemplate2 = document.createElement('div');\r
+  oTemplate2.innerHTML = '<span>&nbsp;</span>';\r
+  oTemplate2.className = 'annotation alt';\r
+\r
+  var oTemplate3 = document.createElement('div');\r
+  oTemplate3.className = 'note';\r
+\r
+  this.totalTime = 0;\r
+  this.strToTime = function(sTime) {\r
+    var segments = sTime.split(':');\r
+    var seconds = 0;\r
+    for (var i=segments.length; i--;) {\r
+      seconds += parseInt(segments[i])*Math.pow(60,segments.length-1-i,10); // hours, minutes\r
+    }\r
+    return seconds;\r
+  }\r
+  this.data = [];\r
+  this.data.givenDuration = null;\r
+  this.data.currentItem = null;\r
+  this.data.mainTitle = oSound._data.oLink.innerHTML;\r
+  for (var i=0; i<oItems.length; i++) {\r
+    this.data[i] = {\r
+      o: null,\r
+      title: oItems[i].getElementsByTagName('p')[0].innerHTML,\r
+      startTime: oItems[i].getElementsByTagName('span')[0].innerHTML,\r
+      startSeconds: self.strToTime(oItems[i].getElementsByTagName('span')[0].innerHTML.replace(/[()]/g,'')),\r
+      duration: 0,\r
+      durationMS: null,\r
+      startTimeMS: null,\r
+      endTimeMS: null,\r
+      oNote: null\r
+    }\r
+  }\r
+  var oDuration = pl.getElementsByClassName('duration','div',oLI);\r
+  this.data.givenDuration = (oDuration.length?self.strToTime(oDuration[0].innerHTML)*1000:0);\r
+  for (i=0; i<this.data.length; i++) {\r
+    this.data[i].duration = parseInt(this.data[i+1]?this.data[i+1].startSeconds:(self.data.givenDuration?self.data.givenDuration:oSound.durationEstimate)/1000)-this.data[i].startSeconds;\r
+    this.data[i].startTimeMS = this.data[i].startSeconds*1000;\r
+    this.data[i].durationMS = this.data[i].duration*1000;\r
+    this.data[i].endTimeMS = this.data[i].startTimeMS+this.data[i].durationMS;\r
+    this.totalTime += this.data[i].duration;\r
+  }\r
+  // make stuff\r
+  this.createElements = function() {\r
+    var oFrag = document.createDocumentFragment();\r
+    var oNode = null;\r
+    var oNodeSpan = null;\r
+    var oNode2 = null;\r
+    for (var i=0; i<self.data.length; i++) {\r
+      oNode = (i%2==0?oTemplate:oTemplate2).cloneNode(true);\r
+      oNodeSpan = oNode.getElementsByTagName('span')[0];\r
+      oNode.rel = i;\r
+      self.data[i].o = oNode;\r
+      oNode2 = oTemplate3.cloneNode(true);\r
+      if (i%2==0) oNode2.className = 'note alt';\r
+      oNode2.innerHTML = this.data[i].title;\r
+      // evil old-skool event handlers, css:hover-only ideally would be nice excluding IE 6\r
+      oNode.onmouseover = self.mouseover;\r
+      oNode.onmouseout = self.mouseout;\r
+      this.data[i].oNote = oNode2;\r
+      oSound._data.oControls.appendChild(oNode2);\r
+      oFrag.appendChild(oNode);\r
+    }\r
+    self.refresh();\r
+    oSound._data.oStatus.appendChild(oFrag);\r
+  }\r
+\r
+  this.refresh = function() {\r
+    var offset = 0;\r
+    var relWidth = null;\r
+    var duration = (self.data.givenDuration?self.data.givenDuration:oSound.durationEstimate);\r
+    for (var i=0; i<self.data.length; i++) {\r
+      if (duration) {\r
+        relWidth = (((self.data[i].duration*1000)/duration)*100);\r
+        self.data[i].o.style.left = (offset?offset+'%':'-2px');\r
+        self.data[i].oNote.style.left = (offset?offset+'%':'0px');\r
+        offset += relWidth;\r
+      }\r
+    }\r
+  }\r
+\r
+  this.mouseover = function(e) {\r
+    self.data[this.rel].oNote.style.visibility = 'hidden';\r
+    self.data[this.rel].oNote.style.display = 'inline-block';\r
+    self.data[this.rel].oNote.style.marginLeft = -parseInt(self.data[this.rel].oNote.offsetWidth/2)+'px';\r
+    self.data[this.rel].oNote.style.visibility = 'visible';\r
+  }\r
+\r
+  this.mouseout = function() { \r
+    self.data[this.rel].oNote.style.display = 'none';\r
+  }\r
+\r
+  // ----\r
+\r
+  this.createElements();\r
+  this.refresh();\r
+  \r
+} // MetaData();\r
+\r
+  this.initDOM = function() {\r
+    // set up graph box stuffs\r
+    var sb = self.getElementsByClassName('spectrum-box','div',document.documentElement)[0];\r
+    if (sm.flashVersion >= 9) {\r
+      self.addClass(self.getElementsByClassName('playlist','ul',document.documentElement)[0],self.cssBase);\r
+      var sbC = sb.getElementsByTagName('div')[0];\r
+      var oF = document.createDocumentFragment();\r
+      var oClone = null;\r
+      for (var i=256; i--;) {\r
+        oClone = sbC.cloneNode(false);\r
+        oClone.style.left = (i)+'px';\r
+        oF.appendChild(oClone);\r
+      }\r
+      sb.removeChild(sbC);\r
+      sb.appendChild(oF);\r
+    }\r
+    this.oControls = document.getElementById('control-template').cloneNode(true);\r
+    this.oControls.id = '';\r
+    this.init();\r
+  }\r
+\r
+}\r
+\r
+var pagePlayer = new PagePlayer(typeof PP_CONFIG != 'undefined'?PP_CONFIG:null);\r
+\r
+soundManager.onload = function() {\r
+  // soundManager.createSound() etc. may now be called\r
+  pagePlayer.initDOM();\r
+}
\ No newline at end of file
diff --git a/tools/eztelemeta/design/standard/javascript/soundmanager2-nodebug-jsmin.js b/tools/eztelemeta/design/standard/javascript/soundmanager2-nodebug-jsmin.js
new file mode 100644 (file)
index 0000000..50b0d0a
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+   SoundManager 2: Javascript Sound for the Web\r
+   --------------------------------------------\r
+   http://schillmania.com/projects/soundmanager2/\r
+\r
+   Copyright (c) 2008, Scott Schiller. All rights reserved.\r
+   Code licensed under the BSD License:\r
+   http://schillmania.com/projects/soundmanager2/license.txt\r
+\r
+   V2.94a.20090206\r
+*/\r
+var soundManager=null;function SoundManager(b,a){this.flashVersion=8;this.debugMode=true;this.useConsole=true;this.consoleOnly=false;this.waitForWindowLoad=false;this.nullURL="null.mp3";this.allowPolling=true;this.useMovieStar=false;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashLoadTimeout=750;this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfinish:null,onbeforefinish:null,onbeforefinishtime:5000,onbeforefinishcomplete:null,onjustbeforefinish:null,onjustbeforefinishtime:200,multiShot:true,position:null,pan:0,volume:100};this.flash9Options={onbufferchange:null,isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false};this.movieStarOptions={onmetadata:null,useVideo:false};var f=null;var e=this;this.version=null;this.versionNumber="V2.94a.20090206";this.movieURL=null;this.url=null;this.altURL=null;this.swfLoaded=false;this.enabled=false;this.o=null;this.id=(a||"sm2movie");this.oMC=null;this.sounds={};this.soundIDs=[];this.muted=false;this.wmode=null;this.isIE=(navigator.userAgent.match(/MSIE/i));this.isSafari=(navigator.userAgent.match(/safari/i));this.isGecko=(navigator.userAgent.match(/gecko/i));this.debugID="soundmanager-debug";this._debugOpen=true;this._didAppend=false;this._appendSuccess=false;this._didInit=false;this._disabled=false;this._windowLoaded=false;this._hasConsole=(typeof console!="undefined"&&typeof console.log!="undefined");this._debugLevels=["log","info","warn","error"];this._defaultFlashVersion=8;this._oRemoved=null;this._oRemovedHTML=null;var g=function(h){return document.getElementById(h)};this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.netStreamTypes=["aac","flv","mov","mp4","m4v","f4v","m4a","mp4v","3gp","3g2"];this.netStreamPattern=new RegExp("\\.("+this.netStreamTypes.join("|")+")(\\?.*)?$","i");this.filePattern=null;this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local + internet access)"},description:null,noRemote:null,noLocal:null};this._setVersionInfo=function(){if(e.flashVersion!=8&&e.flashVersion!=9){alert('soundManager.flashVersion must be 8 or 9. "'+e.flashVersion+'" is invalid. Reverting to '+e._defaultFlashVersion+".");e.flashVersion=e._defaultFlashVersion}e.version=e.versionNumber+(e.flashVersion==9?" (AS3/Flash 9)":" (AS2/Flash 8)");if(e.flashVersion>8){e.defaultOptions=e._mergeObjects(e.defaultOptions,e.flash9Options);e.features.buffering=true}if(e.flashVersion>8&&e.useMovieStar){e.defaultOptions=e._mergeObjects(e.defaultOptions,e.movieStarOptions);e.filePatterns.flash9=new RegExp("\\.(mp3|"+e.netStreamTypes.join("|")+")(\\?.*)?$","i");e.features.movieStar=true}else{e.useMovieStar=false;e.features.movieStar=false}e.filePattern=e.filePatterns[(e.flashVersion!=8?"flash9":"flash8")];e.movieURL=(e.flashVersion==8?"soundmanager2.swf":"soundmanager2_flash9.swf");e.features.peakData=e.features.waveformData=e.features.eqData=(e.flashVersion==9)};this._overHTTP=(document.location?document.location.protocol.match(/http/i):null);this._waitingforEI=false;this._initPending=false;this._tryInitOnFocus=(this.isSafari&&typeof document.hasFocus=="undefined");this._isFocused=(typeof document.hasFocus!="undefined"?document.hasFocus():null);this._okToDisable=!this._tryInitOnFocus;this.useAltURL=!this._overHTTP;var d="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html";this.supported=function(){return(e._didInit&&!e._disabled)};this.getMovie=function(h){return e.isIE?window[h]:(e.isSafari?g(h)||document[h]:g(h))};this.loadFromXML=function(h){try{e.o._loadFromXML(h)}catch(i){e._failSafely();return true}};this.createSound=function(i){if(!e._didInit){throw new Error("soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods")}if(arguments.length==2){i={id:arguments[0],url:arguments[1]}}var j=e._mergeObjects(i);var h=j;if(e._idCheck(h.id,true)){return e.sounds[h.id]}if(e.flashVersion>8&&e.useMovieStar){if(h.isMovieStar===null){h.isMovieStar=(h.url.match(e.netStreamPattern)?true:false)}if(h.isMovieStar&&(h.usePeakData||h.useWaveformData||h.useEQData)){h.usePeakData=false;h.useWaveformData=false;h.useEQData=false}}e.sounds[h.id]=new f(h);e.soundIDs[e.soundIDs.length]=h.id;if(e.flashVersion==8){e.o._createSound(h.id,h.onjustbeforefinishtime)}else{e.o._createSound(h.id,h.url,h.onjustbeforefinishtime,h.usePeakData,h.useWaveformData,h.useEQData,h.isMovieStar,(h.isMovieStar?h.useVideo:false))}if(h.autoLoad||h.autoPlay){if(e.sounds[h.id]){e.sounds[h.id].load(h)}}if(h.autoPlay){e.sounds[h.id].play()}return e.sounds[h.id]};this.createVideo=function(h){if(arguments.length==2){h={id:arguments[0],url:arguments[1]}}if(e.flashVersion>=9){h.isMovieStar=true;h.useVideo=true}else{return false}return e.createSound(h)};this.destroySound=function(j,h){if(!e._idCheck(j)){return false}for(var k=0;k<e.soundIDs.length;k++){if(e.soundIDs[k]==j){e.soundIDs.splice(k,1);continue}}e.sounds[j].unload();if(!h){e.sounds[j].destruct()}delete e.sounds[j]};this.destroyVideo=this.destroySound;this.load=function(h,i){if(!e._idCheck(h)){return false}e.sounds[h].load(i)};this.unload=function(h){if(!e._idCheck(h)){return false}e.sounds[h].unload()};this.play=function(h,i){if(!e._idCheck(h)){if(typeof i!="Object"){i={url:i}}if(i&&i.url){i.id=h;e.createSound(i)}else{return false}}e.sounds[h].play(i)};this.start=this.play;this.setPosition=function(h,i){if(!e._idCheck(h)){return false}e.sounds[h].setPosition(i)};this.stop=function(h){if(!e._idCheck(h)){return false}e.sounds[h].stop()};this.stopAll=function(){for(var h in e.sounds){if(e.sounds[h] instanceof f){e.sounds[h].stop()}}};this.pause=function(h){if(!e._idCheck(h)){return false}e.sounds[h].pause()};this.pauseAll=function(){for(var h=e.soundIDs.length;h--;){e.sounds[e.soundIDs[h]].pause()}};this.resume=function(h){if(!e._idCheck(h)){return false}e.sounds[h].resume()};this.resumeAll=function(){for(var h=e.soundIDs.length;h--;){e.sounds[e.soundIDs[h]].resume()}};this.togglePause=function(h){if(!e._idCheck(h)){return false}e.sounds[h].togglePause()};this.setPan=function(h,i){if(!e._idCheck(h)){return false}e.sounds[h].setPan(i)};this.setVolume=function(i,h){if(!e._idCheck(i)){return false}e.sounds[i].setVolume(h)};this.mute=function(h){if(typeof h!="string"){h=null}if(!h){for(var j=e.soundIDs.length;j--;){e.sounds[e.soundIDs[j]].mute()}e.muted=true}else{if(!e._idCheck(h)){return false}e.sounds[h].mute()}};this.muteAll=function(){e.mute()};this.unmute=function(h){if(typeof h!="string"){h=null}if(!h){for(var j=e.soundIDs.length;j--;){e.sounds[e.soundIDs[j]].unmute()}e.muted=false}else{if(!e._idCheck(h)){return false}e.sounds[h].unmute()}};this.unmuteAll=function(){e.unmute()};this.getMemoryUse=function(){if(e.flashVersion==8){return 0}if(e.o){return parseInt(e.o._getMemoryUse(),10)}};this.setPolling=function(h){if(!e.o||!e.allowPolling){return false}e.o._setPolling(h)};this.disable=function(j){if(typeof j=="undefined"){j=false}if(e._disabled){return false}e._disabled=true;for(var h=e.soundIDs.length;h--;){e._disableObject(e.sounds[e.soundIDs[h]])}e.initComplete(j)};this.canPlayURL=function(h){return(h?(h.match(e.filePattern)?true:false):null)};this.getSoundById=function(i,j){if(!i){throw new Error("SoundManager.getSoundById(): sID is null/undefined")}var h=e.sounds[i];return h};this.onload=function(){soundManager._wD("<em>Warning</em>: soundManager.onload() is undefined.",2)};this.onerror=function(){};this._idCheck=this.getSoundById;var c=function(){return false};c._protected=true;this._disableObject=function(i){for(var h in i){if(typeof i[h]=="function"&&typeof i[h]._protected=="undefined"){i[h]=c}}h=null};this._failSafely=function(h){if(typeof h=="undefined"){h=false}if(!e._disabled||h){e.disable(h)}};this._normalizeMovieURL=function(h){var i=null;if(h){if(h.match(/\.swf(\?.*)?$/i)){i=h.substr(h.toLowerCase().lastIndexOf(".swf?")+4);if(i){return h}}else{if(h.lastIndexOf("/")!=h.length-1){h=h+"/"}}}return(h&&h.lastIndexOf("/")!=-1?h.substr(0,h.lastIndexOf("/")+1):"./")+e.movieURL};this._getDocument=function(){return(document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName("div")[0]))};this._getDocument._protected=true;this._createMovie=function(n,l){if(e._didAppend&&e._appendSuccess){return false}if(window.location.href.indexOf("debug=1")+1){e.debugMode=true}e._didAppend=true;e._setVersionInfo();var u=(l?l:e.url);var k=(e.altURL?e.altURL:u);e.url=e._normalizeMovieURL(e._overHTTP?u:k);l=e.url;var m=null;if(e.useHighPerformance&&e.useMovieStar){m="Note: disabling highPerformance, not applicable with movieStar mode on";e.useHighPerformance=false}e.wmode=(e.useHighPerformance&&!e.useMovieStar?"transparent":"");var t={name:n,id:n,src:l,width:"100%",height:"100%",quality:"high",allowScriptAccess:"always",bgcolor:e.bgColor,pluginspage:"http://www.macromedia.com/go/getflashplayer",type:"application/x-shockwave-flash",wmode:e.wmode};var w={id:n,data:l,type:"application/x-shockwave-flash",width:"100%",height:"100%",wmode:e.wmode};var o={movie:l,AllowScriptAccess:"always",quality:"high",bgcolor:e.bgColor,wmode:e.wmode};var j=null;var r=null;if(e.isIE){j=document.createElement("div");var h='<object id="'+n+'" data="'+l+'" type="application/x-shockwave-flash" width="100%" height="100%"><param name="movie" value="'+l+'" /><param name="AllowScriptAccess" value="always" /><param name="quality" value="high" />'+(e.useHighPerformance&&!e.useMovieStar?'<param name="wmode" value="'+e.wmode+'" /> ':"")+'<param name="bgcolor" value="'+e.bgColor+'" /><!-- --></object>'}else{j=document.createElement("embed");for(r in t){if(t.hasOwnProperty(r)){j.setAttribute(r,t[r])}}}var q="soundManager._createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.";var i=e._getDocument();if(i){e.oMC=g("sm2-container")?g("sm2-container"):document.createElement("div");if(!e.oMC.id){e.oMC.id="sm2-container";e.oMC.className="movieContainer";var z=null;var p=null;if(e.useHighPerformance){z={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px"}}else{z={position:"absolute",width:"1px",height:"1px",top:"-999px",left:"-999px"}}var y=null;for(y in z){if(z.hasOwnProperty(y)){e.oMC.style[y]=z[y]}}try{if(!e.isIE){e.oMC.appendChild(j)}i.appendChild(e.oMC);if(e.isIE){p=e.oMC.appendChild(document.createElement("div"));p.className="sm2-object-box";p.innerHTML=h}e._appendSuccess=true}catch(v){throw new Error(q)}}else{e.oMC.appendChild(j);if(e.isIE){p=e.oMC.appendChild(document.createElement("div"));p.className="sm2-object-box";p.innerHTML=h}e._appendSuccess=true}}};this._writeDebug=function(h,j,i){};this._writeDebug._protected=true;this._wdCount=0;this._wdCount._protected=true;this._wD=this._writeDebug;this._toggleDebug=function(){};this._toggleDebug._protected=true;this._debug=function(){};this._debugTS=function(j,h,i){};this._debugTS._protected=true;this._mergeObjects=function(j,h){var m={};for(var k in j){if(j.hasOwnProperty(k)){m[k]=j[k]}}var l=(typeof h=="undefined"?e.defaultOptions:h);for(var n in l){if(l.hasOwnProperty(n)&&typeof m[n]=="undefined"){m[n]=l[n]}}return m};this.createMovie=function(h){if(h){e.url=h}e._initMovie()};this.go=this.createMovie;this._initMovie=function(){if(e.o){return false}e.o=e.getMovie(e.id);if(!e.o){if(!e.oRemoved){e._createMovie(e.id,e.url)}else{if(!e.isIE){e.oMC.appendChild(e.oRemoved)}else{e.oMC.innerHTML=e.oRemovedHTML}e.oRemoved=null;e._didAppend=true}e.o=e.getMovie(e.id)}};this.waitForExternalInterface=function(){if(e._waitingForEI){return false}e._waitingForEI=true;if(e._tryInitOnFocus&&!e._isFocused){return false}if(e.flashLoadTimeout>0){setTimeout(function(){if(!e._didInit&&e._okToDisable){e._failSafely(true)}},e.flashLoadTimeout)}};this.handleFocus=function(){if(e._isFocused||!e._tryInitOnFocus){return true}e._okToDisable=true;e._isFocused=true;if(e._tryInitOnFocus){window.removeEventListener("mousemove",e.handleFocus,false)}e._waitingForEI=false;setTimeout(e.waitForExternalInterface,500);if(window.removeEventListener){window.removeEventListener("focus",e.handleFocus,false)}else{if(window.detachEvent){window.detachEvent("onfocus",e.handleFocus)}}};this.initComplete=function(h){if(e._didInit){return false}e._didInit=true;if(e._disabled||h){e.onerror.apply(window);return false}else{}if(e.waitForWindowLoad&&!e._windowLoaded){if(window.addEventListener){window.addEventListener("load",e.initUserOnload,false)}else{if(window.attachEvent){window.attachEvent("onload",e.initUserOnload)}}return false}else{e.initUserOnload()}};this.initUserOnload=function(){e.onload.apply(window)};this.init=function(){e._initMovie();if(e._didInit){return false}if(window.removeEventListener){window.removeEventListener("load",e.beginDelayedInit,false)}else{if(window.detachEvent){window.detachEvent("onload",e.beginDelayedInit)}}try{e.o._externalInterfaceTest(false);e.setPolling(true);if(!e.debugMode){e.o._disableDebug()}e.enabled=true}catch(h){e._failSafely(true);e.initComplete();return false}e.initComplete()};this.beginDelayedInit=function(){e._windowLoaded=true;setTimeout(e.waitForExternalInterface,500);setTimeout(e.beginInit,20)};this.beginInit=function(){if(e._initPending){return false}e.createMovie();e._initMovie();e._initPending=true;return true};this.domContentLoaded=function(){if(document.removeEventListener){document.removeEventListener("DOMContentLoaded",e.domContentLoaded,false)}e.go()};this._externalInterfaceOK=function(){if(e.swfLoaded){return false}e.swfLoaded=true;e._tryInitOnFocus=false;if(e.isIE){setTimeout(e.init,100)}else{e.init()}};this._setSandboxType=function(h){var i=e.sandbox;i.type=h;i.description=i.types[(typeof i.types[h]!="undefined"?h:"unknown")];if(i.type=="localWithFile"){i.noRemote=true;i.noLocal=false}else{if(i.type=="localWithNetwork"){i.noRemote=false;i.noLocal=true}else{if(i.type=="localTrusted"){i.noRemote=false;i.noLocal=false}}}};this.reboot=function(){if(e.soundIDs.length){}for(var h=e.soundIDs.length;h--;){e.sounds[e.soundIDs[h]].destruct()}try{if(e.isIE){e.oRemovedHTML=e.o.innerHTML}e.oRemoved=e.o.parentNode.removeChild(e.o)}catch(j){}e.enabled=false;e._didInit=false;e._waitingForEI=false;e._initPending=false;e._didInit=false;e._didAppend=false;e._appendSuccess=false;e._didInit=false;e._disabled=false;e._waitingforEI=true;e.swfLoaded=false;e.soundIDs={};e.sounds=[];e.o=null;window.setTimeout(function(){soundManager.beginDelayedInit()},20)};this.destruct=function(){e.disable(true)};f=function(h){var i=this;this.sID=h.id;this.url=h.url;this.options=e._mergeObjects(h);this.instanceOptions=this.options;this._iO=this.instanceOptions;this.pan=this.options.pan;this.volume=this.options.volume;this._debug=function(){if(e.debugMode){var l=null;var n=[];var k=null;var m=null;var j=64;for(l in i.options){if(i.options[l]!==null){if(i.options[l] instanceof Function){k=i.options[l].toString();k=k.replace(/\s\s+/g," ");m=k.indexOf("{");n[n.length]=" "+l+": {"+k.substr(m+1,(Math.min(Math.max(k.indexOf("\n")-1,j),j))).replace(/\n/g,"")+"... }"}else{n[n.length]=" "+l+": "+i.options[l]}}}}};this._debug();this.id3={};this.resetProperties=function(j){i.bytesLoaded=null;i.bytesTotal=null;i.position=null;i.duration=null;i.durationEstimate=null;i.loaded=false;i.playState=0;i.paused=false;i.readyState=0;i.muted=false;i.didBeforeFinish=false;i.didJustBeforeFinish=false;i.isBuffering=false;i.instanceOptions={};i.instanceCount=0;i.peakData={left:0,right:0};i.waveformData=[];i.eqData=[]};i.resetProperties();this.load=function(j){if(typeof j!="undefined"){i._iO=e._mergeObjects(j);i.instanceOptions=i._iO}else{j=i.options;i._iO=j;i.instanceOptions=i._iO}if(typeof i._iO.url=="undefined"){i._iO.url=i.url}if(i._iO.url==i.url&&i.readyState!==0&&i.readyState!=2){return false}i.loaded=false;i.readyState=1;i.playState=0;try{if(e.flashVersion==8){e.o._load(i.sID,i._iO.url,i._iO.stream,i._iO.autoPlay,(i._iO.whileloading?1:0))}else{e.o._load(i.sID,i._iO.url,i._iO.stream?true:false,i._iO.autoPlay?true:false);if(i._iO.isMovieStar&&i._iO.autoLoad&&!i._iO.autoPlay){i.pause()}}}catch(k){e.onerror();e.disable()}};this.unload=function(){if(i.readyState!==0){if(i.readyState!=2){i.setPosition(0,true)}e.o._unload(i.sID,e.nullURL);i.resetProperties()}};this.destruct=function(){e.o._destroySound(i.sID);e.destroySound(i.sID,true)};this.play=function(k){if(!k){k={}}i._iO=e._mergeObjects(k,i._iO);i._iO=e._mergeObjects(i._iO,i.options);i.instanceOptions=i._iO;if(i.playState==1){var j=i._iO.multiShot;if(!j){return false}}if(!i.loaded){if(i.readyState===0){i._iO.stream=true;i._iO.autoPlay=true;i.load(i._iO)}else{if(i.readyState==2){return false}}}if(i.paused){i.resume()}else{i.playState=1;if(!i.instanceCount||e.flashVersion==9){i.instanceCount++}i.position=(typeof i._iO.position!="undefined"&&!isNaN(i._iO.position)?i._iO.position:0);if(i._iO.onplay){i._iO.onplay.apply(i)}i.setVolume(i._iO.volume,true);i.setPan(i._iO.pan,true);e.o._start(i.sID,i._iO.loop||1,(e.flashVersion==9?i.position:i.position/1000))}};this.start=this.play;this.stop=function(j){if(i.playState==1){i.playState=0;i.paused=false;if(i._iO.onstop){i._iO.onstop.apply(i)}e.o._stop(i.sID,j);i.instanceCount=0;i._iO={}}};this.setPosition=function(k,j){if(typeof k=="undefined"){k=0}var l=Math.min(i.duration,Math.max(k,0));i._iO.position=l;e.o._setPosition(i.sID,(e.flashVersion==9?i._iO.position:i._iO.position/1000),(i.paused||!i.playState))};this.pause=function(){if(i.paused||i.playState===0){return false}i.paused=true;e.o._pause(i.sID);if(i._iO.onpause){i._iO.onpause.apply(i)}};this.resume=function(){if(!i.paused||i.playState===0){return false}i.paused=false;e.o._pause(i.sID);if(i._iO.onresume){i._iO.onresume.apply(i)}};this.togglePause=function(){if(!i.playState){i.play({position:(e.flashVersion==9?i.position:i.position/1000)});return false}if(i.paused){i.resume()}else{i.pause()}};this.setPan=function(k,j){if(typeof k=="undefined"){k=0}if(typeof j=="undefined"){j=false}e.o._setPan(i.sID,k);i._iO.pan=k;if(!j){i.pan=k}};this.setVolume=function(j,k){if(typeof j=="undefined"){j=100}if(typeof k=="undefined"){k=false}e.o._setVolume(i.sID,(e.muted&&!i.muted)||i.muted?0:j);i._iO.volume=j;if(!k){i.volume=j}};this.mute=function(){i.muted=true;e.o._setVolume(i.sID,0)};this.unmute=function(){i.muted=false;var j=typeof i._iO.volume!="undefined";e.o._setVolume(i.sID,j?i._iO.volume:i.options.volume)};this._whileloading=function(j,k,l){if(!i._iO.isMovieStar){i.bytesLoaded=j;i.bytesTotal=k;i.duration=Math.floor(l);i.durationEstimate=parseInt((i.bytesTotal/i.bytesLoaded)*i.duration,10);if(i.readyState!=3&&i._iO.whileloading){i._iO.whileloading.apply(i)}}else{i.bytesLoaded=j;i.bytesTotal=k;i.duration=Math.floor(l);i.durationEstimate=i.duration;if(i.readyState!=3&&i._iO.whileloading){i._iO.whileloading.apply(i)}}};this._onid3=function(n,k){var o=[];for(var m=0,l=n.length;m<l;m++){o[n[m]]=k[m]}i.id3=e._mergeObjects(i.id3,o);if(i._iO.onid3){i._iO.onid3.apply(i)}};this._whileplaying=function(k,l,j,m){if(isNaN(k)||k===null){return false}i.position=k;if(i._iO.usePeakData&&typeof l!="undefined"&&l){i.peakData={left:l.leftPeak,right:l.rightPeak}}if(i._iO.useWaveformData&&typeof j!="undefined"&&j){i.waveformData=j}if(i._iO.useEQData&&typeof m!="undefined"&&m){i.eqData=m}if(i.playState==1){if(i._iO.whileplaying){i._iO.whileplaying.apply(i)}if(i.loaded&&i._iO.onbeforefinish&&i._iO.onbeforefinishtime&&!i.didBeforeFinish&&i.duration-i.position<=i._iO.onbeforefinishtime){i._onbeforefinish()}}};this._onload=function(j){j=(j==1?true:false);i.loaded=j;i.readyState=j?3:2;if(i._iO.onload){i._iO.onload.apply(i)}};this._onbeforefinish=function(){if(!i.didBeforeFinish){i.didBeforeFinish=true;if(i._iO.onbeforefinish){i._iO.onbeforefinish.apply(i)}}};this._onjustbeforefinish=function(j){if(!i.didJustBeforeFinish){i.didJustBeforeFinish=true;if(i._iO.onjustbeforefinish){i._iO.onjustbeforefinish.apply(i)}}};this._onfinish=function(){if(i._iO.onbeforefinishcomplete){i._iO.onbeforefinishcomplete.apply(i)}i.didBeforeFinish=false;i.didJustBeforeFinish=false;if(i.instanceCount){i.instanceCount--;if(!i.instanceCount){i.playState=0;i.paused=false;i.instanceCount=0;i.instanceOptions={};if(i._iO.onfinish){i._iO.onfinish.apply(i)}}}else{}};this._onmetadata=function(j){if(!j.width&&!j.height){j.width=320;j.height=240}i.metadata=j;i.width=j.width;i.height=j.height;if(i._iO.onmetadata){i._iO.onmetadata.apply(i)}};this._onbufferchange=function(j){if(j==i.isBuffering){return false}i.isBuffering=(j==1?true:false);if(i._iO.onbufferchange){i._iO.onbufferchange.apply(i)}}};if(window.addEventListener){window.addEventListener("focus",e.handleFocus,false);window.addEventListener("load",e.beginDelayedInit,false);window.addEventListener("unload",e.destruct,false);if(e._tryInitOnFocus){window.addEventListener("mousemove",e.handleFocus,false)}}else{if(window.attachEvent){window.attachEvent("onfocus",e.handleFocus);window.attachEvent("onload",e.beginDelayedInit);window.attachEvent("unload",e.destruct)}else{soundManager.onerror();soundManager.disable()}}if(document.addEventListener){document.addEventListener("DOMContentLoaded",e.domContentLoaded,false)}}soundManager=new SoundManager();
\ No newline at end of file
diff --git a/tools/eztelemeta/design/standard/javascript/soundmanager2.js b/tools/eztelemeta/design/standard/javascript/soundmanager2.js
new file mode 100644 (file)
index 0000000..2b8277d
--- /dev/null
@@ -0,0 +1,1615 @@
+/*!\r
+   SoundManager 2: Javascript Sound for the Web\r
+   --------------------------------------------\r
+   http://schillmania.com/projects/soundmanager2/\r
+\r
+   Copyright (c) 2008, Scott Schiller. All rights reserved.\r
+   Code licensed under the BSD License:\r
+   http://schillmania.com/projects/soundmanager2/license.txt\r
+\r
+   V2.94a.20090206\r
+*/\r
+\r
+var soundManager = null;\r
+\r
+function SoundManager(smURL,smID) {\r
\r
+  this.flashVersion = 8;           // version of flash to require, either 8 or 9. Some API features require Flash 9.\r
+  this.debugMode = true;           // enable debugging output (div#soundmanager-debug, OR console if available + configured)\r
+  this.useConsole = true;          // use firebug/safari console.log()-type debug console if available\r
+  this.consoleOnly = false;        // if console is being used, do not create/write to #soundmanager-debug\r
+  this.waitForWindowLoad = false;  // force SM2 to wait for window.onload() before trying to call soundManager.onload()\r
+  this.nullURL = 'null.mp3';       // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only)\r
+  this.allowPolling = true;        // allow flash to poll for status update (required for "while playing", peak, sound spectrum functions to work.)\r
+  this.useMovieStar = false;      // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio + video formats (AAC, M4V, FLV, MOV etc.)\r
+  this.bgColor = '#ffffff';       // movie (.swf) background color, useful if showing on-screen for video etc.\r
+  this.useHighPerformance = false; // position:fixed flash movie gives increased js/flash speed\r
+  this.flashLoadTimeout = 750;     // ms to wait for flash movie to load before failing (0 = infinity)\r
+\r
+  this.defaultOptions = {\r
+    'autoLoad': false,             // enable automatic loading (otherwise .load() will be called on demand with .play(), the latter being nicer on bandwidth - if you want to .load yourself, you also can)\r
+    'stream': true,                // allows playing before entire file has loaded (recommended)\r
+    'autoPlay': false,             // enable playing of file as soon as possible (much faster if "stream" is true)\r
+    'onid3': null,                 // callback function for "ID3 data is added/available"\r
+    'onload': null,                // callback function for "load finished"\r
+    'whileloading': null,          // callback function for "download progress update" (X of Y bytes received)\r
+    'onplay': null,                // callback for "play" start\r
+    'onpause': null,               // callback for "pause"\r
+    'onresume': null,              // callback for "resume" (pause toggle)\r
+    'whileplaying': null,          // callback during play (position update)\r
+    'onstop': null,                // callback for "user stop"\r
+    'onfinish': null,              // callback function for "sound finished playing"\r
+    'onbeforefinish': null,        // callback for "before sound finished playing (at [time])"\r
+    'onbeforefinishtime': 5000,    // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second)\r
+    'onbeforefinishcomplete':null, // function to call when said sound finishes playing\r
+    'onjustbeforefinish':null,     // callback for [n] msec before end of current sound\r
+    'onjustbeforefinishtime':200,  // [n] - if not using, set to 0 (or null handler) and event will not fire.\r
+    'multiShot': true,             // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time\r
+    'position': null,              // offset (milliseconds) to seek to within loaded sound data.\r
+    'pan': 0,                      // "pan" settings, left-to-right, -100 to 100\r
+    'volume': 100                  // self-explanatory. 0-100, the latter being the max.\r
+  };\r
+\r
+  this.flash9Options = {           // flash 9-only options, merged into defaultOptions if flash 9 is being used\r
+    'onbufferchange': null,       // callback for "isBuffering" property change\r
+    'isMovieStar': null,          // "MovieStar" MPEG4 audio/video mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL\r
+    'usePeakData': false,          // enable left/right channel peak (level) data\r
+    'useWaveformData': false,      // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire.\r
+    'useEQData': false             // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive.\r
+  };\r
+\r
+  this.movieStarOptions = {        // flash 9.0r115+ MPEG4 audio/video options, merged into defaultOptions if flash 9 + movieStar mode is enabled\r
+    'onmetadata': null,                   // callback for when video width/height etc. are received\r
+    'useVideo': false             // if loading movieStar content, whether to show video\r
+  };\r
+\r
+  // jslint global declarations\r
+  /*global sm2Debugger, alert, console, document, navigator, setTimeout, window */\r
+\r
+  var SMSound = null; // defined later\r
+\r
+  var _s = this;\r
+  this.version = null;\r
+  this.versionNumber = 'V2.94a.20090206';\r
+  this.movieURL = null;\r
+  this.url = null;\r
+  this.altURL = null;\r
+  this.swfLoaded = false;\r
+  this.enabled = false;\r
+  this.o = null;\r
+  this.id = (smID||'sm2movie');\r
+  this.oMC = null;\r
+  this.sounds = {};\r
+  this.soundIDs = [];\r
+  this.muted = false;\r
+  this.wmode = null;\r
+  this.isIE = (navigator.userAgent.match(/MSIE/i));\r
+  this.isSafari = (navigator.userAgent.match(/safari/i));\r
+  this.isGecko = (navigator.userAgent.match(/gecko/i));\r
+  this.debugID = 'soundmanager-debug';\r
+  this._debugOpen = true;\r
+  this._didAppend = false;\r
+  this._appendSuccess = false;\r
+  this._didInit = false;\r
+  this._disabled = false;\r
+  this._windowLoaded = false;\r
+  this._hasConsole = (typeof console != 'undefined' && typeof console.log != 'undefined');\r
+  this._debugLevels = ['log','info','warn','error'];\r
+  this._defaultFlashVersion = 8;\r
+  this._oRemoved = null;\r
+  this._oRemovedHTML = null;\r
+\r
+  var _$ = function(sID) {\r
+    return document.getElementById(sID);\r
+  };\r
+\r
+  this.filePatterns = {\r
+       flash8: /\.mp3(\?.*)?$/i,\r
+       flash9: /\.mp3(\?.*)?$/i\r
+  };\r
+\r
+  this.netStreamTypes = ['aac','flv','mov','mp4','m4v','f4v','m4a','mp4v','3gp','3g2']; // Flash v9.0r115+ "moviestar" formats\r
+  this.netStreamPattern = new RegExp('\\.('+this.netStreamTypes.join('|')+')(\\?.*)?$','i');\r
+\r
+  this.filePattern = null;\r
+  this.features = {\r
+       buffering: false,\r
+    peakData: false,\r
+    waveformData: false,\r
+    eqData: false,\r
+    movieStar: false\r
+  };\r
+\r
+  this.sandbox = {\r
+    'type': null,\r
+    'types': {\r
+      'remote': 'remote (domain-based) rules',\r
+      'localWithFile': 'local with file access (no internet access)',\r
+      'localWithNetwork': 'local with network (internet access only, no local access)',\r
+      'localTrusted': 'local, trusted (local + internet access)'\r
+    },\r
+    'description': null,\r
+    'noRemote': null,\r
+    'noLocal': null\r
+  };\r
+\r
+  this._setVersionInfo = function() {\r
+    if (_s.flashVersion != 8 && _s.flashVersion != 9) {\r
+      alert('soundManager.flashVersion must be 8 or 9. "'+_s.flashVersion+'" is invalid. Reverting to '+_s._defaultFlashVersion+'.');\r
+      _s.flashVersion = _s._defaultFlashVersion;\r
+    }\r
+    _s.version = _s.versionNumber+(_s.flashVersion==9?' (AS3/Flash 9)':' (AS2/Flash 8)');\r
+    // set up default options\r
+       if (_s.flashVersion > 8) {\r
+         _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.flash9Options);\r
+         _s.features.buffering = true;\r
+       }\r
+    if (_s.flashVersion > 8 && _s.useMovieStar) {\r
+      // flash 9+ support for movieStar formats as well as MP3\r
+      _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.movieStarOptions);\r
+      _s.filePatterns.flash9 = new RegExp('\\.(mp3|'+_s.netStreamTypes.join('|')+')(\\?.*)?$','i');\r
+      _s.features.movieStar = true;\r
+    } else {\r
+      _s.useMovieStar = false;\r
+      _s.features.movieStar = false;\r
+    }\r
+    _s.filePattern = _s.filePatterns[(_s.flashVersion!=8?'flash9':'flash8')];\r
+    _s.movieURL = (_s.flashVersion==8?'soundmanager2.swf':'soundmanager2_flash9.swf');\r
+    _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion==9);\r
+  };\r
+\r
+  this._overHTTP = (document.location?document.location.protocol.match(/http/i):null);\r
+  this._waitingforEI = false;\r
+  this._initPending = false;\r
+  this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined');\r
+  this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null);\r
+  this._okToDisable = !this._tryInitOnFocus;\r
+\r
+  this.useAltURL = !this._overHTTP; // use altURL if not "online"\r
+\r
+  var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html';\r
+\r
+  // --- public methods ---\r
+  \r
+  this.supported = function() {\r
+    return (_s._didInit && !_s._disabled);\r
+  };\r
+\r
+  this.getMovie = function(smID) {\r
+    return _s.isIE?window[smID]:(_s.isSafari?_$(smID)||document[smID]:_$(smID));\r
+  };\r
+\r
+  this.loadFromXML = function(sXmlUrl) {\r
+    try {\r
+      _s.o._loadFromXML(sXmlUrl);\r
+    } catch(e) {\r
+      _s._failSafely();\r
+      return true;\r
+    }\r
+  };\r
+\r
+  this.createSound = function(oOptions) {\r
+    if (!_s._didInit) {\r
+         throw new Error('soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods');\r
+       }\r
+    if (arguments.length == 2) {\r
+      // function overloading in JS! :) ..assume simple createSound(id,url) use case\r
+      oOptions = {'id':arguments[0],'url':arguments[1]};\r
+    }\r
+    var thisOptions = _s._mergeObjects(oOptions); // inherit SM2 defaults\r
+    var _tO = thisOptions; // alias\r
+    _s._wD('soundManager.createSound(): '+_tO.id+' ('+_tO.url+')',1);\r
+    if (_s._idCheck(_tO.id,true)) {\r
+      _s._wD('soundManager.createSound(): '+_tO.id+' exists',1);\r
+      return _s.sounds[_tO.id];\r
+    }\r
+    if (_s.flashVersion > 8 && _s.useMovieStar) {\r
+         if (_tO.isMovieStar === null) {\r
+           _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false);\r
+         }\r
+         if (_tO.isMovieStar) {\r
+           _s._wD('soundManager.createSound(): using MovieStar handling');\r
+         }\r
+         if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) {\r
+           _s._wD('Warning: peak/waveform/eqData features unsupported for non-MP3 formats');\r
+           _tO.usePeakData = false;\r
+               _tO.useWaveformData = false;\r
+               _tO.useEQData = false;\r
+         }\r
+    }\r
+    _s.sounds[_tO.id] = new SMSound(_tO);\r
+    _s.soundIDs[_s.soundIDs.length] = _tO.id;\r
+    // AS2:\r
+    if (_s.flashVersion == 8) {\r
+      _s.o._createSound(_tO.id,_tO.onjustbeforefinishtime);\r
+    } else {\r
+      _s.o._createSound(_tO.id,_tO.url,_tO.onjustbeforefinishtime,_tO.usePeakData,_tO.useWaveformData,_tO.useEQData,_tO.isMovieStar,(_tO.isMovieStar?_tO.useVideo:false));\r
+    }\r
+    if (_tO.autoLoad || _tO.autoPlay) {\r
+      // TODO: does removing timeout here cause problems?\r
+        if (_s.sounds[_tO.id]) {\r
+          _s.sounds[_tO.id].load(_tO);\r
+        }\r
+    }\r
+    if (_tO.autoPlay) {\r
+         _s.sounds[_tO.id].play();\r
+       }\r
+    return _s.sounds[_tO.id];\r
+  };\r
+\r
+  this.createVideo = function(oOptions) {\r
+    if (arguments.length==2) {\r
+      oOptions = {'id':arguments[0],'url':arguments[1]};\r
+    }\r
+    if (_s.flashVersion >= 9) {\r
+      oOptions.isMovieStar = true;\r
+      oOptions.useVideo = true;\r
+    } else {\r
+      _s._wD('soundManager.createVideo(): flash 9 required for video. Exiting.',2);\r
+      return false;\r
+    }\r
+    if (!_s.useMovieStar) {\r
+      _s._wD('soundManager.createVideo(): MovieStar mode not enabled. Exiting.',2);\r
+    }\r
+    return _s.createSound(oOptions);\r
+  };\r
+\r
+  this.destroySound = function(sID,bFromSound) {\r
+    // explicitly destroy a sound before normal page unload, etc.\r
+    if (!_s._idCheck(sID)) {\r
+      return false;\r
+    }\r
+    for (var i=0; i<_s.soundIDs.length; i++) {\r
+      if (_s.soundIDs[i] == sID) {\r
+           _s.soundIDs.splice(i,1);\r
+        continue;\r
+      }\r
+    }\r
+    // conservative option: avoid crash with ze flash 8\r
+    // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP + flash 8??\r
+    // if (_s.flashVersion != 8) {\r
+      _s.sounds[sID].unload();\r
+    // }\r
+    if (!bFromSound) {\r
+      // ignore if being called from SMSound instance\r
+      _s.sounds[sID].destruct();\r
+    }\r
+    delete _s.sounds[sID];\r
+  };\r
+\r
+  this.destroyVideo = this.destroySound;\r
+\r
+  this.load = function(sID,oOptions) {\r
+    if (!_s._idCheck(sID)) {\r
+      return false;\r
+    }\r
+    _s.sounds[sID].load(oOptions);\r
+  };\r
+\r
+  this.unload = function(sID) {\r
+    if (!_s._idCheck(sID)) {\r
+      return false;\r
+    }\r
+    _s.sounds[sID].unload();\r
+  };\r
+\r
+  this.play = function(sID,oOptions) {\r
+    if (!_s._idCheck(sID)) {\r
+      if (typeof oOptions != 'Object') {\r
+               oOptions = {url:oOptions}; // overloading use case: play('mySound','/path/to/some.mp3');\r
+         }\r
+      if (oOptions && oOptions.url) {\r
+        // overloading use case, creation + playing of sound: .play('someID',{url:'/path/to.mp3'});\r
+        _s._wD('soundController.play(): attempting to create "'+sID+'"',1);\r
+        oOptions.id = sID;\r
+        _s.createSound(oOptions);\r
+      } else {\r
+        return false;\r
+      }\r
+    }\r
+    _s.sounds[sID].play(oOptions);\r
+  };\r
+\r
+  this.start = this.play; // just for convenience\r
+\r
+  this.setPosition = function(sID,nMsecOffset) {\r
+    if (!_s._idCheck(sID)) {\r
+      return false;\r
+    }\r
+    _s.sounds[sID].setPosition(nMsecOffset);\r
+  };\r
+\r
+  this.stop = function(sID) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s._wD('soundManager.stop('+sID+')',1);\r
+    _s.sounds[sID].stop(); \r
+  };\r
+\r
+  this.stopAll = function() {\r
+    _s._wD('soundManager.stopAll()',1);\r
+    for (var oSound in _s.sounds) {\r
+      if (_s.sounds[oSound] instanceof SMSound) {\r
+               _s.sounds[oSound].stop(); // apply only to sound objects\r
+         }\r
+    }\r
+  };\r
+\r
+  this.pause = function(sID) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s.sounds[sID].pause();\r
+  };\r
+\r
+  this.pauseAll = function() {\r
+    for (var i=_s.soundIDs.length; i--;) {\r
+      _s.sounds[_s.soundIDs[i]].pause();\r
+    }\r
+  };\r
+\r
+  this.resume = function(sID) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s.sounds[sID].resume();\r
+  };\r
+\r
+  this.resumeAll = function() {\r
+    for (var i=_s.soundIDs.length; i--;) {\r
+      _s.sounds[_s.soundIDs[i]].resume();\r
+    }\r
+  };\r
+\r
+  this.togglePause = function(sID) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s.sounds[sID].togglePause();\r
+  };\r
+\r
+  this.setPan = function(sID,nPan) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s.sounds[sID].setPan(nPan);\r
+  };\r
+\r
+  this.setVolume = function(sID,nVol) {\r
+    if (!_s._idCheck(sID)) {\r
+         return false;\r
+       }\r
+    _s.sounds[sID].setVolume(nVol);\r
+  };\r
+\r
+  this.mute = function(sID) {\r
+       if (typeof sID != 'string') {\r
+         sID = null;\r
+       }\r
+    if (!sID) {\r
+      _s._wD('soundManager.mute(): Muting all sounds');\r
+      for (var i=_s.soundIDs.length; i--;) {\r
+        _s.sounds[_s.soundIDs[i]].mute();\r
+      }\r
+      _s.muted = true;\r
+    } else {\r
+      if (!_s._idCheck(sID)) {\r
+           return false;\r
+         }\r
+      _s._wD('soundManager.mute(): Muting "'+sID+'"');\r
+      _s.sounds[sID].mute();\r
+    }\r
+  };\r
+\r
+  this.muteAll = function() {\r
+    _s.mute();\r
+  };\r
+\r
+  this.unmute = function(sID) {\r
+    if (typeof sID != 'string') {\r
+         sID = null;\r
+       }\r
+    if (!sID) {\r
+      _s._wD('soundManager.unmute(): Unmuting all sounds');\r
+      for (var i=_s.soundIDs.length; i--;) {\r
+        _s.sounds[_s.soundIDs[i]].unmute();\r
+      }\r
+      _s.muted = false;\r
+    } else {\r
+      if (!_s._idCheck(sID)) {\r
+               return false;\r
+         }\r
+      _s._wD('soundManager.unmute(): Unmuting "'+sID+'"');\r
+      _s.sounds[sID].unmute();\r
+    }\r
+  };\r
+\r
+  this.unmuteAll = function() {\r
+    _s.unmute();\r
+  };\r
+\r
+  this.getMemoryUse = function() {\r
+    if (_s.flashVersion == 8) {\r
+      // not supported in Flash 8\r
+      return 0;\r
+    }\r
+    if (_s.o) {\r
+      return parseInt(_s.o._getMemoryUse(),10);\r
+    }\r
+  };\r
+\r
+  this.setPolling = function(bPolling) {\r
+    if (!_s.o || !_s.allowPolling) {\r
+         return false;\r
+       }\r
+    _s.o._setPolling(bPolling);\r
+  };\r
+\r
+  this.disable = function(bNoDisable) {\r
+    // destroy all functions\r
+    if (typeof bNoDisable == 'undefined') {\r
+      bNoDisable = false;\r
+    }\r
+    if (_s._disabled) {\r
+         return false;\r
+    }\r
+    _s._disabled = true;\r
+    _s._wD('soundManager.disable(): Shutting down',1);\r
+    for (var i=_s.soundIDs.length; i--;) {\r
+      _s._disableObject(_s.sounds[_s.soundIDs[i]]);\r
+    }\r
+    _s.initComplete(bNoDisable); // fire "complete", despite fail\r
+    // _s._disableObject(_s); // taken out to allow reboot()\r
+  };\r
+\r
+  this.canPlayURL = function(sURL) {\r
+    return (sURL?(sURL.match(_s.filePattern)?true:false):null);        \r
+  };\r
+\r
+  this.getSoundById = function(sID,suppressDebug) {\r
+    if (!sID) {\r
+         throw new Error('SoundManager.getSoundById(): sID is null/undefined');\r
+       }\r
+    var result = _s.sounds[sID];\r
+    if (!result && !suppressDebug) {\r
+      _s._wD('"'+sID+'" is an invalid sound ID.',2);\r
+      // soundManager._wD('trace: '+arguments.callee.caller);\r
+    }\r
+    return result;\r
+  };\r
+\r
+  this.onload = function() {\r
+    // window.onload() equivalent for SM2, ready to create sounds etc.\r
+    // this is a stub - you can override this in your own external script, eg. soundManager.onload = function() {}\r
+    soundManager._wD('<em>Warning</em>: soundManager.onload() is undefined.',2);\r
+  };\r
+\r
+  this.onerror = function() {\r
+    // stub for user handler, called when SM2 fails to load/init\r
+  };\r
+\r
+  // --- "private" methods ---\r
+\r
+  this._idCheck = this.getSoundById;\r
+\r
+  var _doNothing = function() {\r
+    return false;\r
+  };\r
+  _doNothing._protected = true;\r
+\r
+  this._disableObject = function(o) {\r
+    for (var oProp in o) {\r
+      if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') {\r
+               o[oProp] = _doNothing;\r
+         }\r
+    }\r
+    oProp = null;\r
+  };\r
+\r
+  this._failSafely = function(bNoDisable) {\r
+    // general failure exception handler\r
+    if (typeof bNoDisable == 'undefined') {\r
+      bNoDisable = false;\r
+    }\r
+    if (!_s._disabled || bNoDisable) {\r
+      _s._wD('soundManager: Failed to initialise.',2);\r
+      _s.disable(bNoDisable);\r
+    }\r
+  };\r
+  \r
+  this._normalizeMovieURL = function(smURL) {\r
+    var urlParams = null;\r
+    if (smURL) {\r
+      if (smURL.match(/\.swf(\?.*)?$/i)) {\r
+        urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?')+4);\r
+        if (urlParams) {\r
+          return smURL; // assume user knows what they're doing\r
+        }\r
+      } else if (smURL.lastIndexOf('/') != smURL.length-1) {\r
+        smURL = smURL+'/';\r
+      }\r
+    }\r
+    return(smURL && smURL.lastIndexOf('/')!=-1?smURL.substr(0,smURL.lastIndexOf('/')+1):'./')+_s.movieURL;\r
+  };\r
+\r
+  this._getDocument = function() {\r
+    return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0]));\r
+  };\r
+\r
+  this._getDocument._protected = true;\r
+\r
+  this._createMovie = function(smID,smURL) {\r
+    if (_s._didAppend && _s._appendSuccess) {\r
+         return false; // ignore if already succeeded\r
+       }\r
+    if (window.location.href.indexOf('debug=1')+1) {\r
+         _s.debugMode = true; // allow force of debug mode via URL\r
+       }\r
+    _s._didAppend = true;\r
+       \r
+    // safety check for legacy (change to Flash 9 URL)\r
+    _s._setVersionInfo();\r
+    var remoteURL = (smURL?smURL:_s.url);\r
+    var localURL = (_s.altURL?_s.altURL:remoteURL);\r
+    _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL);\r
+    smURL = _s.url;\r
+\r
+    var specialCase = null;\r
+\r
+    if (_s.useHighPerformance && _s.useMovieStar) {\r
+      specialCase = 'Note: disabling highPerformance, not applicable with movieStar mode on';\r
+      _s.useHighPerformance = false;\r
+    }\r
+\r
+    _s.wmode = (_s.useHighPerformance && !_s.useMovieStar?'transparent':''); // wmode=opaque seems to break firefox/windows.\r
+\r
+    var oEmbed = {\r
+      name: smID,\r
+      id: smID,\r
+      src: smURL,\r
+      width: '100%',\r
+      height: '100%',\r
+      quality: 'high',\r
+      allowScriptAccess: 'always',\r
+      bgcolor: _s.bgColor,\r
+      pluginspage: 'http://www.macromedia.com/go/getflashplayer',\r
+      type: 'application/x-shockwave-flash',\r
+      wmode: _s.wmode\r
+    };\r
+\r
+    var oObject = {\r
+      id: smID,\r
+      data: smURL,\r
+      type: 'application/x-shockwave-flash',\r
+      width: '100%',\r
+      height: '100%',\r
+      wmode: _s.wmode\r
+    };\r
+\r
+    var oObjectParams = {\r
+      movie: smURL,\r
+      AllowScriptAccess: 'always',\r
+      quality: 'high',\r
+      bgcolor: _s.bgColor,\r
+      wmode: _s.wmode\r
+    };\r
+\r
+    var oMovie = null;\r
+    var tmp = null;\r
+\r
+    if (_s.isIE) {\r
+      // IE is "special".\r
+      oMovie = document.createElement('div');\r
+      var movieHTML = '<object id="'+smID+'" data="'+smURL+'" type="application/x-shockwave-flash" width="100%" height="100%"><param name="movie" value="'+smURL+'" /><param name="AllowScriptAccess" value="always" /><param name="quality" value="high" />'+(_s.useHighPerformance && !_s.useMovieStar?'<param name="wmode" value="'+_s.wmode+'" /> ':'')+'<param name="bgcolor" value="'+_s.bgColor+'" /><!-- --></object>';\r
+    } else {\r
+      oMovie = document.createElement('embed');\r
+      for (tmp in oEmbed) {\r
+       if (oEmbed.hasOwnProperty(tmp)) {\r
+          oMovie.setAttribute(tmp,oEmbed[tmp]);\r
+       }\r
+      }\r
+    }\r
+\r
+    var oD = document.createElement('div');\r
+    oD.id = _s.debugID+'-toggle';\r
+    var oToggle = {\r
+      position: 'fixed',\r
+      bottom: '0px',\r
+      right: '0px',\r
+      width: '1.2em',\r
+      height: '1.2em',\r
+      lineHeight: '1.2em',\r
+      margin: '2px',\r
+      textAlign: 'center',\r
+      border: '1px solid #999',\r
+      cursor: 'pointer',\r
+      background: '#fff',\r
+      color: '#333',\r
+      zIndex: 10001\r
+    };\r
+\r
+    oD.appendChild(document.createTextNode('-'));\r
+    oD.onclick = _s._toggleDebug;\r
+    oD.title = 'Toggle SM2 debug console';\r
+\r
+    if (navigator.userAgent.match(/msie 6/i)) {\r
+      oD.style.position = 'absolute';\r
+      oD.style.cursor = 'hand';\r
+    }\r
+\r
+    for (tmp in oToggle) {\r
+       if (oToggle.hasOwnProperty(tmp)) {\r
+          oD.style[tmp] = oToggle[tmp];\r
+       }\r
+    }\r
+\r
+    var appXHTML = 'soundManager._createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.';\r
+\r
+    var oTarget = _s._getDocument();\r
+\r
+    if (oTarget) {\r
+       \r
+      _s.oMC = _$('sm2-container')?_$('sm2-container'):document.createElement('div');\r
+\r
+      if (!_s.oMC.id) {\r
+        _s.oMC.id = 'sm2-container';\r
+        _s.oMC.className = 'movieContainer';\r
+        // "hide" flash movie\r
+        var s = null;\r
+        var oEl = null;\r
+        if (_s.useHighPerformance) {\r
+          s = {\r
+               position: 'fixed',\r
+                   width: '8px',\r
+            height: '8px', // must be at least 6px for flash to run fast. odd? yes.\r
+            bottom: '0px',\r
+            left: '0px'\r
+           // zIndex:-1 // sit behind everything else - potentially dangerous/buggy?\r
+          };\r
+        } else {\r
+          s = {\r
+            position: 'absolute',\r
+           width: '1px',\r
+            height: '1px',\r
+            top: '-999px',\r
+            left: '-999px'\r
+          };\r
+        }\r
+        var x = null;\r
+        for (x in s) {\r
+                 if (s.hasOwnProperty(x)) {\r
+            _s.oMC.style[x] = s[x];\r
+                 }\r
+        }\r
+        try {\r
+                 if (!_s.isIE) {\r
+           _s.oMC.appendChild(oMovie);\r
+                 }\r
+          oTarget.appendChild(_s.oMC);\r
+                 if (_s.isIE) {\r
+                       oEl = _s.oMC.appendChild(document.createElement('div'));\r
+                       oEl.className = 'sm2-object-box';\r
+                       oEl.innerHTML = movieHTML;\r
+          }\r
+          _s._appendSuccess = true;\r
+        } catch(e) {\r
+          throw new Error(appXHTML);\r
+        }\r
+      } else {\r
+        // it's already in the document.\r
+        _s.oMC.appendChild(oMovie);\r
+               if (_s.isIE) {\r
+                 oEl = _s.oMC.appendChild(document.createElement('div'));\r
+                 oEl.className = 'sm2-object-box';\r
+                 oEl.innerHTML = movieHTML;\r
+        }\r
+        _s._appendSuccess = true;\r
+      }\r
+\r
+      if (!_$(_s.debugID) && ((!_s._hasConsole||!_s.useConsole)||(_s.useConsole && _s._hasConsole && !_s.consoleOnly))) {\r
+        var oDebug = document.createElement('div');\r
+        oDebug.id = _s.debugID;\r
+        oDebug.style.display = (_s.debugMode?'block':'none');\r
+        if (_s.debugMode && !_$(oD.id)) {\r
+          try {\r
+            oTarget.appendChild(oD);\r
+          } catch(e2) {\r
+            throw new Error(appXHTML);\r
+          }\r
+          oTarget.appendChild(oDebug);\r
+        }\r
+      }\r
+      oTarget = null;\r
+    }\r
+\r
+    if (specialCase) {\r
+      _s._wD(specialCase);\r
+    }\r
+\r
+    _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s.useHighPerformance?', high performance mode':'')+' --',1);\r
+    _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?'(alternate URL)':''),1);\r
+  };\r
+\r
+  // aliased to this._wD()\r
+  this._writeDebug = function(sText,sType,bTimestamp) {\r
+    if (!_s.debugMode) {\r
+         return false;\r
+       }\r
+    if (typeof bTimestamp != 'undefined' && bTimestamp) {\r
+      sText = sText + ' | '+new Date().getTime();\r
+    }\r
+    if (_s._hasConsole && _s.useConsole) {\r
+      var sMethod = _s._debugLevels[sType];\r
+      if (typeof console[sMethod] != 'undefined') {\r
+           console[sMethod](sText);\r
+      } else {\r
+        console.log(sText);\r
+      }\r
+      if (_s.useConsoleOnly) {\r
+       return true;\r
+      }\r
+    }\r
+    var sDID = 'soundmanager-debug';\r
+    try {\r
+      var o = _$(sDID);\r
+      if (!o) {\r
+               return false;\r
+         }\r
+      var oItem = document.createElement('div');\r
+      if (++_s._wdCount%2===0) {\r
+           oItem.className = 'sm2-alt';\r
+      }\r
+      // sText = sText.replace(/\n/g,'<br />');\r
+      if (typeof sType == 'undefined') {\r
+        sType = 0;\r
+      } else {\r
+        sType = parseInt(sType,10);\r
+      }\r
+      oItem.appendChild(document.createTextNode(sText));\r
+      if (sType) {\r
+        if (sType >= 2) {\r
+                 oItem.style.fontWeight = 'bold';\r
+               }\r
+        if (sType == 3) {\r
+                 oItem.style.color = '#ff3333';\r
+               }\r
+      }\r
+      // o.appendChild(oItem); // top-to-bottom\r
+      o.insertBefore(oItem,o.firstChild); // bottom-to-top\r
+    } catch(e) {\r
+      // oh well\r
+    }\r
+    o = null;\r
+  };\r
+  this._writeDebug._protected = true;\r
+  this._wdCount = 0;\r
+  this._wdCount._protected = true;\r
+  this._wD = this._writeDebug;\r
+\r
+  this._wDAlert = function(sText) { alert(sText); };\r
+\r
+  if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) {\r
+    _s._wD = _s._wDAlert;\r
+  }\r
+\r
+  this._toggleDebug = function() {\r
+    var o = _$(_s.debugID);\r
+    var oT = _$(_s.debugID+'-toggle');\r
+    if (!o) {\r
+         return false;\r
+       }\r
+    if (_s._debugOpen) {\r
+      // minimize\r
+      oT.innerHTML = '+';\r
+      o.style.display = 'none';\r
+    } else {\r
+      oT.innerHTML = '-';\r
+      o.style.display = 'block';\r
+    }\r
+    _s._debugOpen = !_s._debugOpen;\r
+  };\r
+\r
+  this._toggleDebug._protected = true;\r
+\r
+  this._debug = function() {\r
+    _s._wD('--- soundManager._debug(): Current sound objects ---',1);\r
+    for (var i=0,j=_s.soundIDs.length; i<j; i++) {\r
+      _s.sounds[_s.soundIDs[i]]._debug();\r
+    }\r
+  };\r
+\r
+  this._debugTS = function(sEventType,bSuccess,sMessage) {\r
+    // troubleshooter debug hooks\r
+    if (typeof sm2Debugger != 'undefined') {\r
+         try {\r
+           sm2Debugger.handleEvent(sEventType,bSuccess,sMessage);\r
+         } catch(e) {\r
+           // oh well  \r
+         }\r
+    }\r
+  };\r
+\r
+  this._debugTS._protected = true;\r
+\r
+  this._mergeObjects = function(oMain,oAdd) {\r
+    // non-destructive merge\r
+    var o1 = {}; // clone o1\r
+    for (var i in oMain) {\r
+         if (oMain.hasOwnProperty(i)) {\r
+        o1[i] = oMain[i];\r
+         }\r
+    }\r
+    var o2 = (typeof oAdd == 'undefined'?_s.defaultOptions:oAdd);\r
+    for (var o in o2) {\r
+      if (o2.hasOwnProperty(o) && typeof o1[o] == 'undefined') {\r
+               o1[o] = o2[o];\r
+         }\r
+    }\r
+    return o1;\r
+  };\r
+\r
+  this.createMovie = function(sURL) {\r
+    if (sURL) {\r
+      _s.url = sURL;\r
+    }\r
+    _s._initMovie();\r
+  };\r
+\r
+  this.go = this.createMovie; // nice alias\r
+\r
+  this._initMovie = function() {\r
+    // attempt to get, or create, movie\r
+    if (_s.o) {\r
+         return false; // may already exist\r
+    }\r
+    _s.o = _s.getMovie(_s.id); // (inline markup)\r
+    if (!_s.o) {\r
+      if (!_s.oRemoved) {\r
+        // try to create\r
+        _s._createMovie(_s.id,_s.url);\r
+      } else {\r
+        // try to re-append removed movie after reboot()\r
+        if (!_s.isIE) {\r
+          _s.oMC.appendChild(_s.oRemoved);\r
+        } else {\r
+          _s.oMC.innerHTML = _s.oRemovedHTML;\r
+        }\r
+        _s.oRemoved = null;\r
+        _s._didAppend = true;\r
+      }\r
+      _s.o = _s.getMovie(_s.id);\r
+    }\r
+    if (_s.o) {\r
+      _s._wD('soundManager._initMovie(): Got '+_s.o.nodeName+' element ('+(_s._didAppend?'created via JS':'static HTML')+')',1);\r
+      if (_s.flashLoadTimeout>0) {\r
+        _s._wD('soundManager._initMovie(): Waiting for ExternalInterface call from Flash..');\r
+      }\r
+    }\r
+  };\r
+\r
+  this.waitForExternalInterface = function() {\r
+    if (_s._waitingForEI) {\r
+         return false;\r
+       }\r
+    _s._waitingForEI = true;\r
+    if (_s._tryInitOnFocus && !_s._isFocused) {\r
+      _s._wD('soundManager: Special case: Waiting for focus-related event..');\r
+      return false;\r
+    }\r
+    if (_s.flashLoadTimeout>0) {\r
+      if (!_s._didInit) {\r
+        _s._wD('soundManager: Getting impatient, still waiting for Flash.. ;)');\r
+      }\r
+      setTimeout(function() {\r
+        if (!_s._didInit) {\r
+          _s._wD('soundManager: No Flash response within reasonable time after document load.\nPossible causes: Flash version under 8, no support, or Flash security denying JS-Flash communication.',2);\r
+          if (!_s._overHTTP) {\r
+          _s._wD('soundManager: Loading this page from local/network file system (not over HTTP?) Flash security likely restricting JS-Flash access. Consider adding current URL to "trusted locations" in the Flash player security settings manager at '+flashCPLink+', or simply serve this content over HTTP.',2);\r
+        }\r
+        _s._debugTS('flashtojs',false,': Timed out'+(_s._overHTTP)?' (Check flash security)':' (No plugin/missing SWF?)');\r
+      }\r
+      // if still not initialized and no other options, give up\r
+      if (!_s._didInit && _s._okToDisable) {\r
+       _s._failSafely(true); // don't disable, for reboot()\r
+      }\r
+    },_s.flashLoadTimeout);\r
+    } else if (!_s.didInit) {\r
+      _s._wD('soundManager: Waiting indefinitely for Flash...');\r
+    }\r
+  };\r
+\r
+  this.handleFocus = function() {\r
+    if (_s._isFocused || !_s._tryInitOnFocus) {\r
+         return true;\r
+       }\r
+    _s._okToDisable = true;\r
+    _s._isFocused = true;\r
+    _s._wD('soundManager.handleFocus()');\r
+    if (_s._tryInitOnFocus) {\r
+      // giant Safari 3.1 hack - assume window in focus if mouse is moving, since document.hasFocus() not currently implemented.\r
+      window.removeEventListener('mousemove',_s.handleFocus,false);\r
+    }\r
+    // allow init to restart\r
+    _s._waitingForEI = false;\r
+    setTimeout(_s.waitForExternalInterface,500);\r
+    // detach event\r
+    if (window.removeEventListener) {\r
+      window.removeEventListener('focus',_s.handleFocus,false);\r
+    } else if (window.detachEvent) {\r
+      window.detachEvent('onfocus',_s.handleFocus);\r
+    }\r
+  };\r
+\r
+  this.initComplete = function(bNoDisable) {\r
+    if (_s._didInit) {\r
+         return false;\r
+       }\r
+    _s._didInit = true;\r
+    _s._wD('-- SoundManager 2 '+(_s._disabled?'failed to load':'loaded')+' ('+(_s._disabled?'security/load error':'OK')+') --',1);\r
+    if (_s._disabled || bNoDisable) {\r
+      _s._wD('soundManager.initComplete(): calling soundManager.onerror()',1);\r
+      _s._debugTS('onload',false);\r
+      _s.onerror.apply(window);\r
+      return false;\r
+    } else {\r
+         _s._debugTS('onload',true);\r
+    }\r
+    if (_s.waitForWindowLoad && !_s._windowLoaded) {\r
+      _s._wD('soundManager: Waiting for window.onload()');\r
+      if (window.addEventListener) {\r
+        window.addEventListener('load',_s.initUserOnload,false);\r
+      } else if (window.attachEvent) {\r
+        window.attachEvent('onload',_s.initUserOnload);\r
+      }\r
+      return false;\r
+    } else {\r
+      if (_s.waitForWindowLoad && _s._windowLoaded) {\r
+        _s._wD('soundManager: Document already loaded');\r
+      }\r
+      _s.initUserOnload();\r
+    }\r
+  };\r
+\r
+  this.initUserOnload = function() {\r
+    _s._wD('soundManager.initComplete(): calling soundManager.onload()',1);\r
+    // call user-defined "onload", scoped to window\r
+    _s.onload.apply(window);\r
+    _s._wD('soundManager.onload() complete',1);\r
+  };\r
+\r
+  this.init = function() {\r
+    _s._wD('-- soundManager.init() --');\r
+    // called after onload()\r
+    _s._initMovie();\r
+    if (_s._didInit) {\r
+      _s._wD('soundManager.init(): Already called?');\r
+      return false;\r
+    }\r
+    // event cleanup\r
+    if (window.removeEventListener) {\r
+      window.removeEventListener('load',_s.beginDelayedInit,false);\r
+    } else if (window.detachEvent) {\r
+      window.detachEvent('onload',_s.beginDelayedInit);\r
+    }\r
+    try {\r
+      _s._wD('Attempting to call Flash from JS..');\r
+      _s.o._externalInterfaceTest(false); // attempt to talk to Flash\r
+      // _s._wD('Flash ExternalInterface call (JS-Flash) OK',1);\r
+      if (!_s.allowPolling) {\r
+           _s._wD('Polling (whileloading/whileplaying support) is disabled.',1);\r
+         }\r
+      _s.setPolling(true);\r
+         if (!_s.debugMode) {\r
+               _s.o._disableDebug();\r
+         }\r
+      _s.enabled = true;\r
+      _s._debugTS('jstoflash',true);\r
+    } catch(e) {\r
+         _s._debugTS('jstoflash',false);\r
+      _s._failSafely(true); // don't disable, for reboot()\r
+      _s.initComplete();\r
+      return false;\r
+    }\r
+    _s.initComplete();\r
+  };\r
+\r
+  this.beginDelayedInit = function() {\r
+    _s._wD('soundManager.beginDelayedInit()');\r
+    _s._windowLoaded = true;\r
+    setTimeout(_s.waitForExternalInterface,500);\r
+    setTimeout(_s.beginInit,20);\r
+  };\r
+\r
+  this.beginInit = function() {\r
+    if (_s._initPending) {\r
+         return false;\r
+       }\r
+    _s.createMovie(); // ensure creation if not already done\r
+    _s._initMovie();\r
+    _s._initPending = true;\r
+    return true;\r
+  };\r
+\r
+  this.domContentLoaded = function() {\r
+    _s._wD('soundManager.domContentLoaded()');\r
+    if (document.removeEventListener) {\r
+         document.removeEventListener('DOMContentLoaded',_s.domContentLoaded,false);\r
+       }\r
+    _s.go();\r
+  };\r
+\r
+  this._externalInterfaceOK = function() {\r
+    // callback from flash for confirming that movie loaded, EI is working etc.\r
+    if (_s.swfLoaded) {\r
+         return false;\r
+       }\r
+    _s._wD('soundManager._externalInterfaceOK()');\r
+    _s._debugTS('swf',true);\r
+    _s._debugTS('flashtojs',true);\r
+    _s.swfLoaded = true;\r
+    _s._tryInitOnFocus = false;\r
+    if (_s.isIE) {\r
+      // IE needs a timeout OR delay until window.onload - may need TODO: investigating\r
+      setTimeout(_s.init,100);\r
+    } else {\r
+      _s.init();\r
+    }\r
+  };\r
+\r
+  this._setSandboxType = function(sandboxType) {\r
+    var sb = _s.sandbox;\r
+    sb.type = sandboxType;\r
+    sb.description = sb.types[(typeof sb.types[sandboxType] != 'undefined'?sandboxType:'unknown')];\r
+    _s._wD('Flash security sandbox type: '+sb.type);\r
+    if (sb.type == 'localWithFile') {\r
+      sb.noRemote = true;\r
+      sb.noLocal = false;\r
+      _s._wD('Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html',2);\r
+    } else if (sb.type == 'localWithNetwork') {\r
+      sb.noRemote = false;\r
+      sb.noLocal = true;\r
+    } else if (sb.type == 'localTrusted') {\r
+      sb.noRemote = false;\r
+      sb.noLocal = false;\r
+    }\r
+  };\r
+\r
+  this.reboot = function() {\r
+    // attempt to reset and init SM2\r
+    _s._wD('soundManager.reboot()');\r
+    if (_s.soundIDs.length) {\r
+      _s._wD('Destroying '+_s.soundIDs.length+' SMSound objects...');\r
+    }\r
+    for (var i=_s.soundIDs.length; i--;) {\r
+      _s.sounds[_s.soundIDs[i]].destruct();\r
+    }\r
+    // trash ze flash\r
+    try {\r
+      if (_s.isIE) {\r
+        _s.oRemovedHTML = _s.o.innerHTML;\r
+      }\r
+      _s.oRemoved = _s.o.parentNode.removeChild(_s.o);\r
+      _s._wD('Flash movie removed.');\r
+    } catch(e) {\r
+      // uh-oh.\r
+      _s._wD('Warning: Failed to remove flash movie.',2);\r
+    }\r
+    _s.enabled = false;\r
+    _s._didInit = false;\r
+    _s._waitingForEI = false;\r
+    _s._initPending = false;\r
+    _s._didInit = false;\r
+    _s._didAppend = false;\r
+    _s._appendSuccess = false;\r
+    _s._didInit = false;\r
+    _s._disabled = false;\r
+    _s._waitingforEI = true;\r
+    _s.swfLoaded = false;\r
+    _s.soundIDs = {};\r
+    _s.sounds = [];\r
+    _s.o = null;\r
+    _s._wD('soundManager: Rebooting...');\r
+    window.setTimeout(function() {\r
+      soundManager.beginDelayedInit();\r
+    },20);\r
+  };\r
+\r
+  this.destruct = function() {\r
+    _s._wD('soundManager.destruct()');\r
+    _s.disable(true);\r
+  };\r
+  \r
+  // SMSound (sound object)\r
+  \r
+  SMSound = function(oOptions) {\r
+  var _t = this;\r
+  this.sID = oOptions.id;\r
+  this.url = oOptions.url;\r
+  this.options = _s._mergeObjects(oOptions);\r
+  this.instanceOptions = this.options; // per-play-instance-specific options\r
+  this._iO = this.instanceOptions; // short alias\r
+\r
+  // assign property defaults (volume, pan etc.)\r
+  this.pan = this.options.pan;\r
+  this.volume = this.options.volume;\r
+\r
+  this._debug = function() {\r
+    if (_s.debugMode) {\r
+    var stuff = null;\r
+    var msg = [];\r
+    var sF = null;\r
+    var sfBracket = null;\r
+    var maxLength = 64; // # of characters of function code to show before truncating\r
+    for (stuff in _t.options) {\r
+      if (_t.options[stuff] !== null) {\r
+        if (_t.options[stuff] instanceof Function) {\r
+             // handle functions specially\r
+             sF = _t.options[stuff].toString();\r
+             sF = sF.replace(/\s\s+/g,' '); // normalize spaces\r
+             sfBracket = sF.indexOf('{');\r
+             msg[msg.length] = ' '+stuff+': {'+sF.substr(sfBracket+1,(Math.min(Math.max(sF.indexOf('\n')-1,maxLength),maxLength))).replace(/\n/g,'')+'... }';\r
+           } else {\r
+             msg[msg.length] = ' '+stuff+': '+_t.options[stuff];\r
+           }\r
+      }\r
+    }\r
+    _s._wD('SMSound() merged options: {\n'+msg.join(', \n')+'\n}');\r
+    }\r
+  };\r
+\r
+  this._debug();\r
+\r
+  this.id3 = {\r
+   /* \r
+    Name/value pairs set via Flash when available - see reference for names:\r
+    http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001567.html\r
+    (eg., this.id3.songname or this.id3['songname'])\r
+   */\r
+  };\r
+\r
+  this.resetProperties = function(bLoaded) {\r
+    _t.bytesLoaded = null;\r
+    _t.bytesTotal = null;\r
+    _t.position = null;\r
+    _t.duration = null;\r
+    _t.durationEstimate = null;\r
+    _t.loaded = false;\r
+    _t.playState = 0;\r
+    _t.paused = false;\r
+    _t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success\r
+    _t.muted = false;\r
+    _t.didBeforeFinish = false;\r
+    _t.didJustBeforeFinish = false;\r
+    _t.isBuffering = false;\r
+    _t.instanceOptions = {};\r
+    _t.instanceCount = 0;\r
+    _t.peakData = {\r
+      left: 0,\r
+      right: 0\r
+    };\r
+    _t.waveformData = [];\r
+    _t.eqData = [];\r
+  };\r
+\r
+  _t.resetProperties();\r
+\r
+  // --- public methods ---\r
+\r
+  this.load = function(oOptions) {\r
+    if (typeof oOptions != 'undefined') {\r
+      _t._iO = _s._mergeObjects(oOptions);\r
+      _t.instanceOptions = _t._iO;\r
+    } else {\r
+      oOptions = _t.options;\r
+      _t._iO = oOptions;\r
+      _t.instanceOptions = _t._iO;\r
+    } \r
+    if (typeof _t._iO.url == 'undefined') {\r
+      _t._iO.url = _t.url;\r
+    }\r
+    _s._wD('soundManager.load(): '+_t._iO.url,1);\r
+    if (_t._iO.url == _t.url && _t.readyState !== 0 && _t.readyState != 2) {\r
+      _s._wD('soundManager.load(): current URL already assigned.',1);\r
+      return false;\r
+    }\r
+    _t.loaded = false;\r
+    _t.readyState = 1;\r
+    _t.playState = 0; // (oOptions.autoPlay?1:0); // if autoPlay, assume "playing" is true (no way to detect when it actually starts in Flash unless onPlay is watched?)\r
+    try {\r
+      if (_s.flashVersion==8) {\r
+        _s.o._load(_t.sID,_t._iO.url,_t._iO.stream,_t._iO.autoPlay,(_t._iO.whileloading?1:0));\r
+      } else {\r
+        _s.o._load(_t.sID,_t._iO.url,_t._iO.stream?true:false,_t._iO.autoPlay?true:false); // ,(_tO.whileloading?true:false)\r
+        if (_t._iO.isMovieStar && _t._iO.autoLoad && !_t._iO.autoPlay) {\r
+          // special case: MPEG4 content must start playing to load, then pause to prevent playing.\r
+          _t.pause();\r
+        }\r
+      }\r
+    } catch(e) {\r
+      _s._wD('SMSound.load(): Exception: JS-Flash communication failed, or JS error.',2);\r
+      _s._debugTS('onload',false);\r
+      _s.onerror();\r
+      _s.disable();\r
+    }\r
+\r
+  };\r
+\r
+  this.unload = function() {\r
+    // Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3\r
+    // Flash 9/AS3: Close stream, preventing further load\r
+    if (_t.readyState !== 0) {\r
+      _s._wD('SMSound.unload(): "'+_t.sID+'"');\r
+      if (_t.readyState != 2) { // reset if not error\r
+        _t.setPosition(0,true); // reset current sound positioning\r
+      }\r
+      _s.o._unload(_t.sID,_s.nullURL);\r
+      // reset load/status flags\r
+      _t.resetProperties();\r
+    }\r
+  };\r
+\r
+  this.destruct = function() {\r
+    // kill sound within Flash\r
+    _s._wD('SMSound.destruct(): "'+_t.sID+'"');\r
+    _s.o._destroySound(_t.sID);\r
+    _s.destroySound(_t.sID,true); // ensure deletion from controller\r
+  };\r
+\r
+  this.play = function(oOptions) {\r
+    if (!oOptions) {\r
+         oOptions = {};\r
+    }\r
+    _t._iO = _s._mergeObjects(oOptions,_t._iO);\r
+    _t._iO = _s._mergeObjects(_t._iO,_t.options);\r
+    _t.instanceOptions = _t._iO;\r
+    if (_t.playState == 1) {\r
+      var allowMulti = _t._iO.multiShot;\r
+      if (!allowMulti) {\r
+        _s._wD('SMSound.play(): "'+_t.sID+'" already playing (one-shot)',1);\r
+        return false;\r
+      } else {\r
+        _s._wD('SMSound.play(): "'+_t.sID+'" already playing (multi-shot)',1);\r
+      }\r
+    }\r
+    if (!_t.loaded) {\r
+      if (_t.readyState === 0) {\r
+        _s._wD('SMSound.play(): Attempting to load "'+_t.sID+'"',1);\r
+        // try to get this sound playing ASAP\r
+        _t._iO.stream = true;\r
+        _t._iO.autoPlay = true;\r
+        // TODO: need to investigate when false, double-playing\r
+        // if (typeof oOptions.autoPlay=='undefined') _tO.autoPlay = true; // only set autoPlay if unspecified here\r
+        _t.load(_t._iO); // try to get this sound playing ASAP\r
+      } else if (_t.readyState == 2) {\r
+        _s._wD('SMSound.play(): Could not load "'+_t.sID+'" - exiting',2);\r
+        return false;\r
+      } else {\r
+        _s._wD('SMSound.play(): "'+_t.sID+'" is loading - attempting to play..',1);\r
+      }\r
+    } else {\r
+      _s._wD('SMSound.play(): "'+_t.sID+'"');\r
+    }\r
+    if (_t.paused) {\r
+      _t.resume();\r
+    } else {\r
+      _t.playState = 1;\r
+      if (!_t.instanceCount || _s.flashVersion == 9) {\r
+               _t.instanceCount++;\r
+         }\r
+      _t.position = (typeof _t._iO.position != 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);\r
+      if (_t._iO.onplay) {\r
+               _t._iO.onplay.apply(_t);\r
+         }\r
+      _t.setVolume(_t._iO.volume,true); // restrict volume to instance options only\r
+      _t.setPan(_t._iO.pan,true);\r
+      _s.o._start(_t.sID,_t._iO.loop||1,(_s.flashVersion==9?_t.position:_t.position/1000));\r
+    }\r
+  };\r
+\r
+  this.start = this.play; // just for convenience\r
+\r
+  this.stop = function(bAll) {\r
+    if (_t.playState == 1) {\r
+      _t.playState = 0;\r
+      _t.paused = false;\r
+      // if (_s.defaultOptions.onstop) _s.defaultOptions.onstop.apply(_s);\r
+      if (_t._iO.onstop) {\r
+               _t._iO.onstop.apply(_t);\r
+         }\r
+      _s.o._stop(_t.sID,bAll);\r
+      _t.instanceCount = 0;\r
+      _t._iO = {};\r
+      // _t.instanceOptions = _t._iO;\r
+    }\r
+  };\r
+\r
+  this.setPosition = function(nMsecOffset,bNoDebug) {\r
+    if (typeof nMsecOffset == 'undefined') {\r
+      nMsecOffset = 0;\r
+    }\r
+    var offset = Math.min(_t.duration,Math.max(nMsecOffset,0)); // position >= 0 and <= current available (loaded) duration\r
+    _t._iO.position = offset;\r
+    if (!bNoDebug) {\r
+      _s._wD('SMSound.setPosition('+nMsecOffset+')'+(nMsecOffset != offset?', corrected value: '+offset:''));\r
+    }\r
+    _s.o._setPosition(_t.sID,(_s.flashVersion==9?_t._iO.position:_t._iO.position/1000),(_t.paused||!_t.playState)); // if paused or not playing, will not resume (by playing)\r
+  };\r
+\r
+  this.pause = function() {\r
+    if (_t.paused || _t.playState === 0) {\r
+         return false;\r
+       }\r
+    _s._wD('SMSound.pause()');\r
+    _t.paused = true;\r
+    _s.o._pause(_t.sID);\r
+    if (_t._iO.onpause) {\r
+         _t._iO.onpause.apply(_t);\r
+       }\r
+  };\r
+\r
+  this.resume = function() {\r
+    if (!_t.paused || _t.playState === 0) {\r
+         return false;\r
+       }\r
+    _s._wD('SMSound.resume()');\r
+    _t.paused = false;\r
+    _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume)\r
+    if (_t._iO.onresume) {\r
+         _t._iO.onresume.apply(_t);\r
+       }\r
+  };\r
+\r
+  this.togglePause = function() {\r
+    _s._wD('SMSound.togglePause()');\r
+    if (!_t.playState) {\r
+      _t.play({position:(_s.flashVersion==9?_t.position:_t.position/1000)});\r
+      return false;\r
+    }\r
+    if (_t.paused) {\r
+      _t.resume();\r
+    } else {\r
+      _t.pause();\r
+    }\r
+  };\r
+\r
+  this.setPan = function(nPan,bInstanceOnly) {\r
+    if (typeof nPan == 'undefined') {\r
+      nPan = 0;\r
+    }\r
+    if (typeof bInstanceOnly == 'undefined') {\r
+      bInstanceOnly = false;\r
+    }\r
+    _s.o._setPan(_t.sID,nPan);\r
+    _t._iO.pan = nPan;\r
+    if (!bInstanceOnly) {\r
+      _t.pan = nPan;\r
+    }\r
+  };\r
+\r
+  this.setVolume = function(nVol,bInstanceOnly) {\r
+    if (typeof nVol == 'undefined') {\r
+      nVol = 100;\r
+    }\r
+    if (typeof bInstanceOnly == 'undefined') {\r
+      bInstanceOnly = false;\r
+    }\r
+    _s.o._setVolume(_t.sID,(_s.muted&&!_t.muted)||_t.muted?0:nVol);\r
+    _t._iO.volume = nVol;\r
+    if (!bInstanceOnly) {\r
+      _t.volume = nVol;\r
+    }\r
+  };\r
+\r
+  this.mute = function() {\r
+    _t.muted = true;\r
+    _s.o._setVolume(_t.sID,0);\r
+  };\r
+\r
+  this.unmute = function() {\r
+    _t.muted = false;\r
+    var hasIO = typeof _t._iO.volume != 'undefined';\r
+    _s.o._setVolume(_t.sID,hasIO?_t._iO.volume:_t.options.volume);\r
+  };\r
+\r
+  // --- "private" methods called by Flash ---\r
+\r
+  this._whileloading = function(nBytesLoaded,nBytesTotal,nDuration) {\r
+    if (!_t._iO.isMovieStar) {\r
+      _t.bytesLoaded = nBytesLoaded;\r
+      _t.bytesTotal = nBytesTotal;\r
+      _t.duration = Math.floor(nDuration);\r
+      _t.durationEstimate = parseInt((_t.bytesTotal/_t.bytesLoaded)*_t.duration,10); // estimate total time (will only be accurate with CBR MP3s.)\r
+      if (_t.readyState != 3 && _t._iO.whileloading) {\r
+       _t._iO.whileloading.apply(_t);\r
+      }\r
+    } else {\r
+      _t.bytesLoaded = nBytesLoaded;\r
+      _t.bytesTotal = nBytesTotal;\r
+      _t.duration = Math.floor(nDuration);\r
+      _t.durationEstimate = _t.duration;\r
+      if (_t.readyState != 3 && _t._iO.whileloading) {\r
+       _t._iO.whileloading.apply(_t);\r
+      }\r
+    }\r
+  };\r
+\r
+  this._onid3 = function(oID3PropNames,oID3Data) {\r
+    // oID3PropNames: string array (names)\r
+    // ID3Data: string array (data)\r
+    _s._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.');\r
+    var oData = [];\r
+    for (var i=0,j=oID3PropNames.length; i<j; i++) {\r
+      oData[oID3PropNames[i]] = oID3Data[i];\r
+      // _s._wD(oID3PropNames[i]+': '+oID3Data[i]);\r
+    }\r
+    _t.id3 = _s._mergeObjects(_t.id3,oData);\r
+    if (_t._iO.onid3) {\r
+      _t._iO.onid3.apply(_t);\r
+    }\r
+  };\r
+\r
+  this._whileplaying = function(nPosition,oPeakData,oWaveformData,oEQData) {\r
+    if (isNaN(nPosition) || nPosition === null) {\r
+      return false; // Flash may return NaN at times\r
+    }\r
+    _t.position = nPosition;\r
+       if (_t._iO.usePeakData && typeof oPeakData != 'undefined' && oPeakData) {\r
+         _t.peakData = {\r
+          left: oPeakData.leftPeak,\r
+          right: oPeakData.rightPeak\r
+         };\r
+       }\r
+       if (_t._iO.useWaveformData && typeof oWaveformData != 'undefined' && oWaveformData) {\r
+         _t.waveformData = oWaveformData;\r
+         /*\r
+         _t.spectrumData = {\r
+          left: oSpectrumData.left.split(','),\r
+          right: oSpectrumData.right.split(',')\r
+         }\r
+         */\r
+       }\r
+       if (_t._iO.useEQData && typeof oEQData != 'undefined' && oEQData) {\r
+         _t.eqData = oEQData;\r
+       }\r
+    if (_t.playState == 1) {\r
+      if (_t._iO.whileplaying) {\r
+       _t._iO.whileplaying.apply(_t); // flash may call after actual finish\r
+      }\r
+      if (_t.loaded && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration-_t.position <= _t._iO.onbeforefinishtime) {\r
+        _s._wD('duration-position &lt;= onbeforefinishtime: '+_t.duration+' - '+_t.position+' &lt= '+_t._iO.onbeforefinishtime+' ('+(_t.duration-_t.position)+')');\r
+        _t._onbeforefinish();\r
+      }\r
+    }\r
+  };\r
+\r
+  this._onload = function(bSuccess) {\r
+    bSuccess = (bSuccess==1?true:false);\r
+    _s._wD('SMSound._onload(): "'+_t.sID+'"'+(bSuccess?' loaded.':' failed to load? - '+_t.url),(bSuccess?1:2));\r
+    if (!bSuccess) {\r
+      if (_s.sandbox.noRemote === true) {\r
+        _s._wD('SMSound._onload(): Reminder: Flash security is denying network/internet access',1);\r
+      }\r
+      if (_s.sandbox.noLocal === true) {\r
+        _s._wD('SMSound._onload(): Reminder: Flash security is denying local access',1);\r
+      }\r
+    }\r
+    _t.loaded = bSuccess;\r
+    _t.readyState = bSuccess?3:2;\r
+    if (_t._iO.onload) {\r
+      _t._iO.onload.apply(_t);\r
+    }\r
+  };\r
+\r
+  this._onbeforefinish = function() {\r
+    if (!_t.didBeforeFinish) {\r
+      _t.didBeforeFinish = true;\r
+      if (_t._iO.onbeforefinish) {\r
+        _s._wD('SMSound._onbeforefinish(): "'+_t.sID+'"');\r
+        _t._iO.onbeforefinish.apply(_t);\r
+      }\r
+    }\r
+  };\r
+\r
+  this._onjustbeforefinish = function(msOffset) {\r
+    // msOffset: "end of sound" delay actual value (eg. 200 msec, value at event fire time was 187)\r
+    if (!_t.didJustBeforeFinish) {\r
+      _t.didJustBeforeFinish = true;\r
+      if (_t._iO.onjustbeforefinish) {\r
+        _s._wD('SMSound._onjustbeforefinish(): "'+_t.sID+'"');\r
+        _t._iO.onjustbeforefinish.apply(_t);\r
+      }\r
+    }\r
+  };\r
+\r
+  this._onfinish = function() {\r
+    // sound has finished playing\r
+\r
+    // TODO: calling user-defined onfinish() should happen after setPosition(0)\r
+    // OR: onfinish() and then setPosition(0) is bad.\r
+\r
+    if (_t._iO.onbeforefinishcomplete) {\r
+      _t._iO.onbeforefinishcomplete.apply(_t);\r
+    }\r
+    // reset some state items\r
+    _t.didBeforeFinish = false;\r
+    _t.didJustBeforeFinish = false;\r
+    if (_t.instanceCount) {\r
+      _t.instanceCount--;\r
+      if (!_t.instanceCount) {\r
+        // reset instance options\r
+        // _t.setPosition(0);\r
+        _t.playState = 0;\r
+        _t.paused = false;\r
+        _t.instanceCount = 0;\r
+        _t.instanceOptions = {};\r
+        if (_t._iO.onfinish) {\r
+          _s._wD('SMSound._onfinish(): "'+_t.sID+'"');\r
+          _t._iO.onfinish.apply(_t);\r
+        }\r
+      }\r
+    } else {\r
+      // _t.setPosition(0);\r
+    }\r
+  };\r
+\r
+  this._onmetadata = function(oMetaData) {\r
+    // movieStar mode only\r
+    _s._wD('SMSound.onmetadata()');\r
+    // Contains a subset of metadata. Note that files may have their own unique metadata.\r
+    // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html\r
+    if (!oMetaData.width && !oMetaData.height) {\r
+         _s._wD('No width/height given, assuming defaults');\r
+         oMetaData.width = 320;\r
+         oMetaData.height = 240;\r
+    }\r
+    _t.metadata = oMetaData; // potentially-large object from flash\r
+    _t.width = oMetaData.width;\r
+    _t.height = oMetaData.height;\r
+    if (_t._iO.onmetadata) {\r
+      _s._wD('SMSound._onmetadata(): "'+_t.sID+'"');\r
+      _t._iO.onmetadata.apply(_t);\r
+    }\r
+    _s._wD('SMSound.onmetadata() complete');\r
+  };\r
+\r
+  this._onbufferchange = function(bIsBuffering) {\r
+    if (bIsBuffering == _t.isBuffering) {\r
+      // ignore initial "false" default, if matching\r
+      return false;\r
+    }\r
+    _t.isBuffering = (bIsBuffering==1?true:false);\r
+    if (_t._iO.onbufferchange) {\r
+      _s._wD('SMSound._onbufferchange(): '+bIsBuffering);\r
+      _t._iO.onbufferchange.apply(_t);\r
+    }\r
+  };\r
+\r
+  }; // SMSound()\r
+\r
+  // register a few event handlers\r
+  if (window.addEventListener) {\r
+    window.addEventListener('focus',_s.handleFocus,false);\r
+    window.addEventListener('load',_s.beginDelayedInit,false);\r
+    window.addEventListener('unload',_s.destruct,false);\r
+    if (_s._tryInitOnFocus) {\r
+      window.addEventListener('mousemove',_s.handleFocus,false); // massive Safari focus hack\r
+    }\r
+  } else if (window.attachEvent) {\r
+    window.attachEvent('onfocus',_s.handleFocus);\r
+    window.attachEvent('onload',_s.beginDelayedInit);\r
+    window.attachEvent('unload',_s.destruct);\r
+  } else {\r
+    // no add/attachevent support - safe to assume no JS -> Flash either.\r
+    _s._debugTS('onload',false);\r
+    soundManager.onerror();\r
+    soundManager.disable();\r
+  }\r
+\r
+  if (document.addEventListener) {\r
+       document.addEventListener('DOMContentLoaded',_s.domContentLoaded,false);\r
+  }\r
+\r
+} // SoundManager()\r
+\r
+soundManager = new SoundManager();
\ No newline at end of file
diff --git a/tools/eztelemeta/design/standard/stylesheets/page-player.css b/tools/eztelemeta/design/standard/stylesheets/page-player.css
new file mode 100644 (file)
index 0000000..92b7a9d
--- /dev/null
@@ -0,0 +1,758 @@
+/*\r
+\r
+ SoundManager 2: "page as playlist" example\r
+ ------------------------------------------\r
+\r
+ Clicks on links to MP3s are intercepted via JS, calls are\r
+ made to SoundManager to load/play sounds. CSS classes are\r
+ appended to the LI parent, which are used to highlight the\r
+ current play state and so on.\r
+\r
+ Class names are applied in addition to "sm2_link" base.\r
+\r
+ Default:\r
+\r
+ sm2_link\r
+\r
+ Additional states:\r
+\r
+ sm2_playing\r
+ sm2_paused\r
+\r
+ eg.\r
+\r
+ <!-- default -->\r
+ <li class="sm2_link"><a href="some.mp3">some.mp3</a></li>\r
+\r
+ <!-- playing -->\r
+ <li class="sm2_link sm2_playing"><a href="some.mp3">some.mp3</a></li>\r
+\r
+ The script also injects an HTML template containing control bar\r
+ and timing elements, which can also be targeted with CSS.\r
+\r
+\r
+ Note you don't necessarily require ul.playlist for your use\r
+ if only using one style on a page. You can just use .sm2_link\r
+ and so on, but isolate the CSS you want.\r
+\r
+ Side note: Would do multiple class definitions eg.\r
+\r
+ li.sm2_default.sm2_playing{}\r
+\r
+ .. except IE 6 has a parsing bug which may break behaviour,\r
+ applying sm2_playing {} even when the class is set to sm2_default.\r
+\r
+\r
+ If you want to make your own UI from scratch, here is the base:\r
+\r
+ Default + hover state, "click to play":\r
+\r
+ li.sm2_link {}\r
+ li.sm2_link:hover {}\r
+\r
+ Playing + hover state, "click to pause":\r
+\r
+ li.sm2_playing {}\r
+ li.sm2_playing:hover {}\r
+\r
+ Paused + hover state, "click to resume":\r
+\r
+ li.sm2_paused {}\r
+ li.sm2_paused:hover {}\r
+\r
+*/\r
+\r
+\r
+/* background-image-based CSS3 example */\r
+\r
+.spectrum-container {\r
+ display:none;\r
+}\r
+\r
+ul.use-spectrum li.sm2_playing .spectrum-container {\r
+ position:absolute;\r
+ left:0px;\r
+ top:0px;\r
+ margin-left:-266px;\r
+ margin-top:-1px;\r
+ display:block;\r
+ background-color:#5588bb;\r
+ border:1px solid #99ccff;\r
+ -moz-border-radius:4px;\r
+ -webkit-border-radius:4px;\r
+ border-radius:4px;\r
+}\r
+\r
+ul.use-spectrum .spectrum-box {\r
+ position:relative;\r
+ width:255px;\r
+ font-size:1em;\r
+ padding:2px 0px;\r
+ height:1.2em;\r
+ overflow:hidden;\r
+}\r
+\r
+ul.use-spectrum .spectrum-box .spectrum {\r
+ position:absolute;\r
+ left:0px;\r
+ top:-2px;\r
+ margin-top:20px;\r
+ display:block;\r
+ font-size:1px;\r
+ width:1px;\r
+ height:1px; /* set to 50px for a thick line, 1px for a thin line, etc. */\r
+ overflow:hidden;\r
+ background-color:#fff;\r
+}\r
+\r
+ul.playlist {\r
+ list-style-type:none;\r
+ margin:0px;\r
+ padding:0px;\r
+\r
+}\r
+\r
+ul.playlist li {\r
+ /* assume all items will be sounds rather than wait for onload etc. in this example.. may differ for your uses. */\r
+ position:relative;\r
+ display:block;\r
+ width:auto;\r
+ font-size:2em;\r
+ color:#666;\r
+ padding:0.25em 0.5em 0.25em 0.5em;\r
+ border:none;\r
+ letter-spacing:-1px; /* ZOMG WEB X.0. ;) */\r
+ background-color:#f9f9f9;\r
+ -webkit-transition-property: hover;\r
+ -webkit-transition: background-color 0.15s ease-in-out;\r
+}\r
+\r
+ul.playlist li a {\r
+ display:block;\r
+ text-decoration:none;\r
+ font-weight:normal;\r
+ color:#000;\r
+ font-size:120%;\r
+ outline:none;\r
+ position:relative;\r
+ z-index:2;\r
+ text-shadow: 0 0 0 #fff; /* stupid Safari "fat" font rendering tweak */\r
+}\r
+\r
+ul.playlist li.sm2_playing,\r
+ul.playlist li.sm2_paused,\r
+ul.playlist li.sm2_playing a {\r
+ color:#fff;\r
+ border-radius:3px;\r
+ -webkit-border-radius:3px;\r
+ -moz-border-radius:3px;\r
+}\r
+\r
+ul.playlist li:hover {\r
+ background-color:#eee;\r
+}\r
+\r
+ul.playlist li:hover a {\r
+ color:#333;\r
+}\r
+\r
+ul.playlist li.sm2_playing,\r
+ul.playlist li.sm2_playing:hover {\r
+ background-color:#6699cc;\r
+}\r
+\r
+ul.playlist li.sm2_paused {\r
+ background-color:#999;\r
+}\r
+\r
+ul.playlist li.sm2_playing:hover a,\r
+ul.playlist li.sm2_paused a {\r
+ color:#fff;\r
+}\r
+\r
+ul.playlist li .controls {\r
+ display:none;\r
+}\r
+\r
+ul.playlist li .peak,\r
+ul.playlist.use-peak li .peak {\r
+ display:none;\r
+ position:absolute;\r
+ top:0.55em;\r
+ right:0.5em;\r
+}\r
+\r
+ul.playlist li.sm2_playing .controls,\r
+ul.playlist li.sm2_paused .controls {\r
+ position:relative;\r
+ display:block;\r
+}\r
+\r
+ul.playlist.use-peak li.sm2_playing .peak,\r
+ul.playlist.use-peak li.sm2_paused .peak {\r
+ display:inline;\r
+ display:inline-block;\r
+}\r
+\r
+ul.playlist.use-peak li .peak {\r
+ display:none; /* IE 7 */\r
+}\r
+\r
+ul.playlist li.sm2_paused .controls {\r
+ background-color:#666;\r
+}\r
+\r
+ul.playlist li:hover .controls .statusbar {\r
+ position:relative;\r
+ cursor:ew-resize;\r
+ cursor:-moz-grab;\r
+ cursor:grab;\r
+}\r
+\r
+ul.playlist li.sm2_paused .controls .statusbar {\r
+ background-color:#ccc;\r
+}\r
+\r
+ul.playlist li .controls {\r
+ position:relative;\r
+ margin-top:0.25em;\r
+ margin-bottom:0.25em;\r
+ background-color:#99ccff;\r
+}\r
+\r
+ul.playlist li .controls .statusbar {\r
+ position:relative;\r
+ height:0.5em;\r
+ background-color:#ccddff;\r
+ border:2px solid #fff;\r
+ border-radius:2px;\r
+ -moz-border-radius:2px;\r
+ -webkit-border-radius:2px;\r
+ overflow:hidden;\r
+ cursor:-moz-grab;\r
+ cursor:grab;\r
+}\r
+\r
+ul.playlist li .controls.dragging .statusbar {\r
+ cursor:-moz-grabbing;\r
+ cursor:grabbing;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .position,\r
+ul.playlist li .controls .statusbar .loading,\r
+ul.playlist li .controls .statusbar .annotation {\r
+ position:absolute;\r
+ left:0px;\r
+ top:0px;\r
+ height:0.5em;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .position {\r
+ background-color:#336699;\r
+ border-right:3px solid #336699;\r
+ border-radius:3px;\r
+ -moz-border-radius:3px;\r
+ -webkit-border-radius:3px;\r
+}\r
+\r
+ul.playlist li.sm2_paused .controls .statusbar .position {\r
+ background-color:#666;\r
+ border-color:#666;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .loading {\r
+ background-color:#eee;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .position,\r
+ul.playlist li .controls .statusbar .loading {\r
+ width:0px;\r
+}\r
+\r
+ul.playlist li.sm2_playing a.sm2_link,\r
+ul.playlist li.sm2_paused a.sm2_link {\r
+ margin-right:4.5em; /* room for timing stuff */\r
+}\r
+\r
+ul.playlist li .timing {\r
+ position:absolute;\r
+ display:none;\r
+ text-align:right;\r
+ right:1em;\r
+ top:1em;\r
+ width:auto;\r
+ height:1em;\r
+ /*\r
+ padding:4px 5px 2px 5px;\r
+ *padding:3px 5px 3px 5px;\r
+ */\r
+ padding:3px 5px;\r
+ background-color:#5588bb;\r
+ border:1px solid #99ccff;\r
+ -moz-border-radius:4px;\r
+ -khtml-border-radius:4px;\r
+ border-radius:4px;\r
+ letter-spacing:0px;\r
+ font:44% monaco,"VT-100",terminal,"lucida console",courier,system;\r
+ line-height:1em;\r
+ vertical-align:middle;\r
+}\r
+\r
+ul.playlist.use-peak li .timing {\r
+ right:4.25em;\r
+}\r
+\r
+ul.playlist li:hover .timing {\r
+ z-index:2;\r
+}\r
+\r
+ul.playlist li .timing div.sm2_timing {\r
+ margin:0px;\r
+ padding:0px;\r
+ margin-top:-1em;\r
+ text-shadow: 0 0 0 #fff; /* stupid Safari "fat" font rendering tweak */\r
+}\r
+\r
+ul.playlist li.sm2_playing .timing,\r
+ul.playlist li.sm2_paused .timing {\r
+ display:block;\r
+}\r
+\r
+ul.playlist li.sm2_paused .timing .sm2_position {\r
+ text-decoration:blink; /* hee hee. first actual appropriate use? :D */\r
+}\r
+\r
+ul.playlist li.sm2_paused .timing,\r
+ul.playlist.use-peak li.sm2_paused .peak {\r
+ background-color:#888;\r
+ border-color:#ccc;\r
+}\r
+\r
+/* peak data */\r
+\r
+/* ul.playlist ... */\r
+\r
+ul.playlist.use-peak li .peak {\r
+ display:none;\r
+ zoom:1;\r
+ border:1px solid #99ccff;\r
+ padding:2px;\r
+ height:0.55em;\r
+ -moz-border-radius:4px;\r
+ -khtml-border-radius:4px;\r
+ border-radius:4px;\r
+ background-color:#5588bb;\r
+ width:0.8em;\r
+ height:0.55em;\r
+ margin-top:-3px;\r
+}\r
+\r
+ul.playlist.use-peak li .peak-box {\r
+ position:relative;\r
+ width:100%;\r
+ height:0.55em;\r
+ overflow:hidden;\r
+}\r
+\r
+ul.playlist li .peak .l,\r
+ul.playlist li .peak .r {\r
+ position:absolute;\r
+ left:0px;\r
+ top:0px;\r
+ width:7px;\r
+ height:50px;\r
+ background:#fff;\r
+ border:1px solid #fff;\r
+ -moz-border-radius:1px;\r
+ -khtml-border-radius:1px;\r
+ margin-top:1em;\r
+}\r
+\r
+ul.playlist li .peak .l {\r
+ margin-right:1px;\r
+}\r
+\r
+ul.playlist li .peak .r {\r
+ left:10px;\r
+}\r
+\r
+#control-template {\r
+ display:none;\r
+}\r
+\r
+/*\r
+ ------------------------------------------\r
+ -- annotations (sub-tracks, notes etc.) --\r
+ ------------------------------------------\r
+*/\r
+\r
+ul.playlist li a.sm2_link .metadata {\r
+ display:none; /* hide by default */\r
+}\r
+\r
+ul.playlist li.sm2_paused a.sm2_link .metadata,\r
+ul.playlist li.sm2_playing a.sm2_link .metadata {\r
+ display:inline;\r
+}\r
+\r
+ul.playlist li ul {\r
+ list-style-type:none;\r
+ margin:0px;\r
+ padding:0px;\r
+ position:relative;\r
+ font-size:small;\r
+ display:none;\r
+}\r
+\r
+ul.playlist li ul li {\r
+ position:relative;\r
+ margin:0px;\r
+ padding:2px 3px;\r
+ border:1px solid transparent;\r
+ -moz-border-radius:6px;\r
+ -khtml-border-radius:6px;\r
+ border-radius:6px;\r
+ margin-right:1em;\r
+ font-family:helvetica,verdana,tahoma,arial,"sans serif";\r
+ font-size:x-small;\r
+ font-weight:lighter;\r
+ letter-spacing:0px;\r
+ background-color:transparent;\r
+ opacity:0.66;\r
+}\r
+\r
+ul.playlist li ul li:hover {\r
+ opacity:1;\r
+ background-color:#fff;\r
+ border-color:#ccc;\r
+ color:#666;\r
+}\r
+\r
+ul.playlist li.sm2_playing ul li,\r
+ul.playlist li.sm2_paused ul li {\r
+ color:#fff;\r
+}\r
+\r
+ul.playlist li.sm2_playing ul li:hover {\r
+ background-color:#fff;\r
+ color:#5588bb;\r
+ border-color:#336699;\r
+ opacity:0.9;\r
+}\r
+\r
+ul.playlist li.sm2_paused ul li:hover {\r
+ background-color:#888;\r
+}\r
+\r
+/* metadata */\r
+\r
+ul.playlist li .metadata .duration {\r
+ /* optional timing data */\r
+ display:none;\r
+}\r
+\r
+ul.playlist li .metadata ul li p {\r
+ margin:0px;\r
+ padding:0px;\r
+}\r
+\r
+ul.playlist li .metadata ul li span {\r
+ display:none;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation {\r
+ position:absolute;\r
+ background-color:transparent;\r
+ top:0px;\r
+ color:#666;\r
+ text-align:right;\r
+ margin-left:10px;\r
+ height:0.5em;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation:hover {\r
+ z-index:12; /* sit on top of note */\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation span.bubble {\r
+ /* using &middot; */\r
+ display:inline-block;\r
+ background-color:#fff;\r
+ border:1px solid #666;\r
+ border-radius:6px;\r
+ -moz-border-radius:6px;\r
+ -webkit-border-radius:6px;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation span {\r
+ display:block;\r
+ background:transparent url(../image/divot.png) no-repeat 50% 0px;\r
+ width:15px;\r
+ margin-left:-15px;\r
+ height:12px;\r
+ text-align:center;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation.alt {\r
+ top:auto;\r
+ bottom:0px;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation span:hover {\r
+ cursor:none; /* Fx3 rules. */\r
+ margin-top:0.1em;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation.alt span:hover {\r
+ margin-top:-0.1em;\r
+}\r
+\r
+ul.playlist li .controls .statusbar .annotation.alt span {\r
+ background:transparent url(../image/divot-bottom.png) no-repeat 50% bottom;\r
+}\r
+\r
+ul.playlist li .note {\r
+ position:absolute;\r
+ display:none;\r
+ left:0px;\r
+ top:0px;\r
+ z-index:10;\r
+ font-size:x-small;\r
+ padding:2px 4px 2px 4px;\r
+ width:auto;\r
+ color:#666;\r
+ background-color:#fff;\r
+ border:1px solid #ccc;\r
+ border-radius:6px;\r
+ -moz-border-radius:6px;\r
+ -webkit-border-radius:6px;\r
+ font-style:normal;\r
+ font-weight:bold;\r
+ font-family:arial,tahoma,verdana,"sans serif";\r
+ letter-spacing:0px;\r
+ margin-top:1.1em;\r
+}\r
+\r
+ul.playlist li .note.alt {\r
+ margin-top:-1.32em;\r
+}\r
+\r
+ul.playlist li .note:hover {\r
+ display:block !important;\r
+}\r
+\r
+ul.playlist li .sm2_divider {\r
+ font-size:0.75em;\r
+}\r
+\r
+ul.playlist li .sm2_metadata {\r
+ font-size:0.65em;\r
+}\r
+\r
+\r
+/* \r
+ ---------------------------------\r
+ -- alternate (optional) themes --\r
+ ---------------------------------\r
+*/\r
+\r
+ul.playlist.dark li.sm2_playing a {\r
+ color:#fff;\r
+}\r
+\r
+ul.playlist.dark li.sm2_playing .timing,\r
+ul.playlist.use-peak.dark li.sm2_playing .peak {\r
+ color:#999;\r
+}\r
+\r
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container {\r
+ background-color:#222;\r
+ border-color:#444;\r
+}\r
+\r
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container .spectrum {\r
+ background-color:#999;\r
+}\r
+\r
+ul.playlist.dark li.sm2_paused {\r
+ background-color:#333;\r
+}\r
+\r
+ul.playlist.dark li.sm2_paused a {\r
+ color:#999;\r
+}\r
+\r
+ul.playlist.dark li.sm2_playing,\r
+ul.playlist.dark li.sm2_playing:hover {\r
+ background-color:#333;\r
+}\r
+\r
+ul.playlist.dark li:hover .controls .statusbar {\r
+ background-color:#666;\r
+}\r
+\r
+ul.playlist.dark li .controls {\r
+ background-color:#333;\r
+}\r
+\r
+ul.playlist.dark li .controls .statusbar {\r
+ background-color:#666;\r
+ border-color:#444;\r
+}\r
+\r
+ul.playlist.dark li .controls .statusbar .position {\r
+ background-color:#111;\r
+ border-right:3px solid #111;\r
+ border-radius:3px;\r
+ -moz-border-radius:3px;\r
+ -webkit-border-radius:3px;\r
+}\r
+\r
+ul.playlist.dark li .controls .statusbar .loading {\r
+ background-color:#444;\r
+}\r
+\r
+ul.playlist.dark li .timing,\r
+ul.playlist.use-peak.dark li .peak {\r
+ background-color:#222;\r
+ border-color:#444;\r
+}\r
+\r
+ul.playlist.dark.use-peak li .peak .l,\r
+ul.playlist.dark.use-peak li .peak .r {\r
+ border-color:#444;\r
+ background-color:#999;\r
+}\r
+\r
+\r
+/* gold theme */\r
+\r
+ul.playlist.gold li.sm2_paused {\r
+ background-color:#996600;\r
+}\r
+\r
+ul.playlist.gold li.sm2_playing,\r
+ul.playlist.gold li.sm2_playing:hover {\r
+ background-color:#cc9900;\r
+}\r
+\r
+ul.playlist.gold li .controls {\r
+ background-color:transparent;\r
+}\r
+\r
+ul.playlist.gold li .controls .statusbar {\r
+ background-color:#fff;\r
+ border-color:#fff;\r
+}\r
+\r
+ul.playlist.gold li .controls .statusbar .position {\r
+ background-color:#996600;\r
+ border-right:3px solid #996600;\r
+ border-radius:3px;\r
+ -moz-border-radius:3px;\r
+ -webkit-border-radius:3px;\r
+}\r
+\r
+ul.playlist.gold li .controls .statusbar .loading {\r
+ background-color:#ffeedd;\r
+}\r
+\r
+ul.playlist.gold li .timing,\r
+ul.playlist.use-peak.gold li .peak {\r
+ background-color:#CC9900;\r
+ border-color:#ffcc33;\r
+}\r
+\r
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container {\r
+ background-color:#cc9900;\r
+ border-color:#ffcc33;\r
+}\r
+\r
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container .spectrum {\r
+ background-color:#fff;\r
+}\r
+\r
+ul.playlist.gold.use-peak li .peak .l,\r
+ul.playlist.gold.use-peak li .peak .r {\r
+ border-color:#fff;\r
+ background-color:#fff;\r
+}\r
+\r
+\r
+/* ZOMG PONIES!!!ONEONEONE */\r
+\r
+ul.playlist.bubblegum li a {\r
+ font-family:"comic sans ms",verdana,arial,tahoma,"sans serif"; /* heh */\r
+}\r
+\r
+ul.playlist.bubblegum li.sm2_paused,\r
+ul.playlist.bubblegum li.sm2_paused:hover {\r
+ background-color:#ffccee;\r
+}\r
+\r
+ul.playlist.bubblegum li.sm2_paused a,\r
+ul.playlist.bubblegum li.sm2_paused:hover a,\r
+ul.playlist.bubblegum li.sm2_paused .timing,\r
+ul.playlist.use-peak.bubblegum li.sm2_paused .peak {\r
+ color:#ff6699;\r
+}\r
+\r
+ul.playlist.bubblegum li:hover {\r
+ background-color:#ffddee;\r
+}\r
+\r
+ul.playlist.bubblegum li.sm2_playing,\r
+ul.playlist.bubblegum li.sm2_playing:hover {\r
+ background-color:#ff7799;\r
+}\r
+\r
+ul.playlist.bubblegum li .controls {\r
+ background-color:transparent;\r
+}\r
+\r
+ul.playlist.bubblegum li .controls .statusbar {\r
+ background-color:#fff;\r
+ border-color:#fff;\r
+}\r
+\r
+ul.playlist.bubblegum li .controls .statusbar .position {\r
+ background-color:#ffaacc;\r
+ border-right:3px solid #ffaacc;\r
+ border-radius:3px;\r
+ -moz-border-radius:3px;\r
+ -webkit-border-radius:3px;\r
+}\r
+\r
+ul.playlist.bubblegum li .controls .statusbar .loading {\r
+ background-color:#ffeedd;\r
+}\r
+\r
+ul.playlist.bubblegum li .timing,\r
+ul.playlist.use-peak.bubblegum li .peak {\r
+ background-color:#ffaacc;\r
+ border-color:#ffccee;\r
+}\r
+\r
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container {\r
+ background-color:#ffaacc;\r
+ border-color:#ffccee;\r
+}\r
+\r
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container .spectrum {\r
+ background-color:#fff;\r
+}\r
+\r
+ul.playlist.bubblegum.use-peak li .peak .l,\r
+ul.playlist.bubblegum.use-peak li .peak .r {\r
+ border-color:#fff;\r
+ background-color:#fff;\r
+}\r
+\r
+\r
+ul.playlist.shiny li.sm2_paused,\r
+ul.playlist.shiny li.sm2_playing {\r
+ background-image:url(../image/top-highlight.png);\r
+ background-repeat:repeat-x;\r
+ background-position:0px -1px;\r
+ _background-image:none; /* can't be bothered with IE 6. */\r
+}
\ No newline at end of file
diff --git a/tools/eztelemeta/design/standard/swf/soundmanager2.swf b/tools/eztelemeta/design/standard/swf/soundmanager2.swf
new file mode 100644 (file)
index 0000000..8a9711c
Binary files /dev/null and b/tools/eztelemeta/design/standard/swf/soundmanager2.swf differ
diff --git a/tools/eztelemeta/design/standard/swf/soundmanager2_flash9.swf b/tools/eztelemeta/design/standard/swf/soundmanager2_flash9.swf
new file mode 100644 (file)
index 0000000..75366d0
Binary files /dev/null and b/tools/eztelemeta/design/standard/swf/soundmanager2_flash9.swf differ
index 4d03e203f3be31c9593d848149531e89dfa8a730..7835bfeb7baba93ec62cc24f0882e1873777eac1 100644 (file)
@@ -3,3 +3,9 @@ DesignExtensions[]=eztelemeta
 
 [StylesheetSettings]
 CSSFileList[]=eztelemeta.css
+CSSFileList[]=page-player.css
+
+[JavaScriptSettings]
+JavaScriptList[]=init.js
+JavaScriptList[]=soundmanager2-nodebug-jsmin.js
+JavaScriptList[]=page-player.js