diff options
306 files changed, 33428 insertions, 0 deletions
diff --git a/docs/dymaxion/dymaxion.js b/docs/dymaxion/dymaxion.js new file mode 100644 index 0000000..d66d2ed --- /dev/null +++ b/docs/dymaxion/dymaxion.js @@ -0,0 +1,777 @@ +var currentSearch = '' +var currentThread = '' +var keyboard_mode = "navigate" +var idleTimeout = undefined +var fadeInterval = undefined +var faded = false +var qLeftPadding = 20 +/* *************************************************** + 1. page loads + 2. user seraches "dodpop" + << thread list received + 2a user picks thread + << file list received + 3. user picks song 1 + << player enqueues thread + << song 1 starts playing + << if no action is taken, song 2 will be next.. +*************************************************** */ + +var Dymaxion = + { + count: 0, + pos: 0, + nowPlaying: {thread:0,file:0}, + index: {count:0,rows:[],pos:0}, + search: {count:0,rows:[],pos:0}, + thread: {count:0,rows:[],pos:0}, + comment: [], + files: [], + } +var Player = + { + currentSound: false, + nextSound: false, + count: 0, + rows: [], + pos: 0, + threadid: 0, + file: 0, + justbeforefinishMutex: false, + playing: false, + play: function (pos) + { + Player.threadid = Thread.threadid + Player.rows = Dymaxion.thread.rows + Player.count = Dymaxion.thread.rows.length -1 + Player.pos = pos + // 0 thread 1 filename 2 title 3 subtitle + if (Player.pos < Player.count) + Player.playFile(Thread.threadid, Player.rows[Player.pos][1]) + }, + playPrev: function () + { + Player.pos = Player.prev() + if (Thread.threadid === Player.threadid) + Cursor.select(Player.pos) + if (Player.pos < Player.count) + Player.playFile(Thread.threadid, Player.rows[Player.pos][1]) + }, + playNext: function () + { + Player.pos = Player.next() + if (Thread.threadid === Player.threadid) + Cursor.select(Player.pos) + if (Player.pos < Player.count) + Player.playFile(Thread.threadid, Player.rows[Player.pos][1]) + }, + playFile: function (thread, filename) + { + warn('playing '+Player.pos) + if (soundManager.supported()) + { + if (Player.currentSound) + { + Player.currentSound.stop() + Player.currentSound.destruct() + Player.currentSound = false + Player.onjustbeforefinishMutex = '' + } + Player.currentSound = soundManager.createSound + ({ + id: filename, + url: '/bucky/data/'+thread+'/'+filename, + // onload: [ event handler function object ], + }); + Player.currentSound.play(); + } + }, + onbeforefinish: function () + { + var pos = Player.next() + var thread = Thread.threadid + var filename = Player.rows[pos][1] + Player.onjustbeforefinishMutex = filename + warn('loading '+filename) + Player.nextSound = soundManager.createSound + ({ + id: filename, + url: '/bucky/data/'+thread+'/'+filename, + }); + }, + onjustbeforefinish: function () + { + Player.pos = Player.next() + var filename = Player.rows[Player.pos][1] + if (filename === Player.onjustbeforefinishMutex) + { + Player.nextSound.play(); + warn('playing '+Player.pos) + } + else + { + warn('MUTEX: new sound!') + } + }, + cursorPush: function () + { + warn("pushing cursor") + if (Thread.threadid === Player.threadid) + Cursor.select(Player.pos) + }, + onfinish: function () + { + //setTimeout(Player.cursorPush, 2500) + Player.cursorPush() + Player.currentSound.destruct() + Player.currentSound = Player.nextSound + }, + prev: function () + { + var pos = this.pos - 1 + if (pos < 0) + pos = this.count - 1 + return pos + }, + next: function () + { + var pos = this.pos + 1 + if (pos == this.count) + pos = 0 + return pos + }, + loadSoundManager: function () + { + soundManager.debugMode = false + soundManager.url = '/dymaxion/' + soundManager.useFlashBlock = false + soundManager.onready(function() + { + if (soundManager.supported()) + warn('soundmanager loaded') + else + warn('soundmanager did not load!') + }); + soundManager.defaultOptions.onjustbeforefinish = Player.onjustbeforefinish + soundManager.defaultOptions.onbeforefinish = Player.onbeforefinish + soundManager.defaultOptions.onfinish = Player.onfinish + }, + } +var Cursor = + { + mode: "search", + count: 0, + rows: [], + pos: 0, + perpage: 8, + playing: -1, + redrawPage: function () + { + var list = '' + var page = Math.floor(this.pos/this.perpage) + var pos = this.perpage * page + warn('page# ' + page) + for (var i = 0; i < this.perpage && pos < this.count; i++) + { + // 0 thread 1 filename 2 title 3 subtitle + var row = this.rows[pos] + if (row[3]) + { + list += "<li id='cursor-"+pos+"' data-thread=\""+row[0]+"\" data-filename=\""+row[1]+"\" class='twoline'><h2>"+row[2]+"</h2>" + list += "<h3>"+row[3]+"</h3>" + list += "</li>" + } + else + { + list += "<li id='cursor-"+pos+"' data-thread=\""+row[0]+"\" data-filename=\""+row[1]+"\"><h2>"+row[2]+"</h2>" + list += "</li>" + } + pos += 1 + } + $('#list').html(list) + if (this.pos < this.perpage) + $('#pageup').hide() + else + $('#pageup').show() + if (Math.floor((this.count-1)/this.perpage) === page) + $('#pagedown').hide() + else + $('#pagedown').show() + if (this.playing !== -1) + $('#cursor-'+this.playing).addClass("playing") + $('#list').show() + }, + selectFirst: function () + { + this.select(0) + }, + selectPageUp: function () + { + this.pos -= this.perpage + if (this.pos < 0) + this.pos = this.count - 1 + this.redrawPage() + this.selectOn(this.pos) + }, + selectPageDown: function () + { + this.pos += this.perpage + if (this.pos >= this.count) + this.pos = 0 + this.redrawPage() + this.selectOn(this.pos) + }, + selectPrev: function () + { + this.selectOff(this.pos) + this.pos = this.prev() + if (this.pos % this.perpage === this.perpage - 1 || this.pos === this.count - 1) + this.redrawPage() + this.selectOn(this.pos) + }, + selectNext: function () + { + this.selectOff(this.pos) + this.pos = this.next() + if (this.pos % this.perpage === 0) + this.redrawPage() + this.selectOn(this.pos) + }, + selectOff: function (n) + { + $('#cursor-'+n).removeClass("selected") + }, + selectOn: function (n) + { + $('#cursor-'+n).addClass("selected") + }, + select: function (n) + { + this.selectOff(this.pos) + this.pos = n + this.redrawPage() + warn("AT "+n) + this.selectOn(n) + }, + prev: function () + { + var pos = this.pos - 1 + if (pos < 0) + pos = this.count - 1 + return pos + }, + next: function () + { + var pos = this.pos + 1 + if (pos == this.count) + pos = 0 + return pos + }, + chooseThis: function () + { + return this.choose(this.pos) + }, + choose: function (pos) + { + warn("choose "+pos+" in "+this.mode) + switch (this.mode) + { + case "index": + Dymaxion.search.count = 0 + Dymaxion.index.pos = pos + var thread = $('#cursor-'+pos).attr('data-thread') + var filename = $('#cursor-'+pos).attr('data-filename') + Thread.load(thread, filename) + break + case "search": + Dymaxion.search.pos = pos + var thread = $('#cursor-'+pos).attr('data-thread') + var filename = $('#cursor-'+pos).attr('data-filename') + Thread.load(thread, filename) + break + case "thread": + var thread = $('#cursor-'+pos).attr('data-thread') + var filename = $('#cursor-'+pos).attr('data-filename') + if (this.playing != -1) + $('#cursor-'+this.playing).removeClass("playing") + this.playing = pos + $('#cursor-'+pos).addClass("playing") + Player.play(pos) + break + } + }, + report: function (cmd) + { + warn("> "+cmd+" "+this.pos+" "+this.count) + }, + } +function kp (e) + { + var evt = window.event ? window.event : e + var key = evt.keyCode ? evt.keyCode : e.which + if (faded) + unFade() + else + clearTimeout(idleTimeout) +// warn("keypress " + evt.type + " on " + key) + return keypress(key) + } +function keypress (key) + { + if (keyboard_mode == 'textentry') + return keypress_textentry(key) + document.getElementById('username').innerHTML = '"'+ key +'"' + switch (key) + { + case 27: // escape + Search.lastAutocomplete = ''; + $('#q').blur() + $('#searchbox').hide() + $('header').show() + break + case 33: // pageup + Cursor.selectPageUp(); + break + case 34: // pagedown + Cursor.selectPageDown(); + break + case 38: // up + Cursor.selectPrev(); + break + case 40: // down + Cursor.selectNext(); + break + case 37: // left + if (Cursor.mode === "thread" && Dymaxion.search.count !== 0) + { + Search.display() + } + else + { + Index.display() + } + break + case 39: // right + case 13: // enter + Cursor.chooseThis(); + break + case 177: // prev + case 90: // z + ///////////////// prev + if (Player.count) + Player.playPrev() + break + case 179: // play/pause + case 88: // x + if (Player.currentSound) + Player.currentSound.play() + break + case 67: // c + if (Player.currentSound) + Player.currentSound.togglePause() + break + case 178: // stop + case 86: // v + if (Player.currentSound) + Player.currentSound.stop() + break + case 176: // next + case 66: // b + ///////////////// advance + if (Player.count) + Player.playNext() + break + case 82: // r + window.location.reload() + break + case 71: // g + case 70: // f + show_searchbox() + break + case 72: // h + warn("> HALP!") + Thread.load(1716) + break + case 73: // i + Index.display() + break + } + idleTimeout = setTimeout("startFader()", 1000) + return false + } +function startFader() + { + faded = true + fadeamt = 0.5 + fadeInterval = setInterval("fade()", 420); + } +function fade() + { + if (fadeamt > 0.02) + fadeamt -= 0.0007 + else + { + clearInterval(fadeInterval) + fadeamt = 0.03 + } + $('#listbox').css('opacity', fadeamt) + $('#msg').css('opacity', fadeamt) + $('#pageup').css('opacity', fadeamt) + $('#pagedown').css('opacity', fadeamt) + $('#hello').css('opacity', fadeamt) + $('header').css('opacity', fadeamt) + } +function unFade() + { + clearInterval(fadeInterval) + $('#listbox').css('opacity', 0.5) + $('#msg').css('opacity', 0.5) + $('#pageup').css('opacity', 0.5) + $('#pagedown').css('opacity', 0.5) + $('#hello').css('opacity', 0.5) + $('header').css('opacity', 0.5) + faded = false + } +function show_searchbox() + { + keyboard_mode = "textentry" + $('#q').val('') + $('#frag').hide() + $('header').hide() + $('#searchbox').show() + $('#q').focus() + } +function hide_searchbox() + { + keyboard_mode = 'navigate' + $('#q').blur() + $('#frag').hide() + $('#searchbox').hide() + $('header').show() + Search.lastAutocomplete = ''; + } +function keypress_textentry (key) + { + document.getElementById('username').innerHTML = '"'+ key +'"' + switch (key) + { + case 8: // backspace + $('#frag').hide() + break + case 38: // up + break + case 40: // down + hide_searchbox() + Cursor.select(0) + return + case 27: // esc + hide_searchbox() + Index.display() + break + case 13: // enter + hide_searchbox() + Cursor.select(0) + // search($('#q').val()) + return false + case 32: // space + return true + case 178: // stop + if (Player.currentSound) + Player.currentSound.stop() + return false + } + // for letters in range: 0-z + if (key >= 48 && key <= 90) + { + var q = $('#q').val() + q += String.fromCharCode(key).toLowerCase() + $('#frag').hide() + autocomplete(q) + } + return true + } + +// - /api/login +// + /api/index +// + /api/thread +// + /api/search +// + /api/autocomplete +// - /api/post +// - /api/tag + +var Index = + { + go: function () + { + $('#list').fadeOut(200, function(){ }); + if (! Dymaxion.index.count) + $.get("/cgi-bin/bucky/2/api/index",{},Index.parse) + else + Index.display() + }, + parse: function (raw) + { + if (raw) + warn("got it") + else + warn("index empty") + var lines = raw.split("\n") + var rows = [] + var count = 0 + for (i in lines) + { + if (! lines[i]) + continue + var fields = lines[i].split('\t') + // 0 thread 1 title 2 subtitle 3 filename + rows.push([fields[0],fields[3],fields[1],fields[2]]) + count += 1 + } + Dymaxion.index.rows = rows + Dymaxion.index.count = count + Index.display() + }, + display: function () + { + $('header').html('Bucky Dymaxion') + $('header').fadeIn(500, function(){}) + Cursor.mode = "index" + Cursor.rows = Dymaxion.index.rows + Cursor.count = Dymaxion.index.count + Cursor.select(Dymaxion.index.pos) + $('#list').fadeIn(500, function(){}) + }, + }; +var Search = + { + q: '', + lastAutocomplete: '', + oldSequence: '', + autocompleteTimeout: '', + go: function (q) + { + $('#list').fadeOut(200, function(){}) + $('header').html('Results for <b>' +q+ '</b>') + $('#frag').html('') + this.q = q + warn ("> " +q); + $.get("/cgi-bin/bucky/2/api/search",{'q':q},Search.parse) + }, + parse: function (raw) + { + warn("got it") + var lines = raw.split("\n") + var rows = [] + var count = 0 + for (i in lines) + { + if (! lines[i]) + continue + var fields = lines[i].split('\t') + // 0 thread 1 title 2 subtitle 3 filename + rows.push([fields[0],fields[3],fields[1],fields[2]]) + count += 1 + } + // if only 1 search result, jump to that page + if (count == 1) + { + Thread.load(rows[0][0],rows[0][3]) + return + } + Dymaxion.search.count = count + Dymaxion.search.rows = rows + Search.display() + }, + display: function () + { + $('header').html("Results for <b>" + this.q + "</b>") + $('header').fadeIn(500, function(){ }) + Cursor.mode = "search"; + Cursor.count = Dymaxion.search.count + Cursor.rows = Dymaxion.search.rows + Cursor.select(Dymaxion.search.pos) + $('#list').fadeIn(500, function(){ }); + }, + autocomplete: function (q) + { + if (q === Search.lastAutocomplete) + { + $('#frag').hide() + $('#frag').html('') + return + } + warn("autocomplete "+q) + Search.oldSequence = q + clearTimeout(Search.autocompleteTimeout) + Search.autocompleteTimeout = setTimeout(Search.autocompleteGo, 200) + }, + autocompleteGo: function (q) + { + $.get("/cgi-bin/bucky/2/api/autocomplete",{'q':q}, Search.autocompleteRaw); + }, + autocompleteRaw: function(raw) + { + if (Search.oldSequence !== q) + { + warn('bailing: '+q) + return; + } + warn('not bailing: '+q) + var lines = raw.split("\n") + var rows = [] + var count = 0 + var frag = '' + for (i in lines) + { + if (! frag) + { + var frag = lines[0] + if (frag === "_") + { + warn("matched full word "+q) + $('#frag').hide() + $('#frag').html('') + Search.q = q + } + else + { + Search.lastAutocomplete = q+frag + var qt = document.getElementById('qtmp') + qt.innerHTML = q + // var qwidth = document.defaultView.getComputedStyle(qt,null).getPropertyValue('offsetWidth'); + var qwidth = qt.offsetWidth + qt.innerHTML = '' + warn("qwidth: "+qwidth) + warn("matched "+q+"_"+frag) + document.getElementById('frag').innerHTML = frag + document.getElementById('frag').style.left = qwidth + qLeftPadding + Search.q = Search.lastAutocomplete + $('#frag').fadeIn(500) + } + continue + } + if (! lines[i]) + continue + var fields = lines[i].split('\t') + // 0 thread 1 title 2 subtitle 3 filename + rows.push([fields[0],fields[3],fields[1],fields[2]]) + count += 1 + } + $('header').html('Results for <b>' +Search.q+ '</b>'); + Cursor.mode = "search"; + Cursor.count = count + Cursor.rows = rows + Dymaxion.search.count = count + Dymaxion.search.rows = rows + Cursor.redrawPage() + $('#list').fadeIn(200, function(){ }); + warn ("> " +q); + }, + }; +var Thread = + { + thread: false, + threadid: 0, + fileid: 0, + matchpos: 0, + load: function (threadid, fileid) + { + if (! threadid) + return + Thread.threadid = threadid + Thread.fileid = fileid + warn ("loading "+threadid) + $.get("/cgi-bin/bucky/2/api/thread",{'id':threadid},Thread.parse) + }, + parse: function (raw) + { + warn("got it") + var lines = raw.split("\n") + var bg = ''; + var count = 0 + var rows = [] + var thread = false + Thread.matchpos = 0 + for (i in lines) + { + if (! lines[i]) + continue + var fields = lines[i].split('\t') + // thread (first line) + // 0 id 1 title 2 flagged 3 createdate 4 username 5 keyword + if (! thread) + thread = fields + + // file: + // 0 id 1 type 2 filename 3 title 4 date 5 size + else if (fields[1] === 'mp3') + { + // 0 id 1 type 2 filename 3 title 4 date 5 size + rows.push([thread[0],fields[2],fields[3],undefined]) + if (fields[0] === Thread.fileid) + Thread.matchpos = count + count += 1 + } + else if ( + ! bg && + ( thread[2] && fields[0] === thread[2] ) || + (! thread[2] && (fields[1] === 'jpg' || fields[1] === 'gif' || fields[1] === 'png')) + ) + { + bg = fields[2] + $('#background').fadeOut(500, function () + { + warn("bg = "+bg) + warn("/bucky/data/"+Thread.threadid+"/"+bg) + document.getElementById('background').src = "/bucky/data/"+Thread.threadid+"/"+bg + document.getElementById('background').onload = function(){ $('#background').fadeIn(500, function (){}) } + }) + } + // comment: + // 0 id 1 type 2 username 3 date 4 comment + else if (fields[1] === 'comment') + { + if (! fields[4]) + continue + rows.push([thread[0],fields[2],'',fields[4],]) + count += 1 + } + } + Thread.thread = thread + Dymaxion.thread.count = count + Dymaxion.thread.rows = rows + Thread.display() + }, + display: function () + { + $('header').html(Thread.thread[1]); + $('header').fadeIn(500, function(){ }) + Cursor.mode = "thread"; + Cursor.count = Dymaxion.thread.count + Cursor.rows = Dymaxion.thread.rows + if (Thread.fileid) + Cursor.select(Thread.matchpos) + else + Cursor.select(0) + }, + } +function warn(s) + { + var h = document.getElementById('msg').innerHTML + h = s + '<br / >' + h + document.getElementById('msg').innerHTML = h + } +function init () + { + warn ("yo") + document.onkeydown = kp + Index.go() + Player.loadSoundManager() + $('#background').hide() + document.getElementById('background').src = "/dymaxion/paradis.jpg" + document.getElementById('background').onload = function(){ $('#background').fadeIn(5000, function (){}) } + // Search.go('surgeon') + // Thread.load(666) + } +init() + diff --git a/docs/dymaxion/index.html b/docs/dymaxion/index.html new file mode 100644 index 0000000..8205393 --- /dev/null +++ b/docs/dymaxion/index.html @@ -0,0 +1,200 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>Bucky Dymaxion</title> + <style type="text/css"> + <!-- +* { margin: 0; padding: 0; } +body { background-color: #111111; margin: 0px; padding: 0px; overflow: hidden; } +a { text-decoration: underline; color: #0ff; } +.classy { font-family: georgia, serif; font-size: 77px; font-style: italic; font-weight: bold; color: #eee; letter-spacing: -2px; } +#hello { + opacity: 0.5; -moz-border-radius: 20px; border-radius: 20px; + font-size: 15px; font-family: georgia, serif; + color: #eee; background-color: #644; + width: 260px; padding: 10px; + position: fixed; top: 10px; right: 15px; + text-align: center; + } +#hello b { color: #fff; } +html, body, #bg, #bg table, #bg td { height:100%; width:100%; overflow:hidden; } +#bg { position: fixed; } +#bg div { height:200%; left:-50%; position:absolute; top:-50%; width:200%; } +#bg td { text-align:center; vertical-align:middle; } +#bg img { margin:0 auto; min-height:50%; min-width:50%; } +#background { opacity: 0.3; } +#msg { position: fixed; right: 15px; top: 10%; max-height: 84%; background: #222; color: #ccc; width: 250px; + font-family: monospace; + padding: 10px 15px; + opacity: 0.5; -moz-border-radius: 20px; border-radius: 20px; + overflow: hidden; + // display: none; + } +header + { + position: fixed; + top: 25px; + left: 50px; + font-family: sans-serif; + font-size: 36px; + font-weight: normal; + color: #cbb; + opacity: 0.5; + text-shadow: #667 0px -1px 3px, + #755 2px 1px 2px, + #755 -2px -1px 2px; + } +#searchbox + { + position: fixed; + top: 15px; + left: 40px; + display: none; + z-index: 2; + } +#searchbox #q + { + -moz-border-radius: 50px; border-radius: 50px; + border: transparent; + font-family: sans-serif; + padding: 10px 20px 10px 20px; + font-size: 32px; + background-color: #f8f8ff; + color: #000; + width: 600px; + opacity: .95; + outline: 0; + position: absolute; + top: 0; + left: 0; + } +#searchbox #frag + { + font-family: sans-serif; + position: absolute; + top: 10px; + left: 0; + color: #888; + font-size: 32px; + } +#qtmp + { + position: fixed; + font-family: sans-serif; + font-size: 32px; + top: 0px; + z-index: 1; + } +#listbox + { + position: fixed; + top: 90px; + left: 40px; + max-width: 700px; + font-family: sans-serif; + opacity: .5; + } +#listbox ul + { + -moz-border-radius: 30px; border-radius: 30px; + padding: 10px; + background-color: #000; + display: none; + } +#listbox ul li + { + list-style-type: none; + -moz-border-radius: 20px; border-radius: 20px; + padding: 10px; + background-color: transparent; + } +#listbox ul li.twoline + { + padding: 5px 10px; + } +#listbox ul li h2 + { + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + font-size: 24px; + color: #ddd; + } +#listbox ul li h3 + { + font-size: 14px; + color: #666; + } +#listbox ul li.playing + { + background-color: #334; + } +#listbox ul li.playing * + { + color: #fff; + } +#listbox ul li.selected + { + background-color: #fee; + color: #000; + } +#listbox ul li.selected * + { + color: #000; + } +#pageup + { + border-width: 12px; + border-style: solid; + border-color: transparent transparent #ddd transparent; + position: fixed; + top: 100px; + left: 6px; + display: none; + width: 0; + height: 0; + opacity: 0.5; + } +#pagedown + { + border-width: 12px; + border-style: solid; + border-color: #ddd transparent transparent transparent; + position: fixed; + top: 540px; + left: 6px; + display: none; + width: 0; + height: 0; + opacity: 0.5; + } + --> + </style> + + </head> + +<body> + +<div id="bg"> +<div><table cellspacing=0 cellpadding=0><tr><td><img id="background" /></td></tr></table></div> +</div> + +<div id="hello">hello, <b id="username">ghost</b></div> +<div id="msg"></div> +<div id="searchbox"><input type="text" id="q" name="q" autocomplete="off"><span id="frag" /></div> +<header></header> +<div id="listbox"><ul id="list"></ul></div> +<div id="pageup"></div> +<div id="pagedown"></div> +<div id="qtmp"></div> +</body> + +<script type="text/javascript" src="jquery-1.4.4.min.js"></script> +<script type="text/javascript" src="soundmanager2.js"></script> +<script type="text/javascript" src="dymaxion.js"></script> + +</html> + + diff --git a/docs/dymaxion/jquery-1.4.4.min.js b/docs/dymaxion/jquery-1.4.4.min.js new file mode 100644 index 0000000..8f3ca2e --- /dev/null +++ b/docs/dymaxion/jquery-1.4.4.min.js @@ -0,0 +1,167 @@ +/*! + * jQuery JavaScript Library v1.4.4 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Nov 11 19:04:53 2010 -0500 + */ +(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h= +h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;k<J.length;k++){h=J[k];h.origType.replace(X,"")===a.type?f.push(h.selector):J.splice(k--,1)}f=c(a.target).closest(f,a.currentTarget);o=0;for(x=f.length;o<x;o++){r=f[o];for(k=0;k<J.length;k++){h=J[k];if(r.selector===h.selector&&(!A||A.test(h.namespace))){l=r.elem;e=null;if(h.preType==="mouseenter"|| +h.preType==="mouseleave"){a.type=h.preType;e=c(a.relatedTarget).closest(h.selector)[0]}if(!e||e!==l)C.push({elem:l,handleObj:h,level:r.level})}}}o=0;for(x=C.length;o<x;o++){f=C[o];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La, +"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this, +e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a, +"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+ +a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/, +C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j, +s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this, +j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length}, +toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j=== +-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false; +if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K<Q;K++)if((j=arguments[K])!=null)for(s in j){v=G[s];z=j[s];if(G!==z)if(ga&&z&&(b.isPlainObject(z)||(H=b.isArray(z)))){if(H){H=false;v=v&&b.isArray(v)?v:[]}else v=v&&b.isPlainObject(v)?v:{};G[s]=b.extend(ga,v,z)}else if(z!==B)G[s]=z}return G};b.extend({noConflict:function(j){E.$=e;if(j)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(j){j===true&&b.readyWait--; +if(!b.readyWait||j!==true&&!b.isReady){if(!t.body)return setTimeout(b.ready,1);b.isReady=true;if(!(j!==true&&--b.readyWait>0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload", +b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&& +!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&& +l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H<G;){if(s.apply(j[H++],v)===false)break}else if(K)for(z in j){if(s.call(j[z], +z,j[z])===false)break}else for(v=j[0];H<G&&s.call(v,H,v)!==false;v=j[++H]);return j},trim:O?function(j){return j==null?"":O.call(j)}:function(j){return j==null?"":j.toString().replace(k,"").replace(o,"")},makeArray:function(j,s){var v=s||[];if(j!=null){var z=b.type(j);j.length==null||z==="string"||z==="function"||z==="regexp"||b.isWindow(j)?M.call(v,j):b.merge(v,j)}return v},inArray:function(j,s){if(s.indexOf)return s.indexOf(j);for(var v=0,z=s.length;v<z;v++)if(s[v]===j)return v;return-1},merge:function(j, +s){var v=j.length,z=0;if(typeof s.length==="number")for(var H=s.length;z<H;z++)j[v++]=s[z];else for(;s[z]!==B;)j[v++]=s[z++];j.length=v;return j},grep:function(j,s,v){var z=[],H;v=!!v;for(var G=0,K=j.length;G<K;G++){H=!!s(j[G],G);v!==H&&z.push(j[G])}return z},map:function(j,s,v){for(var z=[],H,G=0,K=j.length;G<K;G++){H=s(j[G],G,v);if(H!=null)z[z.length]=H}return z.concat.apply([],z)},guid:1,proxy:function(j,s,v){if(arguments.length===2)if(typeof s==="string"){v=j;j=v[s];s=B}else if(s&&!b.isFunction(s)){v= +s;s=B}if(!s&&j)s=function(){return j.apply(v||this,arguments)};if(j)s.guid=j.guid=j.guid||s.guid||b.guid++;return s},access:function(j,s,v,z,H,G){var K=j.length;if(typeof s==="object"){for(var Q in s)b.access(j,Q,s[Q],z,H,v);return j}if(v!==B){z=!G&&z&&b.isFunction(v);for(Q=0;Q<K;Q++)H(j[Q],s,z?v.call(j[Q],Q,H(j[Q],s)):v,G);return j}return K?H(j[0],s):B},now:function(){return(new Date).getTime()},uaMatch:function(j){j=j.toLowerCase();j=L.exec(j)||g.exec(j)||i.exec(j)||j.indexOf("compatible")<0&&n.exec(j)|| +[];return{browser:j[1]||"",version:j[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(j,s){R["[object "+s+"]"]=s.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=m.version}if(b.browser.webkit)b.browser.safari=true;if(D)b.inArray=function(j,s){return D.call(s,j)};if(!/\s/.test("\u00a0")){k=/^[\s\xA0]+/;o=/[\s\xA0]+$/}f=b(t);if(t.addEventListener)u=function(){t.removeEventListener("DOMContentLoaded",u, +false);b.ready()};else if(t.attachEvent)u=function(){if(t.readyState==="complete"){t.detachEvent("onreadystatechange",u);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=t.documentElement,b=t.createElement("script"),d=t.createElement("div"),e="script"+c.now();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"), +k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false, +scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent= +false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom= +1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display= +"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h= +c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando); +else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h<l;h++){f=e[h].name;if(f.indexOf("data-")===0){f=f.substr(5);ka(this[0],f,d[f])}}}return d}else if(typeof a==="object")return this.each(function(){c.data(this, +a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===B){d=this.triggerHandler("getData"+k[1]+"!",[k[0]]);if(d===B&&this.length){d=c.data(this[0],a);d=ka(this[0],a,d)}return d===B&&k[1]?this.data(k[0]):d}else return this.each(function(){var o=c(this),x=[k[0],b];o.triggerHandler("setData"+k[1]+"!",x);c.data(this,a,b);o.triggerHandler("changeData"+k[1]+"!",x)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e= +c.data(a,b);if(!d)return e||[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===B)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this, +a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var sa=/[\n\t]/g,ha=/\s+/,Sa=/\r/g,Ta=/^(?:href|src|style)$/,Ua=/^(?:button|input)$/i,Va=/^(?:button|input|object|select|textarea)$/i,Wa=/^a(?:rea)?$/i,ta=/^(?:radio|checkbox)$/i;c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan", +colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(x){var r=c(this);r.addClass(a.call(this,x,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType=== +1)if(f.className){for(var h=" "+f.className+" ",l=f.className,k=0,o=b.length;k<o;k++)if(h.indexOf(" "+b[k]+" ")<0)l+=" "+b[k];f.className=c.trim(l)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var x=c(this);x.removeClass(a.call(this,o,x.attr("class")))});if(a&&typeof a==="string"||a===B)for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(sa," "), +l=0,k=b.length;l<k;l++)h=h.replace(" "+b[l]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,l=c(this),k=b,o=a.split(ha);f=o[h++];){k=e?k:!l.hasClass(f);l[k?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this, +"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(sa," ").indexOf(a)>-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one"; +if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var l=f[h];if(l.selected&&(c.support.optDisabled?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!c.nodeName(l.parentNode,"optgroup"))){a=c(l).val();if(b)return a;d.push(a)}}return d}if(ta.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Sa,"")}return B}var k=c.isFunction(a);return this.each(function(o){var x=c(this),r=a;if(this.nodeType===1){if(k)r= +a.call(this,o,x.val());if(r==null)r="";else if(typeof r==="number")r+="";else if(c.isArray(r))r=c.map(r,function(C){return C==null?"":C+""});if(c.isArray(r)&&ta.test(this.type))this.checked=c.inArray(x.val(),r)>=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true}, +attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&& +b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0}; +c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem, +arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid= +d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+ +c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h<A.length;h++){C=A[h];if(d.guid===C.guid){if(k||x.test(C.namespace)){e==null&&A.splice(h--,1);r.remove&&r.remove.call(a,C)}if(e!=null)break}}if(A.length===0||e!=null&&A.length===1){if(!r.teardown||r.teardown.call(a,o)===false)c.removeEvent(a,f,w.handle);delete I[f]}}else for(h=0;h<A.length;h++){C=A[h];if(k||x.test(C.namespace)){c.event.remove(a,r,C.handler,h);A.splice(h--,1)}}}if(c.isEmptyObject(I)){if(b= +w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,J);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType=== +8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k=== +"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+ +d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f<l;f++){var k=d[f];if(b||e.test(k.namespace)){a.handler=k.handler;a.data=k.data;a.handleObj=k;k=k.handler.apply(this,h);if(k!==B){a.result=k;if(k===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), +fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||t;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=t.documentElement;d=t.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop|| +d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==B)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ka,guid:a.handler.guid}))},remove:function(a){c.event.remove(this, +Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=t.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp= +c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ca;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ca;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ca;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U}; +var va=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},wa=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?wa:va,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?wa:va)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!== +"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=B;return la("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=B;return la("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V, +xa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired= +B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type=== +"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]=== +0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h<k;h++)c.event.add(this[h],d,l,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d, +a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d= +1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var ya={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var l,k=0,o,x,r=h||this.selector;h=h?this:c(this.context);if(typeof d=== +"object"&&!d.preventDefault){for(l in d)h[b](l,e,d[l],r);return this}if(c.isFunction(e)){f=e;e=B}for(d=(d||"").split(" ");(l=d[k++])!=null;){o=X.exec(l);x="";if(o){x=o[0];l=l.replace(X,"")}if(l==="hover")d.push("mouseenter"+x,"mouseleave"+x);else{o=l;if(l==="focus"||l==="blur"){d.push(ya[l]+x);l+=x}else l=(ya[l]||l)+x;if(b==="live"){x=0;for(var A=h.length;x<A;x++)c.event.add(h[x],"live."+Y(l,r),{data:e,selector:r,handler:f,origType:l,origHandler:f,preType:o})}else h.unbind("live."+Y(l,r),f)}}return this}}); +c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); +(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1&&!q){y.sizcache=n;y.sizset=p}if(y.nodeName.toLowerCase()===i){F=y;break}y=y[g]}m[p]=F}}}function b(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1){if(!q){y.sizcache=n;y.sizset=p}if(typeof i!=="string"){if(y===i){F=true;break}}else if(k.filter(i, +[y]).length>0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3]; +break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr, +q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h= +l;g.sort(w);if(h)for(var i=1;i<g.length;i++)g[i]===g[i-1]&&g.splice(i--,1)}return g};k.matches=function(g,i){return k(g,null,null,i)};k.matchesSelector=function(g,i){return k(i,null,null,[g]).length>0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p<q;p++){var u,y=o.order[p];if(u=o.leftMatch[y].exec(g)){var F=u[1];u.splice(1,1);if(F.substr(F.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");m=o.find[y](u,i,n);if(m!=null){g=g.replace(o.match[y],"");break}}}}m||(m=i.getElementsByTagName("*")); +return{set:m,expr:g}};k.filter=function(g,i,n,m){for(var p,q,u=g,y=[],F=i,M=i&&i[0]&&k.isXML(i[0]);g&&i.length;){for(var N in o.filter)if((p=o.leftMatch[N].exec(g))!=null&&p[2]){var O,D,R=o.filter[N];D=p[1];q=false;p.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(F===y)y=[];if(o.preFilter[N])if(p=o.preFilter[N](p,F,n,y,m,M)){if(p===true)continue}else q=O=true;if(p)for(var j=0;(D=F[j])!=null;j++)if(D){O=R(D,p,j,F);var s=m^!!O;if(n&&O!=null)if(s)q=true;else F[j]=false;else if(s){y.push(D);q=true}}if(O!== +B){n||(F=y);g=g.replace(o.match[N],"");if(!q)return[];break}}}if(g===u)if(q==null)k.error(g);else break;u=g}return F};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var o=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, +POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,i){var n=typeof i==="string",m=n&&!/\W/.test(i);n=n&&!m;if(m)i=i.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=n||q&&q.nodeName.toLowerCase()=== +i?q||false:q===i}n&&k.filter(i,g,true)},">":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p<q;p++){if(n=g[p]){n=n.parentNode;g[p]=n.nodeName.toLowerCase()===i?n:false}}else{for(;p<q;p++)if(n=g[p])g[p]=m?n.parentNode:n.parentNode===i;m&&k.filter(i,g,true)}},"":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=i=i.toLowerCase();q=a}q("parentNode",i,p,g,m,n)},"~":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m= +i=i.toLowerCase();q=a}q("previousSibling",i,p,g,m,n)}},find:{ID:function(g,i,n){if(typeof i.getElementById!=="undefined"&&!n)return(g=i.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,i){if(typeof i.getElementsByName!=="undefined"){for(var n=[],m=i.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&n.push(m[p]);return n.length===0?null:n}},TAG:function(g,i){return i.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,i,n,m,p,q){g=" "+g[1].replace(/\\/g, +"")+" ";if(q)return g;q=0;for(var u;(u=i[q])!=null;q++)if(u)if(p^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n, +m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== +true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== +g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return i<n[3]-0},gt:function(g,i,n){return i>n[3]-0},nth:function(g,i,n){return n[3]- +0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n<m;n++)if(i[n]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,i){var n=i[1],m=g;switch(n){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(n=== +"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":n=i[2];var p=i[3];if(n===1&&p===0)return true;var q=i[0],u=g.parentNode;if(u&&(u.sizcache!==q||!g.nodeIndex)){var y=0;for(m=u.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++y;u.sizcache=q}m=g.nodeIndex-p;return n===0?m===0:m%n===0&&m/n>=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== +i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]]; +if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m, +g);else if(typeof g.length==="number")for(var p=g.length;n<p;n++)m.push(g[n]);else for(;g[n];n++)m.push(g[n]);return m}}var w,I;if(t.documentElement.compareDocumentPosition)w=function(g,i){if(g===i){h=true;return 0}if(!g.compareDocumentPosition||!i.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(i)&4?-1:1};else{w=function(g,i){var n,m,p=[],q=[];n=g.parentNode;m=i.parentNode;var u=n;if(g===i){h=true;return 0}else if(n===m)return I(g,i);else if(n){if(!m)return 1}else return-1; +for(;u;){p.unshift(u);u=u.parentNode}for(u=m;u;){q.unshift(u);u=u.parentNode}n=p.length;m=q.length;for(u=0;u<n&&u<m;u++)if(p[u]!==q[u])return I(p[u],q[u]);return u===n?I(g,q[u],-1):I(p[u],i,1)};I=function(g,i,n){if(g===i)return n;for(g=g.nextSibling;g;){if(g===i)return-1;g=g.nextSibling}return 1}}k.getText=function(g){for(var i="",n,m=0;g[m];m++){n=g[m];if(n.nodeType===3||n.nodeType===4)i+=n.nodeValue;else if(n.nodeType!==8)i+=k.getText(n.childNodes)}return i};(function(){var g=t.createElement("div"), +i="script"+(new Date).getTime(),n=t.documentElement;g.innerHTML="<a name='"+i+"'/>";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g); +n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&& +function(){var g=k,i=t.createElement("div");i.innerHTML="<p class='TEST'></p>";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F|| +p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g= +t.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition? +function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n<u;n++)k(g,q[n],m);return k.filter(p,m)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=k.getText;c.isXMLDoc=k.isXML; +c.contains=k.contains})();var Za=/Until$/,$a=/^(?:parents|prevUntil|prevAll)/,ab=/,/,Na=/^.[^:#\[\.,]*$/,bb=Array.prototype.slice,cb=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var l=0;l<d;l++)if(b[l]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})}, +not:function(a){return this.pushStack(ma(this,a,false),"not",a)},filter:function(a){return this.pushStack(ma(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h= +h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(l?l.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context): +c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a, +2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a, +b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&& +e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/<tbody/i,eb=/<|&#?\w+;/,Ca=/<(?:script|object|embed|option|style)/i,Da=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/\=([^="'>\s]+\/)>/g,P={option:[1, +"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null; +else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d= +c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){var e,f,h,l=a[0],k=[];if(!c.support.checkClone&&arguments.length===3&&typeof l==="string"&&Da.test(l))return this.each(function(){c(this).domManip(a, +b,d,true)});if(c.isFunction(l))return this.each(function(x){var r=c(this);a[0]=l.call(this,x,b?r.html():B);r.domManip(a,b,d)});if(this[0]){e=l&&l.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);h=e.fragment;if(f=h.childNodes.length===1?h=h.firstChild:h.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var o=this.length;f<o;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")): +this[f]:this[f],f>0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append", +prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f<h;f++){var l=(f>0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument|| +b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1></$2>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]==="<table>"&&!x?r.childNodes:[];for(o=k.length- +1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script")))); +d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i, +jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true, +zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b), +h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b); +if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f= +d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left; +e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, +ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b=== +"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("<div>").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&& +!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})}, +getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html", +script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data|| +!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache= +false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset; +A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type", +b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&& +c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d|| +c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]= +encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess", +[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"), +e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}}); +if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show", +3),a,b,d);else{d=0;for(var e=this.length;d<e;d++){a=this[d];b=a.style.display;if(!c.data(a,"olddisplay")&&b==="none")b=a.style.display="";b===""&&c.css(a,"display")==="none"&&c.data(a,"olddisplay",qa(a.nodeName))}for(d=0;d<e;d++){a=this[d];b=a.style.display;if(b===""||b==="none")a.style.display=c.data(a,"olddisplay")||""}return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay", +d)}for(a=0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b, +d,e);if(c.isEmptyObject(a))return this.each(f.complete);return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),l,k=this.nodeType===1,o=k&&c(this).is(":hidden"),x=this;for(l in a){var r=c.camelCase(l);if(l!==r){a[r]=a[l];delete a[l];l=r}if(a[l]==="hide"&&o||a[l]==="show"&&!o)return h.complete.call(this);if(k&&(l==="height"||l==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(qa(this.nodeName)=== +"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[l])){(h.specialEasing=h.specialEasing||{})[l]=a[l][1];a[l]=a[l][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(A,C){var J=new c.fx(x,h,A);if(vb.test(C))J[C==="toggle"?o?"show":"hide":C](a);else{var w=wb.exec(C),I=J.cur()||0;if(w){var L=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(x,A,(L||1)+g);I=(L|| +1)/J.cur()*I;c.style(x,A,I+g)}if(w[1])L=(w[1]==="-="?-1:1)*L+I;J.custom(I,L,g)}else J.custom(I,C,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b, +d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a* +Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)} +var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true; +this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide|| +this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a= +c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(ba);ba=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a=== +b.elem}).length};var xb=/^t(?:able|d|h)$/i,Ia=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in t.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(l){c.offset.setOffset(this,a,l)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=fa(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&& +h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(x){c.offset.setOffset(this,a,x)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d,e=b.offsetParent,f=b.ownerDocument,h=f.documentElement,l=f.body;d=(f=f.defaultView)?f.getComputedStyle(b,null):b.currentStyle; +for(var k=b.offsetTop,o=b.offsetLeft;(b=b.parentNode)&&b!==l&&b!==h;){if(c.offset.supportsFixedPosition&&d.position==="fixed")break;d=f?f.getComputedStyle(b,null):b.currentStyle;k-=b.scrollTop;o-=b.scrollLeft;if(b===e){k+=b.offsetTop;o+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&xb.test(b.nodeName))){k+=parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}e=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"){k+= +parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}d=d}if(d.position==="relative"||d.position==="static"){k+=l.offsetTop;o+=l.offsetLeft}if(c.offset.supportsFixedPosition&&d.position==="fixed"){k+=Math.max(h.scrollTop,l.scrollTop);o+=Math.max(h.scrollLeft,l.scrollLeft)}return{top:k,left:o}};c.offset={initialize:function(){var a=t.body,b=t.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px", +height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells= +f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a, +"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),l=c.css(a,"top"),k=c.css(a,"left"),o=e==="absolute"&&c.inArray("auto",[l,k])>-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a, +e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&& +c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase(); +c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+ +b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window); diff --git a/docs/dymaxion/paradis.jpg b/docs/dymaxion/paradis.jpg Binary files differnew file mode 100644 index 0000000..389b82b --- /dev/null +++ b/docs/dymaxion/paradis.jpg diff --git a/docs/dymaxion/soundmanager2.js b/docs/dymaxion/soundmanager2.js new file mode 100755 index 0000000..46528c9 --- /dev/null +++ b/docs/dymaxion/soundmanager2.js @@ -0,0 +1,2838 @@ +/** @license + * SoundManager 2: Javascript Sound for the Web + * -------------------------------------------- + * http://schillmania.com/projects/soundmanager2/ + * + * Copyright (c) 2007, Scott Schiller. All rights reserved. + * Code provided under the BSD License: + * http://schillmania.com/projects/soundmanager2/license.txt + * + * V2.97a.20101010 + */ + +/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: true, newcap: true, immed: true, regexp: false */ +/*global window, SM2_DEFER, sm2Debugger, alert, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ + +(function(window) { + +var soundManager = null; + +function SoundManager(smURL, smID) { + + this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. + this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available+configured) + this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues + this.useConsole = true; // use firebug/safari console.log()-type debug console if available + this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug + this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() + this.nullURL = 'about:blank'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) + this.allowPolling = true; // allow flash to poll for status update (required for whileplaying() events, peak, sound spectrum functions to work.) + this.useFastPolling = false; // uses lower flash timer interval for higher callback frequency, best combined with useHighPerformance + this.useMovieStar = true; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio formats (AAC, M4V, FLV, MOV etc.) + this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000' + this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag + this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity) + this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top) + this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain' + this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable. + this.useHTML5Audio = false; // Beta feature: Use HTML 5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible. + this.html5Test = /^probably$/i; // HTML5 Audio().canPlayType() test. /^(probably|maybe)$/i if you want to be more liberal/risky. + this.ondebuglog = false; // callback made with each log message, regardless of debugMode + + this.audioFormats = { + // determines HTML5 support, flash requirements + // eg. if MP3 or MP4 required, Flash fallback is used if HTML5 can't play it + // shotgun approach to MIME testing due to browser variance + 'mp3': { + 'type': ['audio/mpeg; codecs="mp3"','audio/mpeg','audio/mp3','audio/MPA','audio/mpa-robust'], + 'required': true + }, + 'mp4': { + 'related': ['aac','m4a'], // additional formats under the MP4 container + 'type': ['audio/mp4; codecs="mp4a.40.2"','audio/aac','audio/x-m4a','audio/MP4A-LATM','audio/mpeg4-generic'], + 'required': true + }, + 'ogg': { + 'type': ['audio/ogg; codecs=vorbis'], + 'required': false + }, + 'wav': { + 'type': ['audio/wav; codecs="1"','audio/wav','audio/wave','audio/x-wav'], + 'required': false + } + }; + + this.defaultOptions = { + '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) + 'stream': true, // allows playing before entire file has loaded (recommended) + 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) + 'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0) + 'onid3': null, // callback function for "ID3 data is added/available" + 'onload': null, // callback function for "load finished" + 'whileloading': null, // callback function for "download progress update" (X of Y bytes received) + 'onplay': null, // callback for "play" start + 'onpause': null, // callback for "pause" + 'onresume': null, // callback for "resume" (pause toggle) + 'whileplaying': null, // callback during play (position update) + 'onstop': null, // callback for "user stop" + 'onfailure': null, // callback function for when playing fails + 'onfinish': null, // callback function for "sound finished playing" + 'onbeforefinish': null, // callback for "before sound finished playing (at [time])" + 'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) + 'onbeforefinishcomplete': null,// function to call when said sound finishes playing + 'onjustbeforefinish': null, // callback for [n] msec before end of current sound + 'onjustbeforefinishtime': 200, // [n] - if not using, set to 0 (or null handler) and event will not fire. + 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time + 'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled + 'position': null, // offset (milliseconds) to seek to within loaded sound data. + 'pan': 0, // "pan" settings, left-to-right, -100 to 100 + 'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3 + 'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access) + 'volume': 100 // self-explanatory. 0-100, the latter being the max. + }; + + this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used + 'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL + 'usePeakData': false, // enable left/right channel peak (level) data + 'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. + 'useEQData': false, // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. + 'onbufferchange': null, // callback for "isBuffering" property change + 'ondataerror': null, // callback for waveform/eq data access error (flash playing audio in other tabs/domains) + 'onstats': null // callback for when connection & play times have been measured + }; + + this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio options, merged into defaultOptions if flash 9+movieStar mode is enabled + 'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.) + 'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants + 'onconnect': null, // rtmp: callback for connection to flash media server + 'bufferTimes': null, // array of buffer sizes to use. Size increases as buffer fills up. + 'duration': null // rtmp: song duration (msec) + }; + + this.version = null; + this.versionNumber = 'V2.97a.20101010'; + this.movieURL = null; + this.url = (smURL || null); + this.altURL = null; + this.swfLoaded = false; + this.enabled = false; + this.o = null; + this.movieID = 'sm2-container'; + this.id = (smID || 'sm2movie'); + this.swfCSS = { + 'swfBox': 'sm2-object-box', + 'swfDefault': 'movieContainer', + 'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error) + 'swfTimedout': 'swf_timedout', + 'swfUnblocked': 'swf_unblocked', // or loaded OK + 'sm2Debug': 'sm2_debug', + 'highPerf': 'high_performance', + 'flashDebug': 'flash_debug' + }; + this.oMC = null; + this.sounds = {}; + this.soundIDs = []; + this.muted = false; + this.debugID = 'soundmanager-debug'; + this.debugURLParam = /([#?&])debug=1/i; + this.specialWmodeCase = false; + this.didFlashBlock = false; + + this.filePattern = null; + this.filePatterns = { + 'flash8': /\.mp3(\?.*)?$/i, + 'flash9': /\.mp3(\?.*)?$/i + }; + + this.baseMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3 + this.netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3, mp4, aac etc. + this.netStreamTypes = ['aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2']; // Flash v9.0r115+ "moviestar" formats + this.netStreamPattern = new RegExp('\\.(' + this.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + this.mimePattern = this.baseMimeTypes; + + this.features = { + 'buffering': false, + 'peakData': false, + 'waveformData': false, + 'eqData': false, + 'movieStar': false + }; + + this.sandbox = { + // <d> + '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 + // </d> + }; + + this.hasHTML5 = null; // switch for handling logic + this.html5 = { // stores canPlayType() results, etc. treat as read-only. + // mp3: boolean + // mp4: boolean + 'usingFlash': null // set if/when flash fallback is needed + }; + this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?) + + // --- private SM2 internals --- + + var SMSound, + _s = this, _sm = 'soundManager', _id, _ua = navigator.userAgent, _wl = window.location.href.toString(), _fV = this.flashVersion, _doc = document, _win = window, _doNothing, _init, _onready = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnReady, _processOnReady, _initUserOnload, _go, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _beginInit, _strings, _initMovie, _dcLoaded, _didDCLoaded, _getDocument, _createMovie, _die, _mobileFlash, _setPolling, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5Only = false, _html5CanPlay, _html5Ext, _dcIE, _testHTML5, _addEvt, _removeEvt, _slice = Array.prototype.slice, + _is_pre = _ua.match(/pre\//i), + _iPadOrPhone = _ua.match(/(ipad|iphone)/i), + _isMobile = (_ua.match(/mobile/i) || _is_pre || _iPadOrPhone), + _isIE = (_ua.match(/MSIE/i)), + _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), + _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), + _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), + _tryInitOnFocus = (typeof _doc.hasFocus === 'undefined' && _isSafari), + _okToDisable = !_tryInitOnFocus; + + this._use_maybe = (_wl.match(/sm2\-useHTML5Maybe\=1/i)); // temporary feature: #sm2-useHTML5Maybe=1 forces loose canPlay() check + this._overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null); + this.useAltURL = !this._overHTTP; // use altURL if not "online" + + if (_iPadOrPhone || _is_pre) { + // might as well force it on Apple + Palm, flash support unlikely + _s.useHTML5Audio = true; + _s.ignoreFlash = true; + } + + if (_is_pre || this._use_maybe) { + // less-strict canPlayType() checking option + _s.html5Test = /^(probably|maybe)$/i; + } + + // Temporary feature: allow force of HTML5 via URL: #sm2-usehtml5audio=0 or 1 + // <d> + (function(){ + var a = '#sm2-usehtml5audio=', l = _wl, b = null; + if (l.indexOf(a) !== -1) { + b = (l.substr(l.indexOf(a)+a.length) === '1'); + if (typeof console !== 'undefined' && typeof console.log !== 'undefined') { + console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); + } + _s.useHTML5Audio = b; + } + }()); + // </d> + + // --- public API methods --- + + this.supported = function() { + return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); + }; + + this.getMovie = function(smID) { + return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); + }; + + this.loadFromXML = function(sXmlUrl) { + try { + _s.o._loadFromXML(sXmlUrl); + } catch(e) { + _failSafely(); + } + return true; + }; + + this.createSound = function(oOptions) { + var _cs = 'soundManager.createSound(): ', + thisOptions = null, oSound = null, _tO = null; + if (!_didInit || !_s.supported()) { + _complain(_cs + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (arguments.length === 2) { + // function overloading in JS! :) ..assume simple createSound(id,url) use case + oOptions = { + 'id': arguments[0], + 'url': arguments[1] + }; + } + thisOptions = _mixin(oOptions); // inherit from defaultOptions + _tO = thisOptions; // alias + // <d> + if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { + _s._wD(_cs + _str('badID', _tO.id), 2); + } + _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); + // </d> + if (_idCheck(_tO.id, true)) { + _s._wD(_cs + _tO.id + ' exists', 1); + return _s.sounds[_tO.id]; + } + + function make() { + thisOptions = _loopFix(thisOptions); + _s.sounds[_tO.id] = new SMSound(_tO); + _s.soundIDs.push(_tO.id); + return _s.sounds[_tO.id]; + } + + if (_html5OK(_tO)) { + oSound = make(); + _s._wD('Loading sound '+_tO.id+' from HTML5'); + oSound._setup_html5(_tO); + } else { + if (_fV > 8 && _s.useMovieStar) { + if (_tO.isMovieStar === null) { + _tO.isMovieStar = ((_tO.serverURL || (_tO.type?_tO.type.match(_s.netStreamPattern):false)||_tO.url.match(_s.netStreamPattern))?true:false); + } + if (_tO.isMovieStar) { + _s._wD(_cs + 'using MovieStar handling'); + } + if (_tO.isMovieStar) { + if (_tO.usePeakData) { + _wDS('noPeak'); + _tO.usePeakData = false; + } + if (_tO.loops > 1) { + _wDS('noNSLoop'); + } + } + } + _tO = _policyFix(_tO, _cs); + oSound = make(); + if (_fV === 8) { + _s.o._createSound(_tO.id, _tO.onjustbeforefinishtime, _tO.loops||1, _tO.usePolicyFile); + } else { + _s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.bufferTimes, _tO.onstats ? true : false, _tO.autoLoad, _tO.usePolicyFile); + if (!_tO.serverURL) { + // We are connected immediately + oSound.connected = true; + if (_tO.onconnect) { + _tO.onconnect.apply(oSound); + } + } + } + } + if (_tO.autoLoad || _tO.autoPlay) { + if (oSound) { + if (_s.isHTML5) { + oSound.autobuffer = 'auto'; // early HTML5 implementation (non-standard) + oSound.preload = 'auto'; // standard + } else { + oSound.load(_tO); + } + } + } + if (_tO.autoPlay) { + oSound.play(); + } + return oSound; + }; + + this.destroySound = function(sID, _bFromSound) { + // explicitly destroy a sound before normal page unload, etc. + if (!_idCheck(sID)) { + return false; + } + var oS = _s.sounds[sID], i; + oS._iO = {}; // Disable all callbacks while the sound is being destroyed + oS.stop(); + oS.unload(); + for (i = 0; i < _s.soundIDs.length; i++) { + if (_s.soundIDs[i] === sID) { + _s.soundIDs.splice(i, 1); + break; + } + } + if (!_bFromSound) { + // ignore if being called from SMSound instance + oS.destruct(true); + } + oS = null; + delete _s.sounds[sID]; + return true; + }; + + this.load = function(sID, oOptions) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].load(oOptions); + }; + + this.unload = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].unload(); + }; + + this.play = function(sID, oOptions) { + var fN = 'soundManager.play(): '; + if (!_didInit || !_s.supported()) { + _complain(fN + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (!_idCheck(sID)) { + if (!(oOptions instanceof Object)) { + oOptions = { + url: oOptions + }; // overloading use case: play('mySound','/path/to/some.mp3'); + } + if (oOptions && oOptions.url) { + // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); + _s._wD(fN + 'attempting to create "' + sID + '"', 1); + oOptions.id = sID; + return _s.createSound(oOptions).play(); + } else { + return false; + } + } + return _s.sounds[sID].play(oOptions); + }; + + this.start = this.play; // just for convenience + + this.setPosition = function(sID, nMsecOffset) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPosition(nMsecOffset); + }; + + this.stop = function(sID) { + if (!_idCheck(sID)) { + return false; + } + _s._wD('soundManager.stop(' + sID + ')', 1); + return _s.sounds[sID].stop(); + }; + + this.stopAll = function() { + _s._wD('soundManager.stopAll()', 1); + for (var oSound in _s.sounds) { + if (_s.sounds[oSound] instanceof SMSound) { + _s.sounds[oSound].stop(); // apply only to sound objects + } + } + }; + + this.pause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].pause(); + }; + + this.pauseAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].pause(); + } + }; + + this.resume = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].resume(); + }; + + this.resumeAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].resume(); + } + }; + + this.togglePause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].togglePause(); + }; + + this.setPan = function(sID, nPan) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPan(nPan); + }; + + this.setVolume = function(sID, nVol) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setVolume(nVol); + }; + + this.mute = function(sID) { + var fN = 'soundManager.mute(): ', + i = 0; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + _s._wD(fN + 'Muting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].mute(); + } + _s.muted = true; + } else { + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Muting "' + sID + '"'); + return _s.sounds[sID].mute(); + } + return true; + }; + + this.muteAll = function() { + _s.mute(); + }; + + this.unmute = function(sID) { + var fN = 'soundManager.unmute(): ', i; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + _s._wD(fN + 'Unmuting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].unmute(); + } + _s.muted = false; + } else { + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Unmuting "' + sID + '"'); + return _s.sounds[sID].unmute(); + } + return true; + }; + + this.unmuteAll = function() { + _s.unmute(); + }; + + this.toggleMute = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].toggleMute(); + }; + + this.getMemoryUse = function() { + if (_fV === 8) { + return 0; + } + if (_s.o) { + return parseInt(_s.o._getMemoryUse(), 10); + } + }; + + this.disable = function(bNoDisable) { + // destroy all functions + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled) { + return false; + } + _disabled = true; + _wDS('shutdown', 1); + for (var i = _s.soundIDs.length; i--;) { + _disableObject(_s.sounds[_s.soundIDs[i]]); + } + _initComplete(bNoDisable); // fire "complete", despite fail + _removeEvt(_win, 'load', _initUserOnload); + return true; + }; + + this.canPlayMIME = function(sMIME) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay({type:sMIME}); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sMIME?(sMIME.match(_s.mimePattern)?true:false):null); + } + }; + + this.canPlayURL = function(sURL) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay(sURL); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sURL?(sURL.match(_s.filePattern)?true:false):null); + } + }; + + this.canPlayLink = function(oLink) { + if (typeof oLink.type !== 'undefined' && oLink.type) { + if (_s.canPlayMIME(oLink.type)) { + return true; + } + } + return _s.canPlayURL(oLink.href); + }; + + this.getSoundById = function(sID, suppressDebug) { + if (!sID) { + throw new Error('SoundManager.getSoundById(): sID is null/undefined'); + } + var result = _s.sounds[sID]; + if (!result && !suppressDebug) { + _s._wD('"' + sID + '" is an invalid sound ID.', 2); + } + return result; + }; + + this.onready = function(oMethod, oScope) { + if (oMethod && oMethod instanceof Function) { + if (_didInit) { + _wDS('queue'); + } + if (!oScope) { + oScope = _win; + } + _addOnReady(oMethod, oScope); + _processOnReady(); + return true; + } else { + throw _str('needFunction'); + } + }; + + this.getMoviePercent = function() { + return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); + }; + + this._writeDebug = function(sText, sType, bTimestamp) { + // If the debug log callback is set, always call it, regardless of debugMode + if (_s.ondebuglog) { + _s.ondebuglog(sText, sType, bTimestamp); + } + // pseudo-private console.log()-style output + // <d> + var sDID = 'soundmanager-debug', o, oItem, sMethod; + if (!_s.debugMode) { + return false; + } + if (typeof bTimestamp !== 'undefined' && bTimestamp) { + sText = sText + ' | ' + new Date().getTime(); + } + if (_hasConsole && _s.useConsole) { + sMethod = _debugLevels[sType]; + if (typeof console[sMethod] !== 'undefined') { + console[sMethod](sText); + } else { + console.log(sText); + } + if (_s.useConsoleOnly) { + return true; + } + } + try { + o = _id(sDID); + if (!o) { + return false; + } + oItem = _doc.createElement('div'); + if (++_wdCount % 2 === 0) { + oItem.className = 'sm2-alt'; + } + if (typeof sType === 'undefined') { + sType = 0; + } else { + sType = parseInt(sType, 10); + } + oItem.appendChild(_doc.createTextNode(sText)); + if (sType) { + if (sType >= 2) { + oItem.style.fontWeight = 'bold'; + } + if (sType === 3) { + oItem.style.color = '#ff3333'; + } + } + // o.appendChild(oItem); // top-to-bottom + o.insertBefore(oItem, o.firstChild); // bottom-to-top + } catch(e) { + // oh well + } + o = null; + // </d> + return true; + }; + this._wD = this._writeDebug; // alias + + this._debug = function() { + // <d> + _wDS('currentObj', 1); + for (var i = 0, j = _s.soundIDs.length; i < j; i++) { + _s.sounds[_s.soundIDs[i]]._debug(); + } + // </d> + }; + + this.reboot = function() { + // attempt to reset and init SM2 + _s._wD('soundManager.reboot()'); + if (_s.soundIDs.length) { + _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); + } + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].destruct(); + } + // trash ze flash + try { + if (_isIE) { + _oRemovedHTML = _s.o.innerHTML; + } + _oRemoved = _s.o.parentNode.removeChild(_s.o); + _s._wD('Flash movie removed.'); + } catch(e) { + // uh-oh. + _wDS('badRemove', 2); + } + // actually, force recreate of movie. + _oRemovedHTML = _oRemoved = null; + _s.enabled = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; + _s.soundIDs = _s.sounds = []; + _s.o = null; + for (i = _onready.length; i--;) { + _onready[i].fired = false; + } + _s._wD(_sm + ': Rebooting...'); + _win.setTimeout(function() { + _s.beginDelayedInit(); + }, 20); + }; + + this.destruct = function() { + _s._wD('soundManager.destruct()'); + _s.disable(true); + }; + + this.beginDelayedInit = function() { + // _s._wD('soundManager.beginDelayedInit()'); + _windowLoaded = true; + _dcLoaded(); + setTimeout(_beginInit, 20); + _delayWaitForEI(); + }; + + // --- SMSound (sound object) instance --- + + SMSound = function(oOptions) { + var _t = this, _resetProperties, _add_html5_events, _stop_html5_timer, _start_html5_timer, _get_html5_duration, _a; + this.sID = oOptions.id; + this.url = oOptions.url; + this.options = _mixin(oOptions); + this.instanceOptions = this.options; // per-play-instance-specific options + this._iO = this.instanceOptions; // short alias + // assign property defaults + this.pan = this.options.pan; + this.volume = this.options.volume; + this._lastURL = null; + this.isHTML5 = false; + + // --- public methods --- + + this.id3 = {}; + + this._debug = function() { + // <d> + // pseudo-private console.log()-style output + if (_s.debugMode) { + var stuff = null, msg = [], sF, sfBracket, maxLength = 64; + for (stuff in _t.options) { + if (_t.options[stuff] !== null) { + if (_t.options[stuff] instanceof Function) { + // handle functions specially + sF = _t.options[stuff].toString(); + sF = sF.replace(/\s\s+/g, ' '); // normalize spaces + sfBracket = sF.indexOf('{'); + msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }'); + } else { + msg.push(' ' + stuff + ': ' + _t.options[stuff]); + } + } + } + _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}'); + } + // </d> + }; + + this._debug(); + + this.load = function(oOptions) { + var oS = null; + if (typeof oOptions !== 'undefined') { + _t._iO = _mixin(oOptions); + _t.instanceOptions = _t._iO; + } else { + oOptions = _t.options; + _t._iO = oOptions; + _t.instanceOptions = _t._iO; + if (_t._lastURL && _t._lastURL !== _t.url) { + _wDS('manURL'); + _t._iO.url = _t.url; + _t.url = null; + } + } + _s._wD('soundManager.load(): ' + _t._iO.url, 1); + if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { + _wDS('onURL', 1); + return _t; + } + _t._lastURL = _t.url; + _t.loaded = false; + _t.readyState = 1; + _t.playState = 0; + if (_html5OK(_t._iO)) { + _s._wD('HTML 5 load: '+_t._iO.url); + oS = _t._setup_html5(_t._iO); + oS.load(); + if (_t._iO.autoPlay) { + _t.play(); + } + } else { + try { + _t.isHTML5 = false; + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_fV === 8) { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile); + } else { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream?true:false, _t._iO.autoPlay?true:false, _t._iO.loops||1, _t._iO.autoLoad?true:false, _t._iO.usePolicyFile); + } + } catch(e) { + _wDS('smError', 2); + _debugTS('onload', false); + _die(); + } + } + return _t; + }; + + this.unload = function() { + // Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 + // Flash 9/AS3: Close stream, preventing further load + if (_t.readyState !== 0) { + _s._wD('SMSound.unload(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + if (_fV === 8) { + _s.o._unload(_t.sID, _s.nullURL); + } else { + _s.o._unload(_t.sID); + } + } else { + _stop_html5_timer(); + if (_a) { + // abort()-style method here, stop loading? (doesn't exist?) + _a.pause(); + _a.src = _s.nullURL; // needed? does nulling object work? any better way to cancel/unload/abort? + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + // reset load/status flags + _resetProperties(); + } + return _t; + }; + + this.destruct = function(_bFromSM) { + _s._wD('SMSound.destruct(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + // kill sound within Flash + // Disable the onfailure handler + _t._iO.onfailure = null; + _s.o._destroySound(_t.sID); + } else { + _stop_html5_timer(); + if (_a) { + _a.pause(); + _a.src = 'about:blank'; + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + if (!_bFromSM) { + _s.destroySound(_t.sID, true); // ensure deletion from controller + } + }; + + this.play = function(oOptions, _updatePlayState) { + var fN = 'SMSound.play(): ', allowMulti; + _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState); + if (!oOptions) { + oOptions = {}; + } + _t._iO = _mixin(oOptions, _t._iO); + _t._iO = _mixin(_t._iO, _t.options); + _t.instanceOptions = _t._iO; + if (_t._iO.serverURL) { + if (!_t.connected) { + if (!_t.getAutoPlay()) { + _s._wD(fN+' Netstream not connected yet - setting autoPlay'); + _t.setAutoPlay(true); + } + return _t; + } + } + if (_html5OK(_t._iO)) { + _t._setup_html5(_t._iO); + _start_html5_timer(); + } + // KJV paused sounds have playState 1. We want these sounds to play. + if (_t.playState === 1 && !_t.paused) { + allowMulti = _t._iO.multiShot; + if (!allowMulti) { + _s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1); + return _t; + } else { + _s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1); + if (_t.isHTML5) { + // TODO: BUG? + _t.setPosition(_t._iO.position); + } + } + } + if (!_t.loaded) { + if (_t.readyState === 0) { + _s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1); + // try to get this sound playing ASAP + if (!_t.isHTML5) { + if (!_t._iO.serverURL) { + _t._iO.autoPlay = true; + _t.load(_t._iO); + } + } else { + _t.load(_t._iO); + _t.readyState = 1; + } + } else if (_t.readyState === 2) { + _s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2); + return _t; + } else { + _s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1); + } + } else { + _s._wD(fN + '"' + _t.sID + '"'); + } + // Streams will pause when their buffer is full if they are not auto-playing. + // In this case paused is true, but the song hasn't started playing yet. If + // we just call resume() the onplay() callback will never be called. + + // Also, if we just call resume() in this case and the sound has been muted + // (volume is 0), it will never have its volume set so sound will be heard + // when it shouldn't. + if (_t.paused && _t.position && _t.position > 0) { // https://gist.github.com/37b17df75cc4d7a90bf6 + _s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1); + _t.resume(); + } else { + _s._wD(fN+'"'+ _t.sID+'" is starting to play'); + _t.playState = 1; + _t.paused = false; + if (!_t.instanceCount || _t._iO.multiShotEvents || (_fV > 8 && !_t.isHTML5 && !_t.getAutoPlay())) { + _t.instanceCount++; + } + _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_t._iO.onplay && _updatePlayState) { + _t._iO.onplay.apply(_t); + } + _t.setVolume(_t._iO.volume, true); + _t.setPan(_t._iO.pan, true); + if (!_t.isHTML5) { + _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t.position:_t.position / 1000)); + } else { + _start_html5_timer(); + _t._setup_html5().play(); + } + } + return _t; + }; + + this.start = this.play; // just for convenience + + this.stop = function(bAll) { + if (_t.playState === 1) { + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (!_t.isHTML5) { + _t.playState = 0; + } + _t.paused = false; + if (_t._iO.onstop) { + _t._iO.onstop.apply(_t); + } + if (!_t.isHTML5) { + _s.o._stop(_t.sID, bAll); + // hack for netStream: just unload + if (_t._iO.serverURL) { + _t.unload(); + } + } else { + if (_a) { + _t.setPosition(0); // act like Flash, though + _a.pause(); // html5 has no stop() + _t.playState = 0; + _t._onTimer(); // and update UI + _stop_html5_timer(); + _t.unload(); + } + } + _t.instanceCount = 0; + _t._iO = {}; + } + return _t; + }; + + this.setAutoPlay = function(autoPlay) { + _s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off')); + _t._iO.autoPlay = autoPlay; + _s.o._setAutoPlay(_t.sID, autoPlay); + if (autoPlay) { + // KJV Only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP) + if (!_t.instanceCount && _t.readyState === 1) { + _t.instanceCount++; + _s._wD('sound '+_t.sID+' incremented instance count to '+_t.instanceCount); + } + } + }; + + this.getAutoPlay = function() { + return _t._iO.autoPlay; + }; + + this.setPosition = function(nMsecOffset, bNoDebug) { + if (nMsecOffset === undefined) { + nMsecOffset = 0; + } + // KJV Use the duration from the instance options, if we don't have a track duration yet. + // Auto-loading streams with a starting position in their options will start playing + // as soon as they connect. In the start() call we set the position on the stream, + // but because the stream hasn't played _t.duration won't have been set (that is + // done in whileloading()). So if we don't have a duration yet, use the duration + // from the instance options, if available. + var position, offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); // position >= 0 and <= current available (loaded) duration + _t.position = offset; + _t.resetOnPosition(_t.position); + if (!_t.isHTML5) { + position = _fV === 9 ? _t.position : _t.position / 1000; + // KJV We want our sounds to play on seek. A progressive download that + // is loaded has paused = false so resume() does nothing and the sound + // doesn't play. Handle that case here. + if (_t.playState === 0) { + _t.play({ position: position }); + } else { + _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) + // if (_t.paused) { + // _t.resume(); + // } + } + } else if (_a) { + _s._wD('setPosition(): setting position to '+(_t.position / 1000)); + if (_t.playState) { + // DOM/JS errors/exceptions to watch out for: + // if seek is beyond (loaded?) position, "DOM exception 11" + // "INDEX_SIZE_ERR": DOM exception 1 + try { + _a.currentTime = _t.position / 1000; + } catch(e) { + _s._wD('setPosition('+_t.position+'): WARN: Caught exception: '+e.message, 2); + } + } else { + _s._wD('HTML 5 warning: cannot set position while playState == 0 (not playing)',2); + } + if (_t.paused) { // if paused, refresh UI right away + _t._onTimer(true); // force update + if (_t._iO.useMovieStar) { + _t.resume(); + } + } + } + return _t; + }; + + this.pause = function(bCallFlash) { + if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { + return _t; + } + _s._wD('SMSound.pause()'); + _t.paused = true; + if (!_t.isHTML5) { + if (bCallFlash || bCallFlash === undefined) { + _s.o._pause(_t.sID); + } + } else { + _t._setup_html5().pause(); + _stop_html5_timer(); + } + if (_t._iO.onpause) { + _t._iO.onpause.apply(_t); + } + return _t; + }; + + this.resume = function() { + // When auto-loaded streams pause on buffer full they have a playState of 0. + // We need to make sure that the playState is set to 1 when these streams "resume". + if (!_t.paused) { + return _t; + } + _s._wD('SMSound.resume()'); + _t.paused = false; + _t.playState = 1; // TODO: verify that this is needed. + if (!_t.isHTML5) { + _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) + } else { + _t._setup_html5().play(); + _start_html5_timer(); + } + if (_t._iO.onresume) { + _t._iO.onresume.apply(_t); + } + return _t; + }; + + this.togglePause = function() { + _s._wD('SMSound.togglePause()'); + if (_t.playState === 0) { + _t.play({ + position: (_fV === 9 && !_t.isHTML5 ? _t.position:_t.position / 1000) + }); + return _t; + } + if (_t.paused) { + _t.resume(); + } else { + _t.pause(); + } + return _t; + }; + + this.setPan = function(nPan, bInstanceOnly) { + if (typeof nPan === 'undefined') { + nPan = 0; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setPan(_t.sID, nPan); + } // else { no HTML5 pan? } + _t._iO.pan = nPan; + if (!bInstanceOnly) { + _t.pan = nPan; + } + return _t; + }; + + this.setVolume = function(nVol, bInstanceOnly) { + if (typeof nVol === 'undefined') { + nVol = 100; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); + } else if (_a) { + _a.volume = nVol/100; + } + _t._iO.volume = nVol; + if (!bInstanceOnly) { + _t.volume = nVol; + } + return _t; + }; + + this.mute = function() { + _t.muted = true; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, 0); + } else if (_a) { + _a.muted = true; + } + return _t; + }; + + this.unmute = function() { + _t.muted = false; + var hasIO = typeof _t._iO.volume !== 'undefined'; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); + } else if (_a) { + _a.muted = false; + } + return _t; + }; + + this.toggleMute = function() { + return (_t.muted?_t.unmute():_t.mute()); + }; + + this.onposition = function(nPosition, oMethod, oScope) { + // TODO: allow for ranges, too? eg. (nPosition instanceof Array) + _t._onPositionItems.push({ + position: nPosition, + method: oMethod, + scope: (typeof oScope !== 'undefined'?oScope:_t), + fired: false + }); + return _t; + }; + + this.processOnPosition = function() { + var i, item, j = _t._onPositionItems.length; + if (!j || !_t.playState || _t._onPositionFired >= j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (!item.fired && _t.position >= item.position) { + item.method.apply(item.scope,[item.position]); + item.fired = true; + _s._onPositionFired++; + } + } + return true; + }; + + this.resetOnPosition = function(nPosition) { + // reset "fired" for items interested in this position + var i, item, j = _t._onPositionItems.length; + if (!j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (item.fired && nPosition <= item.position) { + item.fired = false; + _s._onPositionFired--; + } + } + return true; + }; + + // pseudo-private soundManager reference + + this._onTimer = function(bForce) { + // HTML 5-only _whileplaying() etc. + var time, x = {}; + if (_t._hasTimer || bForce) { + if (_a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { // TODO: May not need to track readyState (1 = loading) + _t.duration = _get_html5_duration(); + _t.durationEstimate = _t.duration; + time = _a.currentTime?_a.currentTime*1000:0; + _t._whileplaying(time,x,x,x,x); + return true; + } else { + _s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); + return false; + } + } + }; + + // --- private internals --- + + _get_html5_duration = function() { + var d = (_a?_a.duration*1000:undefined); + return (d && !isNaN(d)?d:null); + }; + + _start_html5_timer = function() { + if (_t.isHTML5) { + _startTimer(_t); + } + }; + + _stop_html5_timer = function() { + if (_t.isHTML5) { + _stopTimer(_t); + } + }; + + _resetProperties = function(bLoaded) { + _t._onPositionItems = []; + _t._onPositionFired = 0; + _t._hasTimer = null; + _t._added_events = null; + _t._audio = null; + _a = null; + _t.bytesLoaded = null; + _t.bytesTotal = null; + _t.position = null; + _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null); + _t.durationEstimate = null; + _t.failures = 0; + _t.loaded = false; + _t.playState = 0; + _t.paused = false; + _t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success + _t.muted = false; + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + _t.isBuffering = false; + _t.instanceOptions = {}; + _t.instanceCount = 0; + _t.peakData = { + left: 0, + right: 0 + }; + _t.waveformData = { + left: [], + right: [] + }; + _t.eqData = []; // legacy: 1D array + _t.eqData.left = []; + _t.eqData.right = []; + }; + + _resetProperties(); + + // pseudo-private methods used by soundManager + + this._setup_html5 = function(oOptions) { + var _iO = _mixin(_t._iO, oOptions); + if (_a) { + if (_t.url !== _iO.url) { + _s._wD('setting new URL on existing object: '+_iO.url); + _a.src = _iO.url; + } + } else { + _s._wD('creating HTML 5 audio element with URL: '+_iO.url); + _t._audio = new Audio(_iO.url); + _a = _t._audio; + _t.isHTML5 = true; + _add_html5_events(); + } + _a.loop = (_iO.loops>1?'loop':''); + return _t._audio; + }; + + // related private methods + + _add_html5_events = function() { + if (_t._added_events) { + return false; + } + _t._added_events = true; + + function _add(oEvt, oFn, bCapture) { + return (_a ? _a.addEventListener(oEvt, oFn, bCapture||false) : null); + } + + _add('load', function(e) { + _s._wD('HTML5::load: '+_t.sID); + if (_a) { + _t._onbufferchange(0); + _t._whileloading(_t.bytesTotal, _t.bytesTotal, _get_html5_duration()); + _t._onload(true); + } + }, false); + + _add('canplay', function(e) { + _s._wD('HTML5::canplay: '+_t.sID); + // enough has loaded to play + _t._onbufferchange(0); + },false); + + _add('waiting', function(e) { + _s._wD('HTML5::waiting: '+_t.sID); + // playback faster than download rate, etc. + _t._onbufferchange(1); + },false); + + _add('progress', function(e) { // not supported everywhere yet.. + _s._wD('HTML5::progress: '+_t.sID+': loaded/total: '+(e.loaded||0)+'/'+(e.total||1)); + if (!_t.loaded && _a) { + _t._onbufferchange(0); // if progress, likely not buffering + _t._whileloading(e.loaded||0, e.total||1, _get_html5_duration()); + } + }, false); + + _add('error', function(e) { + if (_a) { + _s._wD('HTML5::error: '+_a.error.code); + // call load with error state? + _t._onload(false); + } + }, false); + + _add('loadstart', function(e) { + _s._wD('HTML5::loadstart: '+_t.sID); + // assume buffering at first + _t._onbufferchange(1); + }, false); + + _add('play', function(e) { + _s._wD('HTML5::play: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + // TODO: verify if this is actually implemented anywhere yet. + _add('playing', function(e) { + _s._wD('HTML5::playing: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + _add('timeupdate', function(e) { + _t._onTimer(); + }, false); + + // avoid stupid premature event-firing bug in Safari(?) + setTimeout(function(){ + if (_t && _a) { + _add('ended',function(e) { + _s._wD('HTML5::ended: '+_t.sID); + _t._onfinish(); + }, false); + } + }, 250); + return true; + }; + + // --- "private" methods called by Flash --- + + this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { + _t.bytesLoaded = nBytesLoaded; + _t.bytesTotal = nBytesTotal; + _t.duration = Math.floor(nDuration); + _t.bufferLength = nBufferLength; + if (!_t._iO.isMovieStar) { + if (_t._iO.duration) { + // use options, if specified and larger + _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration; + } else { + _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); + } + if (_t.durationEstimate === undefined) { + _t.durationEstimate = _t.duration; + } + _t.bufferLength = nBufferLength; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } else { + _t.durationEstimate = _t.duration; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } + }; + + this._onid3 = function(oID3PropNames, oID3Data) { + // oID3PropNames: string array (names) + // ID3Data: string array (data) + _s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.'); + var oData = [], i, j; + for (i = 0, j = oID3PropNames.length; i < j; i++) { + oData[oID3PropNames[i]] = oID3Data[i]; + } + _t.id3 = _mixin(_t.id3, oData); + if (_t._iO.onid3) { + _t._iO.onid3.apply(_t); + } + }; + + this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { + if (isNaN(nPosition) || nPosition === null) { + return false; // Flash may return NaN at times + } + if (_t.playState === 0 && nPosition > 0) { + // invalid position edge case for end/stop + nPosition = 0; + } + _t.position = nPosition; + _t.processOnPosition(); + if (_fV > 8 && !_t.isHTML5) { + if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { + _t.peakData = { + left: oPeakData.leftPeak, + right: oPeakData.rightPeak + }; + } + if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { + _t.waveformData = { + left: oWaveformDataLeft.split(','), + right: oWaveformDataRight.split(',') + }; + } + if (_t._iO.useEQData) { + if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { + var eqLeft = oEQData.leftEQ.split(','); + _t.eqData = eqLeft; + _t.eqData.left = eqLeft; + if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { + _t.eqData.right = oEQData.rightEQ.split(','); + } + } + } + } + if (_t.playState === 1) { + // special case/hack: ensure buffering is false if loading from cache (and not yet started) + if (!_t.isHTML5 && _s.flashVersion === 8 && !_t.position && _t.isBuffering) { + _t._onbufferchange(0); + } + if (_t._iO.whileplaying) { + _t._iO.whileplaying.apply(_t); // flash may call after actual finish + } + if ((_t.loaded || (!_t.loaded && _t._iO.isMovieStar)) && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { + _t._onbeforefinish(); + } + } + return true; + }; + + this._onconnect = function(bSuccess) { + var fN = 'SMSound._onconnect(): '; + bSuccess = (bSuccess === 1); + _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); + _t.connected = bSuccess; + if (bSuccess) { + _t.failures = 0; + if (_t._iO.onconnect) { + _t._iO.onconnect.apply(_t,[bSuccess]); + } + // don't play if the sound is being destroyed + if (_idCheck(_t.sID) && (_t.options.autoLoad || _t.getAutoPlay())) { + _t.play(undefined, _t.getAutoPlay()); // only update the play state if auto playing + } + } + }; + + this._onload = function(nSuccess) { + var fN = 'SMSound._onload(): ', loadOK = (nSuccess?true:false); + _s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2)); + // <d> + if (!loadOK && !_t.isHTML5) { + if (_s.sandbox.noRemote === true) { + _s._wD(fN + _str('noNet'), 1); + } + if (_s.sandbox.noLocal === true) { + _s._wD(fN + _str('noLocal'), 1); + } + } + // </d> + _t.loaded = loadOK; + _t.readyState = loadOK?3:2; + _t._onbufferchange(0); + if (_t._iO.onload) { + _t._iO.onload.apply(_t, [loadOK]); + } + return true; + }; + + // fire onfailure() only once at most + // at this point we just recreate failed sounds rather than trying to reconnect. + this._onfailure = function(msg, level, code) { + _t.failures++; + _s._wD('SMSound._onfailure(): "'+_t.sID+'" count '+_t.failures); + if (_t._iO.onfailure && _t.failures === 1) { + _t._iO.onfailure(_t, msg, level, code); + } else { + _s._wD('SMSound._onfailure(): ignoring'); + } + }; + + this._onbeforefinish = function() { + if (!_t.didBeforeFinish) { + _t.didBeforeFinish = true; + if (_t._iO.onbeforefinish) { + _s._wD('SMSound._onbeforefinish(): "' + _t.sID + '"'); + _t._iO.onbeforefinish.apply(_t); + } + } + }; + + this._onjustbeforefinish = function(msOffset) { + if (!_t.didJustBeforeFinish) { + _t.didJustBeforeFinish = true; + if (_t._iO.onjustbeforefinish) { + _s._wD('SMSound._onjustbeforefinish(): "' + _t.sID + '"'); + _t._iO.onjustbeforefinish.apply(_t); + } + } + }; + + // KJV - connect & play time callback from Flash + this._onstats = function(stats) { + if (_t._iO.onstats) { + _t._iO.onstats(_t, stats); + } + }; + + this._onfinish = function() { + // _s._wD('SMSound._onfinish(): "' + _t.sID + '" got instanceCount '+_t.instanceCount); + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (_t._iO.onbeforefinishcomplete) { + _t._iO.onbeforefinishcomplete.apply(_t); + } + // reset some state items + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + if (_t.instanceCount) { + _t.instanceCount--; + if (!_t.instanceCount) { + // reset instance options + _t.playState = 0; + _t.paused = false; + _t.instanceCount = 0; + _t.instanceOptions = {}; + _stop_html5_timer(); + } + if (!_t.instanceCount || _t._iO.multiShotEvents) { + // fire onfinish for last, or every instance + if (_t._iO.onfinish) { + _s._wD('SMSound._onfinish(): "' + _t.sID + '"'); + _t._iO.onfinish.apply(_t); + } + } + } + }; + + this._onbufferchange = function(nIsBuffering) { + var fN = 'SMSound._onbufferchange()'; + if (_t.playState === 0) { + // ignore if not playing + return false; + } + if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { + return false; + } + _t.isBuffering = (nIsBuffering === 1); + if (_t._iO.onbufferchange) { + _s._wD(fN + ': ' + nIsBuffering); + _t._iO.onbufferchange.apply(_t); + } + return true; + }; + + this._ondataerror = function(sError) { + // flash 9 wave/eq data handler + if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish() + _s._wD('SMSound._ondataerror(): ' + sError); + if (_t._iO.ondataerror) { + _t._iO.ondataerror.apply(_t); + } + } + }; + + }; // SMSound() + + // --- private SM2 internals --- + + _getDocument = function() { + return (_doc.body?_doc.body:(_doc._docElement?_doc.documentElement:_doc.getElementsByTagName('div')[0])); + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _mixin = function(oMain, oAdd) { + // non-destructive merge + var o1 = {}, i, o2, o; + for (i in oMain) { // clone c1 + if (oMain.hasOwnProperty(i)) { + o1[i] = oMain[i]; + } + } + o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd); + for (o in o2) { + if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { + o1[o] = o2[o]; + } + } + return o1; + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + _html5OK = function(iO) { + return ((iO.type?_html5CanPlay({type:iO.type}):false)||_html5CanPlay(iO.url)); + }; + + _html5CanPlay = function(sURL) { + // try to find MIME, test and return truthiness + if (!_s.useHTML5Audio || !_s.hasHTML5) { + return false; + } + var result, mime, fileExt, item, aF = _s.audioFormats; + if (!_html5Ext) { + _html5Ext = []; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + _html5Ext.push(item); + if (aF[item].related) { + _html5Ext = _html5Ext.concat(aF[item].related); + } + } + } + _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')','i'); + } + mime = (typeof sURL.type !== 'undefined'?sURL.type:null); + fileExt = (typeof sURL === 'string'?sURL.toLowerCase().match(_html5Ext):null); // TODO: Strip URL queries, etc. + if (!fileExt || !fileExt.length) { + if (!mime) { + return false; + } + } else { + fileExt = fileExt[0].substr(1); // "mp3", for example + } + if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { + // result known + return _s.html5[fileExt]; + } else { + if (!mime) { + if (fileExt && _s.html5[fileExt]) { + return _s.html5[fileExt]; + } else { + // best-case guess, audio/whatever-dot-filename-format-you're-playing + mime = 'audio/'+fileExt; + } + } + result = _s.html5.canPlayType(mime); + _s.html5[fileExt] = result; + // _s._wD('canPlayType, found result: '+result); + return result; + } + }; + + _testHTML5 = function() { + if (!_s.useHTML5Audio || typeof Audio === 'undefined') { + return false; + } + var a = (typeof Audio !== 'undefined' ? new Audio():null), item, support = {}, aF, i; + function _cp(m) { + var canPlay, i, j, isOK = false; + if (!a || typeof a.canPlayType !== 'function') { + return false; + } + if (m instanceof Array) { + // iterate through all mime types, return any successes + for (i=0, j=m.length; i<j && !isOK; i++) { + if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) { + isOK = true; + _s.html5[m[i]] = true; + } + } + return isOK; + } else { + canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false); + return (canPlay && (canPlay.match(_s.html5Test)?true:false)); + } + } + // test all registered formats + codecs + aF = _s.audioFormats; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + support[item] = _cp(aF[item].type); + // assign result to related formats, too + if (aF[item] && aF[item].related) { + for (i=0; i<aF[item].related.length; i++) { + _s.html5[aF[item].related[i]] = support[item]; + } + } + } + } + support.canPlayType = (a?_cp:null); + _s.html5 = _mixin(_s.html5, support); + return true; + }; + + _strings = { + // <d> + notReady: 'Not loaded yet - wait for soundManager.onload()/onready()', + notOK: 'Audio support is not available.', + appXHTML: _sm + '::createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', + spcWmode: _sm + '::createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue', + swf404: _sm + ': Verify that %s is a valid path.', + tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)', + checkSWF: 'See SWF output for more debug info.', + localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', + waitFocus: _sm + ': Special case: Waiting for focus-related event..', + waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', + waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', + needFunction: _sm + '.onready(): Function object expected', + badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', + noMS: 'MovieStar mode not enabled. Exiting.', + currentObj: '--- ' + _sm + '._debug(): Current sound objects ---', + waitEI: _sm + '::initMovie(): Waiting for ExternalInterface call from Flash..', + waitOnload: _sm + ': Waiting for window.onload()', + docLoaded: _sm + ': Document already loaded', + onload: _sm + '::initComplete(): calling soundManager.onload()', + onloadOK: _sm + '.onload() complete', + init: '-- ' + _sm + '::init() --', + didInit: _sm + '::init(): Already called?', + flashJS: _sm + ': Attempting to call Flash from JS..', + noPolling: _sm + ': Polling (whileloading()/whileplaying() support) is disabled.', + secNote: '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', + badRemove: 'Warning: Failed to remove flash movie.', + noPeak: 'Warning: peakData features unsupported for movieStar formats', + shutdown: _sm + '.disable(): Shutting down', + queue: _sm + '.onready(): Queueing handler', + smFail: _sm + ': Failed to initialise.', + smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', + fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..', + fbLoaded: 'Flash loaded', + fbHandler: 'soundManager::flashBlockHandler()', + manURL: 'SMSound.load(): Using manually-assigned URL', + onURL: _sm + '.load(): current URL already assigned.', + badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.', + as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)', + noNSLoop: 'Note: Looping not implemented for MovieStar formats', + needfl9: 'Note: Switching to flash 9, required for MP4 formats.', + mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case', + mfOn: 'mobileFlash::enabling on-screen flash repositioning', + policy: 'Enabling usePolicyFile for data access' + // </d> + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _str = function() { // o [,items to replace] + // <d> + var args = _slice.call(arguments), // real array, please + o = args.shift(), // first arg + str = (_strings && _strings[o]?_strings[o]:''), i, j; + if (str && args && args.length) { + for (i = 0, j = args.length; i < j; i++) { + str = str.replace('%s', args[i]); + } + } + return str; + // </d> + }; + + _loopFix = function(sOpt) { + // flash 8 requires stream = false for looping to work + if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { + _wDS('as2loop'); + sOpt.stream = false; + } + return sOpt; + }; + + _policyFix = function(sOpt, sPre) { + if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { + _s._wD((sPre?sPre+':':'') + _str('policy')); + sOpt.usePolicyFile = true; + } + return sOpt; + }; + + _complain = function(sMsg) { + if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + console.warn(sMsg); + } else { + _s._wD(sMsg); + } + }; + + _doNothing = function() { + return false; + }; + + _disableObject = function(o) { + for (var oProp in o) { + if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { + o[oProp] = _doNothing; + } + } + oProp = null; + }; + + _failSafely = function(bNoDisable) { + // general failure exception handler + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled || bNoDisable) { + _wDS('smFail', 2); + _s.disable(bNoDisable); + } + }; + + _normalizeMovieURL = function(smURL) { + var urlParams = null; + if (smURL) { + if (smURL.match(/\.swf(\?\.*)?$/i)) { + urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4); + if (urlParams) { + return smURL; // assume user knows what they're doing + } + } else if (smURL.lastIndexOf('/') !== smURL.length - 1) { + smURL = smURL + '/'; + } + } + return (smURL && smURL.lastIndexOf('/') !== - 1?smURL.substr(0, smURL.lastIndexOf('/') + 1):'./') + _s.movieURL; + }; + + _setVersionInfo = function() { + if (_fV !== 8 && _fV !== 9) { + _s._wD(_str('badFV', _fV, _defaultFlashVersion)); + _s.flashVersion = _defaultFlashVersion; + } + var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); // debug flash movie, if applicable + if (_s.flashVersion < 9 && _s.useHTML5Audio && _s.audioFormats.mp4.required) { + _s._wD(_str('needfl9')); + _s.flashVersion = 9; + } + _fV = _s.flashVersion; // short-hand for internal use + _s.version = _s.versionNumber + (_html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); + // set up default options + if (_fV > 8) { + _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); + _s.features.buffering = true; + } + if (_fV > 8 && _s.useMovieStar) { + // flash 9+ support for movieStar formats as well as MP3 + _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); + _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _s.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + _s.mimePattern = _s.netStreamMimeTypes; + _s.features.movieStar = true; + } else { + _s.features.movieStar = false; + } + _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; + _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf',isDebug); + _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); + }; + + _setPolling = function(bPolling, bHighPerformance) { + if (!_s.o || !_s.allowPolling) { + return false; + } + _s.o._setPolling(bPolling, bHighPerformance); + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + function _initDebug() { + if (_s.debugURLParam.test(_wl)) { + _s.debugMode = true; // allow force of debug mode via URL + } + // <d> + if (_id(_s.debugID)) { + return false; + } + var oD, oDebug, oTarget, oToggle, tmp; + if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) { + oD = _doc.createElement('div'); + oD.id = _s.debugID + '-toggle'; + oToggle = { + 'position': 'fixed', + 'bottom': '0px', + 'right': '0px', + 'width': '1.2em', + 'height': '1.2em', + 'lineHeight': '1.2em', + 'margin': '2px', + 'textAlign': 'center', + 'border': '1px solid #999', + 'cursor': 'pointer', + 'background': '#fff', + 'color': '#333', + 'zIndex': 10001 + }; + oD.appendChild(_doc.createTextNode('-')); + oD.onclick = _toggleDebug; + oD.title = 'Toggle SM2 debug console'; + if (_ua.match(/msie 6/i)) { + oD.style.position = 'absolute'; + oD.style.cursor = 'hand'; + } + for (tmp in oToggle) { + if (oToggle.hasOwnProperty(tmp)) { + oD.style[tmp] = oToggle[tmp]; + } + } + oDebug = _doc.createElement('div'); + oDebug.id = _s.debugID; + oDebug.style.display = (_s.debugMode?'block':'none'); + if (_s.debugMode && !_id(oD.id)) { + try { + oTarget = _getDocument(); + oTarget.appendChild(oD); + } catch(e2) { + throw new Error(_str('appXHTML')); + } + oTarget.appendChild(oDebug); + } + } + oTarget = null; + // </d> + } + + _mobileFlash = (function(){ + + var oM = null; + + function resetPosition() { + if (oM) { + oM.left = oM.top = '-9999px'; + } + } + + function reposition() { + oM.left = _win.scrollX+'px'; + oM.top = _win.scrollY+'px'; + } + + function setReposition(bOn) { + _s._wD('mobileFlash::flash on-screen hack: '+(bOn?'ON':'OFF')); + var f = _win[(bOn?'add':'remove')+'EventListener']; + f('resize', reposition, false); + f('scroll', reposition, false); + } + + function check(inDoc) { + // mobile flash (Android for starters) check + oM = _s.oMC.style; + if (_ua.match(/android/i)) { + if (inDoc) { + if (_s.flashLoadTimeout) { + _s._wDS('mfTimeout'); + _s.flashLoadTimeout = 0; + } + return false; + } + _s._wD('mfOn'); + oM.position = 'absolute'; + oM.left = oM.top = '0px'; + setReposition(true); + _s.onready(function(){ + setReposition(false); // detach + resetPosition(); // restore when OK/timed out + }); + reposition(); + } + return true; + } + + return { + 'check': check + }; + + }()); + + _createMovie = function(smID, smURL) { + + var specialCase = null, + remoteURL = (smURL?smURL:_s.url), + localURL = (_s.altURL?_s.altURL:remoteURL), + oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(), s, x, sClass, side = '100%', isRTL = null, html = _doc.getElementsByTagName('html')[0]; + isRTL = (html && html.dir && html.dir.match(/rtl/i)); + smID = (typeof smID === 'undefined'?_s.id:smID); + + if (_didAppend && _appendSuccess) { + return false; // ignore if already succeeded + } + + function _initMsg() { + _s._wD('-- SoundManager 2 ' + _s.version + (!_html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (_s.useMovieStar?', MovieStar mode':'') + (_s.useHighPerformance?', high performance mode, ':', ') + ((_s.useFastPolling?'fast':'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') + ' --', 1); + } + + if (_html5Only) { + _setVersionInfo(); + _initMsg(); + _s.oMC = _id(_s.movieID); + _init(); + // prevent multiple init attempts + _didAppend = true; + _appendSuccess = true; + return false; + } + + _didAppend = true; + + // safety check for legacy (change to Flash 9 URL) + _setVersionInfo(); + _s.url = _normalizeMovieURL(this._overHTTP?remoteURL:localURL); + smURL = _s.url; + + _s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); + + if (_s.wmode !== null && !_isIE && !_s.useHighPerformance && navigator.platform.match(/win32/i)) { + _s.specialWmodeCase = true; + // extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here + // does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout + _wDS('spcWmode'); + _s.wmode = null; + } + + oEmbed = { + 'name': smID, + 'id': smID, + 'src': smURL, + 'width': side, + 'height': side, + 'quality': 'high', + 'allowScriptAccess': _s.allowScriptAccess, + 'bgcolor': _s.bgColor, + 'pluginspage': 'http://www.macromedia.com/go/getflashplayer', + 'type': 'application/x-shockwave-flash', + 'wmode': _s.wmode + }; + + if (_s.debugFlash) { + oEmbed.FlashVars = 'debug=1'; + } + + if (!_s.wmode) { + delete oEmbed.wmode; // don't write empty attribute + } + + if (_isIE) { + // IE is "special". + oMovie = _doc.createElement('div'); + movieHTML = '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" width="' + oEmbed.width + '" height="' + oEmbed.height + '"><param name="movie" value="' + smURL + '" /><param name="AllowScriptAccess" value="' + _s.allowScriptAccess + '" /><param name="quality" value="' + oEmbed.quality + '" />' + (_s.wmode?'<param name="wmode" value="' + _s.wmode + '" /> ':'') + '<param name="bgcolor" value="' + _s.bgColor + '" />' + (_s.debugFlash?'<param name="FlashVars" value="' + oEmbed.FlashVars + '" />':'') + '<!-- --></object>'; + } else { + oMovie = _doc.createElement('embed'); + for (tmp in oEmbed) { + if (oEmbed.hasOwnProperty(tmp)) { + oMovie.setAttribute(tmp, oEmbed[tmp]); + } + } + } + + _initDebug(); + extraClass = _getSWFCSS(); + oTarget = _getDocument(); + + if (oTarget) { + _s.oMC = _id(_s.movieID)?_id(_s.movieID):_doc.createElement('div'); + if (!_s.oMC.id) { + _s.oMC.id = _s.movieID; + _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass; + // "hide" flash movie + s = null; + oEl = null; + if (!_s.useFlashBlock) { + if (_s.useHighPerformance) { + s = { + 'position': 'fixed', + 'width': '8px', + 'height': '8px', + // >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes. + 'bottom': '0px', + 'left': '0px', + 'overflow': 'hidden' + }; + } else { + s = { + 'position': 'absolute', + 'width': '6px', + 'height': '6px', + 'top': '-9999px', + 'left': '-9999px' + }; + if (isRTL) { + s.left = Math.abs(parseInt(s.left,10))+'px'; + } + } + } + if (_ua.match(/webkit/i)) { + _s.oMC.style.zIndex = 10000; // soundcloud-reported render/crash fix, safari 5 + } + if (!_s.debugFlash) { + for (x in s) { + if (s.hasOwnProperty(x)) { + _s.oMC.style[x] = s[x]; + } + } + } + try { + if (!_isIE) { + _s.oMC.appendChild(oMovie); + } + oTarget.appendChild(_s.oMC); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + } catch(e) { + throw new Error(_str('appXHTML')); + } + _mobileFlash.check(); + } else { + // it's already in the document. + sClass = _s.oMC.className; + _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:''); + _s.oMC.appendChild(oMovie); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + _mobileFlash.check(true); + } + } + + if (specialCase) { + _s._wD(specialCase); + } + + _initMsg(); + _s._wD('soundManager::createMovie(): Trying to load ' + smURL + (!this._overHTTP && _s.altURL?' (alternate URL)':''), 1); + + return true; + }; + + _idCheck = this.getSoundById; + + _initMovie = function() { + if (_html5Only) { + _createMovie(); + return false; + } + // attempt to get, or create, movie + if (_s.o) { + return false; // may already exist + } + _s.o = _s.getMovie(_s.id); // inline markup + if (!_s.o) { + if (!_oRemoved) { + // try to create + _createMovie(_s.id, _s.url); + } else { + // try to re-append removed movie after reboot() + if (!_isIE) { + _s.oMC.appendChild(_oRemoved); + } else { + _s.oMC.innerHTML = _oRemovedHTML; + } + _oRemoved = null; + _didAppend = true; + } + _s.o = _s.getMovie(_s.id); + } + if (_s.o) { + _s._wD('soundManager::initMovie(): Got '+_s.o.nodeName+' element ('+(_didAppend?'created via JS':'static HTML')+')'); + _wDS('waitEI'); + } + if (_s.oninitmovie instanceof Function) { + setTimeout(_s.oninitmovie, 1); + } + return true; + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + _delayWaitForEI = function() { + setTimeout(_waitForEI, 500); + }; + + _waitForEI = function() { + if (_waitingForEI) { + return false; + } + _waitingForEI = true; + _removeEvt(_win, 'load', _delayWaitForEI); + if (_tryInitOnFocus && !_isFocused) { + _wDS('waitFocus'); + return false; + } + var p; + if (!_didInit) { + p = _s.getMoviePercent(); + _s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':'')))); + } + setTimeout(function() { + p = _s.getMoviePercent(); + if (!_didInit) { + _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2); + if (!this._overHTTP && p) { + _wDS('localFail', 2); + if (!_s.debugFlash) { + _wDS('tryDebug', 2); + } + } + if (p === 0) { + // if 0 (not null), probably a 404. + _s._wD(_str('swf404', _s.url)); + } + _debugTS('flashtojs', false, ': Timed out' + this._overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); + } + // give up / time-out, depending + if (!_didInit && _okToDisable) { + if (p === null) { + // SWF failed. Maybe blocked. + if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + _wDS('waitForever'); + } else { + // old SM2 behaviour, simply fail + _failSafely(true); + } + } else { + // flash loaded? Shouldn't be a blocking issue, then. + if (_s.flashLoadTimeout === 0) { + _wDS('waitForever'); + } else { + _failSafely(true); + } + } + } + }, _s.flashLoadTimeout); + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + // <d> + _wDS = function(o, errorLevel) { + if (!o) { + return ''; + } else { + return _s._wD(_str(o), errorLevel); + } + }; + + if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { + _s._wD = function(sText) {alert(sText);}; + } + + _toggleDebug = function() { + var o = _id(_s.debugID), + oT = _id(_s.debugID + '-toggle'); + if (!o) { + return false; + } + if (_debugOpen) { + // minimize + oT.innerHTML = '+'; + o.style.display = 'none'; + } else { + oT.innerHTML = '-'; + o.style.display = 'block'; + } + _debugOpen = !_debugOpen; + }; + + _debugTS = function(sEventType, bSuccess, sMessage) { + // troubleshooter debug hooks + if (typeof sm2Debugger !== 'undefined') { + try { + sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); + } catch(e) { + // oh well + } + } + return true; + }; + // </d> + + _getSWFCSS = function() { + var css = []; + if (_s.debugMode) { + css.push(_s.swfCSS.sm2Debug); + } + if (_s.debugFlash) { + css.push(_s.swfCSS.flashDebug); + } + if (_s.useHighPerformance) { + css.push(_s.swfCSS.highPerf); + } + return css.join(' '); + }; + + _flashBlockHandler = function() { + // *possible* flash block situation. + var name = _str('fbHandler'), p = _s.getMoviePercent(); + if (!_s.supported()) { + if (_needsFlash) { + // make the movie more visible, so user can fix + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + ' ' + (p === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':'')); + } + _s.didFlashBlock = true; + _processOnReady(true); // fire onready(), complain lightly + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + } else { + // SM2 loaded OK (or recovered) + if (_s.didFlashBlock) { + _s._wD(name+': Unblocked'); + } + if (_s.oMC) { + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + (' '+_s.swfCSS.swfUnblocked); + } + } + }; + + _handleFocus = function() { + function cleanup() { + _removeEvt(_win, 'focus', _handleFocus); + _removeEvt(_win, 'load', _handleFocus); + } + if (_isFocused || !_tryInitOnFocus) { + cleanup(); + return true; + } + _okToDisable = true; + _isFocused = true; + _s._wD('soundManager::handleFocus()'); + if (_isSafari && _tryInitOnFocus) { + // giant Safari 3.1 hack - assume mousemove = focus given lack of focus event + _removeEvt(_win, 'mousemove', _handleFocus); + } + // allow init to restart + _waitingForEI = false; + cleanup(); + return true; + }; + + _initComplete = function(bNoDisable) { + if (_didInit) { + return false; + } + if (_html5Only) { + // all good. + _s._wD('-- SoundManager 2: loaded --'); + _didInit = true; + _processOnReady(); + _initUserOnload(); + return true; + } + var sClass = _s.oMC.className, + wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()); + if (!wasTimeout) { + _didInit = true; + } + _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1); + if (_disabled || bNoDisable) { + if (_s.useFlashBlock) { + _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + } + _processOnReady(); + _debugTS('onload', false); + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + return false; + } else { + _debugTS('onload', true); + } + if (_s.waitForWindowLoad && !_windowLoaded) { + _wDS('waitOnload'); + _addEvt(_win, 'load', _initUserOnload); + return false; + } else { + if (_s.waitForWindowLoad && _windowLoaded) { + _wDS('docLoaded'); + } + _initUserOnload(); + } + return true; + }; + + _addOnReady = function(oMethod, oScope) { + _onready.push({ + 'method': oMethod, + 'scope': (oScope || null), + 'fired': false + }); + }; + + _processOnReady = function(ignoreInit) { + if (!_didInit && !ignoreInit) { + // not ready yet. + return false; + } + var status = { + success: (ignoreInit?_s.supported():!_disabled) + }, + queue = [], i, j, + canRetry = (!_s.useFlashBlock || (_s.useFlashBlock && !_s.supported())); + for (i = 0, j = _onready.length; i < j; i++) { + if (_onready[i].fired !== true) { + queue.push(_onready[i]); + } + } + if (queue.length) { + _s._wD(_sm + ': Firing ' + queue.length + ' onready() item' + (queue.length > 1?'s':'')); + for (i = 0, j = queue.length; i < j; i++) { + if (queue[i].scope) { + queue[i].method.apply(queue[i].scope, [status]); + } else { + queue[i].method(status); + } + if (!canRetry) { // flashblock case doesn't count here + queue[i].fired = true; + } + } + } + return true; + }; + + _initUserOnload = function() { + _win.setTimeout(function() { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + _processOnReady(); + _wDS('onload', 1); + // call user-defined "onload", scoped to window + if (_s.onload instanceof Function) { + _s.onload.apply(_win); + } + _wDS('onloadOK', 1); + if (_s.waitForWindowLoad) { + _addEvt(_win, 'load', _initUserOnload); + } + },1); + }; + + _featureCheck = function() { + var needsFlash, item, + isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_(3|4)/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" bug. https://bugs.webkit.org/show_bug.cgi?id=32159 + isSpecial = (_ua.match(/iphone os (1|2|3_0|3_1)/i)?true:false); // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works. + if (isSpecial) { + _s.hasHTML5 = false; // has Audio(), but is broken; let it load links directly. + _html5Only = true; // ignore flash case, however + if (_s.oMC) { + _s.oMC.style.display = 'none'; + } + return false; + } + if (_s.useHTML5Audio) { + if (!_s.html5 || !_s.html5.canPlayType) { + _s._wD('SoundManager: No HTML5 Audio() support detected.'); + _s.hasHTML5 = false; + return true; + } else { + _s.hasHTML5 = true; + } + if (isBadSafari) { + _s._wD('SoundManager::Note: Buggy HTML5 Audio in Safari on OS X 10.6.[3|4], see https://bugs.webkit.org/show_bug.cgi?id=32159 - disabling HTML5 audio',1); + _s.useHTML5Audio = false; + _s.hasHTML5 = false; + return true; + } + } else { + // flash required. + return true; + } + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item) && _s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) { + // may need flash for this format? + needsFlash = true; + } + } + // sanity check.. + if (_s.ignoreFlash) { + needsFlash = false; + } + _html5Only = (_s.useHTML5Audio && _s.hasHTML5 && !needsFlash); + return needsFlash; + }; + + _init = function() { + var item, tests = []; + _wDS('init'); + + // called after onload() + if (_didInit) { + _wDS('didInit'); + return false; + } + + function _cleanup() { + _removeEvt(_win, 'load', _s.beginDelayedInit); + } + + if (_s.hasHTML5) { + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item)) { + tests.push(item+': '+_s.html5[item]); + } + } + _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); + } + + if (_html5Only) { + if (!_didInit) { + // we don't need no steenking flash! + _cleanup(); + _s.enabled = true; + _initComplete(); + } + return true; + } + + // flash path + _initMovie(); + try { + _wDS('flashJS'); + _s.o._externalInterfaceTest(false); // attempt to talk to Flash + if (!_s.allowPolling) { + _wDS('noPolling', 1); + } else { + _setPolling(true, _s.useFastPolling?true:false); + } + if (!_s.debugMode) { + _s.o._disableDebug(); + } + _s.enabled = true; + _debugTS('jstoflash', true); + } catch(e) { + _s._wD('js/flash exception: ' + e.toString()); + _debugTS('jstoflash', false); + _failSafely(true); // don't disable, for reboot() + _initComplete(); + return false; + } + _initComplete(); + // event cleanup + _cleanup(); + return true; + }; + + _beginInit = function() { + if (_initPending) { + return false; + } + _createMovie(); + _initMovie(); + _initPending = true; + return true; + }; + + _dcLoaded = function() { + if (_didDCLoaded) { + return false; + } + _didDCLoaded = true; + _initDebug(); + _testHTML5(); + _s.html5.usingFlash = _featureCheck(); + _needsFlash = _s.html5.usingFlash; + _didDCLoaded = true; + if (_doc.removeEventListener) { + _doc.removeEventListener('DOMContentLoaded', _dcLoaded, false); + } + _go(); + return true; + }; + + _startTimer = function(oSound) { + if (!oSound._hasTimer) { + oSound._hasTimer = true; + } + }; + + _stopTimer = function(oSound) { + if (oSound._hasTimer) { + oSound._hasTimer = false; + } + }; + + _die = function() { + if (_s.onerror instanceof Function) { + _s.onerror(); + } + _s.disable(); + }; + + // pseudo-private methods called by Flash + + this._setSandboxType = function(sandboxType) { + // <d> + var sb = _s.sandbox; + sb.type = sandboxType; + sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')]; + _s._wD('Flash security sandbox type: ' + sb.type); + if (sb.type === 'localWithFile') { + sb.noRemote = true; + sb.noLocal = false; + _wDS('secNote', 2); + } else if (sb.type === 'localWithNetwork') { + sb.noRemote = false; + sb.noLocal = true; + } else if (sb.type === 'localTrusted') { + sb.noRemote = false; + sb.noLocal = false; + } + // </d> + }; + + this._externalInterfaceOK = function(flashDate) { + // flash callback confirming flash loaded, EI working etc. + // flashDate = approx. timing/delay info for JS/flash bridge + if (_s.swfLoaded) { + return false; + } + var eiTime = new Date().getTime(); + _s._wD('soundManager::externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); + _debugTS('swf', true); + _debugTS('flashtojs', true); + _s.swfLoaded = true; + _tryInitOnFocus = false; + if (_isIE) { + // IE needs a timeout OR delay until window.onload - may need TODO: investigating + setTimeout(_init, 100); + } else { + _init(); + } + }; + + _dcIE = function() { + if (_doc.readyState === 'complete') { + _dcLoaded(); + _doc.detachEvent('onreadystatechange', _dcIE); + } + return true; + }; + + // focus and window load, init + if (!_s.hasHTML5 || _needsFlash) { + // only applies to Flash mode + _addEvt(_win, 'focus', _handleFocus); + _addEvt(_win, 'load', _handleFocus); + _addEvt(_win, 'load', _delayWaitForEI); + if (_isSafari && _tryInitOnFocus) { + _addEvt(_win, 'mousemove', _handleFocus); // massive Safari focus hack + } + } + + if (_doc.addEventListener) { + _doc.addEventListener('DOMContentLoaded', _dcLoaded, false); + } else if (_doc.attachEvent) { + _doc.attachEvent('onreadystatechange', _dcIE); + } else { + // no add/attachevent support - safe to assume no JS -> Flash either + _debugTS('onload', false); + _die(); + } + + if (_doc.readyState === 'complete') { + setTimeout(_dcLoaded,100); + } + +} // SoundManager() + +// var SM2_DEFER = true; +// details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading + +if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { + soundManager = new SoundManager(); +} + +// public interfaces +window.SoundManager = SoundManager; // constructor +window.soundManager = soundManager; // public instance: API, Flash callbacks etc. + +}(window)); diff --git a/docs/dymaxion/soundmanager2.swf b/docs/dymaxion/soundmanager2.swf Binary files differnew file mode 100755 index 0000000..4d2dc23 --- /dev/null +++ b/docs/dymaxion/soundmanager2.swf diff --git a/docs/dymaxion/soundmanager2_debug.swf b/docs/dymaxion/soundmanager2_debug.swf Binary files differnew file mode 100755 index 0000000..01ce0ea --- /dev/null +++ b/docs/dymaxion/soundmanager2_debug.swf diff --git a/docs/dymaxion/soundmanager2_flash9.swf b/docs/dymaxion/soundmanager2_flash9.swf Binary files differnew file mode 100755 index 0000000..dad27ea --- /dev/null +++ b/docs/dymaxion/soundmanager2_flash9.swf diff --git a/docs/dymaxion/soundmanager2_flash9_debug.swf b/docs/dymaxion/soundmanager2_flash9_debug.swf Binary files differnew file mode 100755 index 0000000..cdffb46 --- /dev/null +++ b/docs/dymaxion/soundmanager2_flash9_debug.swf diff --git a/docs/dymaxion/soundmanagerv297a-20101010.zip b/docs/dymaxion/soundmanagerv297a-20101010.zip Binary files differnew file mode 100644 index 0000000..b9931d8 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010.zip diff --git a/docs/dymaxion/soundmanagerv297a-20101010/README.rdoc b/docs/dymaxion/soundmanagerv297a-20101010/README.rdoc new file mode 100755 index 0000000..b121244 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/README.rdoc @@ -0,0 +1,98 @@ +== SoundManager 2: JavaScript Sound for the Web
+
+By wrapping and extending HTML5 and Flash Audio APIs, SoundManager 2 brings reliable cross-platform audio to JavaScript.
+
+== HTML5 Audio() Support (Beta-ish)
+
+ * 100% Flash-free MP3 + MP4/AAC where supported, compatible with Apple iPad 3.2, iPhone/iOS 4
+ * Fallback to Flash for MP3/MP4 support, as needed
+ * SM2 API is unchanged, transparent; HTML5/flash switching handled internally
+ * HTML5 API support approximates Flash 8 API features, minus ID3, plus buffering
+ * Some other formats (WAV/OGG) supported via HTML5, depending on browser
+ * See soundManager.useHTML5Audio for implementation details.
+
+== Basic API Features (Flash 8)
+
+ * Load, stop, play, pause, mute, seek, pan and volume control of sounds from Javascript
+ * Events: onload, whileloading, whileplaying, onfinish and more
+ * ID3V1 and ID3V2 tag support for MP3s (title, artist, genre etc.)
+
+== Shiny Flash 9 Features
+
+ * RTMP / Flash Media Server streaming support (new, experimental)
+ * MPEG-4 (AAC, HE-AAC, H.264) audio support
+ * "MultiShot" play (layered/chorusing effects)
+ * Waveform/frequency spectrum data
+ * Peak (L/R channel volume) data
+ * Audio buffering state/event handling
+
+== General Tech Stuff
+
+ * Full API Documentation with examples and notes
+ * console.log()-style debug output and troubleshooting tools
+ * Community-based discussion/support
+
+== As heard on The Internets
+
+A few nifty sites that have implemented SM2 for driving audio:
+
+ * Muxtape
+ * SoundCloud / The Cloud Player
+ * 8tracks
+ * Last.fm
+ * Opera (media player component)
+ * Discogs
+ * Mixcrate
+
+== Project home, documentation, live demos etc.:
+
+http://www.schillmania.com/projects/soundmanager2/
+
+
+== Merged fork ( kjvarga: http://github.com/kjvarga/SoundManager2/ )
+
+This SM2 fork contains the SoundManager2 implementation that is used on http://www.kazaa.com.
+
+We added RTMP support to SM2 which is now part of the SM2 (experimental) branch as of V2.96a.20100606.
+
+Downloads: http://www.schillmania.com/projects/soundmanager2/doc/download/
+
+For more background on the addition of RTMP check out http://getsatisfaction.com/schillmania/topics/soundmanager_doesnt_support_rtmp
+
+Our old branch of development has been moved to http://github.com/kjvarga/SoundManager2/tree/pre_merge.
+
+== Changes
+
+In addition to the documented SM2 options, we have added the following.
+
+New options to SM2:
+
+* <tt>ondebuglog</tt> callback called with every debugging message. Useful if you need to programatically have access to the debug logs. We use this in our automated reporting of stream failures for QA.
+
+New options to createSound:
+
+* <tt>bufferTimes</tt> optional array of buffer times for double/multiple-buffering. Just specify an array of incrementing buffer sizes (in seconds) e.g. [0.5, 2, 8] for a half-second, then 2 second, then 8 second buffer. Buffers increment when full and reset to the smallest buffer when empty, or when starting to play an unbuffered portion of the stream.
+* <tt>onstats</tt> callback called with statistics including how long it took to connect to the server, and how long it took to play (useful for QA).
+
+Our FMS server has some peculiarities that we have to deal with:
+* bytesLoaded is always 0 for a streaming sound
+* NetStream.Play.Stop is sent when it shouldn't
+* We cannot get the stream length using a typical <tt>getStreamLength</tt> call
+* We cannot get bandwidth information
+
+== Debugging
+
+1. Set <tt>soundManager.debugFlash = true;</tt>
+2. Use a debug version of the SWF e.g. soundmanager2_flash9_debug.swf
+3. Open the Flash IDE. Open the SM2 source code files. Start a remote debugging session.
+4. Refresh the application in the browser (make sure caching is off).
+5. The SWF should connect to Flash and allow you to step through the source.
+
+If it doesn't:
+1. Make sure that the Flash version you have installed supports debugging
+2. Make sure that the Flash debugger application is using the same version of Flash.
+
+== SM2
+
+Project home, documentation, live demos etc.:
+http://www.schillmania.com/projects/soundmanager2/
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360 button.psd b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360 button.psd Binary files differnew file mode 100755 index 0000000..afd0498 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360 button.psd diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.gif Binary files differnew file mode 100755 index 0000000..cf9eab3 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.png Binary files differnew file mode 100755 index 0000000..8f66539 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.gif Binary files differnew file mode 100755 index 0000000..6e589ea --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.png Binary files differnew file mode 100755 index 0000000..dc84def --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-pause.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.gif Binary files differnew file mode 100755 index 0000000..eb36483 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.png Binary files differnew file mode 100755 index 0000000..a2f6557 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.gif Binary files differnew file mode 100755 index 0000000..b97cd7f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.png Binary files differnew file mode 100755 index 0000000..ce2d9a3 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360-button-play.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player-visualization.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player-visualization.css new file mode 100755 index 0000000..96cc582 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player-visualization.css @@ -0,0 +1,88 @@ +/* larger canvas, spectrum + EQ visualization and other items */
+
+.ui360,
+.sm2-360ui {
+ /* size of the container for the circle, etc. */
+ width:256px;
+ height:256px;
+}
+
+.ui360 {
+ position:relative;
+ /* a little extra spacing */
+ padding-top:1px;
+ padding-bottom:1px;
+ margin-bottom:-18px; /* approximate "line height" we want */
+ padding-left:248px;
+ margin-left:0px;
+ background-position:22.6% 50%; /* (~109px) initial play button position */
+}
+
+.ui360 a {
+ font:14px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
+ white-space:nowrap;
+ line-height:256px;
+}
+
+.sm2-360ui {
+ margin-left:-256px;
+}
+
+.ui360 .sm2-timing {
+ line-height:256px;
+}
+
+.ui360 .sm2-timing {
+ font:bold 24px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
+ color:#333;
+ text-align:center;
+ line-height:256px;
+ text-indent:0px;
+}
+
+.sm2-inline-list .ui360,
+.sm2-inline-list .sm2-360ui {
+ margin-left:0px;
+}
+
+.sm2-inline-list .ui360 {
+ margin:8px 13px 7px 0px;
+ padding-left:0px;
+ background-position:50% 50%; /* initial play button position */
+}
+
+.sm2-inline-list .sm2-360ui {
+ border:1px solid #eee;
+}
+
+.sm2-inline-list .ui360 a {
+ position:absolute;
+ left:0px;
+ bottom:0px;
+ margin-left:1px;
+ width:100%; /* 2px padding in box */
+ height:auto;
+ font-size:x-small;
+ padding:2px 0px;
+ color:#999;
+ line-height:15px;
+ text-align:center;
+ display:inline;
+ -moz-border-radius:0px;
+ -khtml-border-radius:0px;
+ border-radius:0px;
+}
+
+.sm2-inline-list .ui360 a:focus,
+.sm2-inline-list .ui360 a:active {
+ background-color:transparent;
+}
+
+/* Use a bigger loading image for this layout */
+
+.ui360 .sm2-360ui.sm2_buffering .sm2-360btn,
+.ui360 .sm2-360ui.sm2_buffering .sm2-360btn:hover {
+ background:transparent url(icon_loading_spinner_bigger.gif) no-repeat 50% 50%;
+ opacity:0.5;
+ visibility:visible;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player.css new file mode 100755 index 0000000..a961dc5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/360player.css @@ -0,0 +1,258 @@ +/* General warning: Beta-ish. Code could be a bit cleaner. */
+
+.ui360,
+.ui360 * {
+ position:relative;
+}
+
+.ui360,
+.sm2-360ui {
+ /* size of the container for the circle, etc. */
+ width:50px;
+ height:50px;
+}
+
+.ui360 {
+ position:relative;
+ /* a little extra spacing */
+ padding-top:1px;
+ padding-bottom:1px;
+ margin-bottom:-18px; /* approximate "line height" we want */
+ padding-left:42px; /* 50px, with a few off - margin used for visualization UI */
+}
+
+.ui360 a {
+ line-height:50px;
+}
+
+.sm2-360ui {
+ margin-left:-50px;
+}
+
+.ui360 {
+ width:auto;
+}
+
+.ui360,
+.ui360 * {
+ vertical-align:middle;
+}
+
+.sm2-360ui {
+ position:relative;
+ display:inline-block; /* firefox 3 et al */
+ float:left; /* firefox 2 needs this, inline-block would work with fx3 and others */
+ *float:left; /* IE 6+7 */
+ *display:inline;
+ *clear:left;
+}
+
+.sm2-360ui.sm2_playing,
+.sm2-360ui.sm2_paused {
+ /* bump on top when active */
+ z-index:10;
+}
+
+.ui360 a.sm2_link { /* this class added to playable links by SM2 */
+ position:relative;
+}
+
+.ui360 a {
+ color:#000;
+ text-decoration:none;
+}
+
+.ui360 a,
+.ui360 a:hover,
+.ui360 a:focus {
+ padding:2px;
+ margin-left:-2px;
+ margin-top:-2px;
+}
+
+.ui360 a:hover,
+.ui360 a:focus {
+ background:#eee;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+ -khtml-border-radius:3px;
+ border-radius:3px;
+ outline:none;
+}
+
+.ui360 .sm2-canvas {
+ position:absolute;
+ left:0px;
+ top:0px;
+}
+
+.ui360 .sm2-timing {
+ position:absolute;
+ display:block;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ margin:0px;
+ font:11px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
+ color:#666;
+ text-align:center;
+ line-height:50px;
+}
+
+.ui360 .sm2-timing.alignTweak {
+ text-indent:1px; /* devious center-alignment tweak for Safari (might break things for others.) */
+}
+
+.ui360 .sm2-cover {
+ position:absolute;
+ left:0px;
+ top:0px;
+ z-index:2;
+ display:none;
+}
+
+.ui360 .sm2-360btn {
+ position:absolute;
+ top:50%;
+ left:50%;
+ width:22px;
+ height:22px;
+ margin-left:-11px;
+ margin-top:-11px;
+ cursor:pointer;
+ z-index:3;
+}
+
+.ui360 .sm2-360btn-default {
+}
+
+.ui360 .sm2-360data {
+ display:inline-block;
+ font-family:helvetica;
+}
+
+.ui360 .sm2-360ui.sm2_playing .sm2-cover,
+.ui360 .sm2-360ui.sm2_paused .sm2-cover {
+ display:block;
+}
+
+/* this could be optimized a fair bit. */
+
+.ui360,
+.ui360 .sm2-360btn-default {
+ background:transparent url(360-button-play.png) no-repeat 50% 50%;
+ _background:transparent url(360-button-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */
+ cursor:pointer;
+}
+
+.ui360 {
+ /*
+ "fake" button shown before SM2 has started, non-JS/non-SM2 case etc.
+ background image will be removed via JS, in threeSixyPlayer.init()
+ */
+ background-position:6px 50%;
+}
+
+.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
+ background:transparent url(360-button-play.png) no-repeat 50% 50%;
+ _background:transparent url(360-button-play.gif) no-repeat 50% 50%;
+ cursor:pointer;
+}
+
+.ui360 .sm2-360btn-default:hover,
+.ui360 .sm2-360ui.sm2_paused .sm2-360btn:hover {
+ background:transparent url(360-button-play-light.png) no-repeat 50% 50%;
+ _background:transparent url(360-button-play.gif) no-repeat 50% 50%;
+ cursor:pointer;
+}
+
+.ui360 .sm2-360ui.sm2_playing .sm2-360btn:hover,
+.ui360 .sm2-360btn-playing:hover {
+ background:transparent url(360-button-pause-light.png) no-repeat 50% 50%;
+ _background:transparent url(360-button-pause-light.gif) no-repeat 50% 50%;
+ cursor:pointer;
+}
+
+
+.ui360 .sm2-360ui.sm2_playing .sm2-timing {
+ visibility:visible;
+}
+
+.ui360 .sm2-360ui.sm2_buffering .sm2-timing {
+ visibility:hidden;
+}
+
+.ui360 .sm2-360ui .sm2-timing,
+.ui360 .sm2-360ui .sm2-360btn:hover + .sm2-timing,
+.ui360 .sm2-360ui.sm2_paused .sm2-timing {
+ visibility:hidden;
+}
+
+.ui360 .sm2-360ui.sm2_dragging .sm2-timing,
+.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover + .sm2-timing {
+ /* paused + dragging */
+ visibility:visible;
+}
+
+.ui360 .sm2-360ui.sm2_playing .sm2-360btn,
+x.ui360 .sm2-360btn-playing,
+.ui360 .sm2-360ui.sm2_dragging .sm2-360btn,
+.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover,
+.ui360 .sm2-360ui.sm2_dragging .sm2-360btn-playing:hover {
+ /* don't let pause button show on hover when dragging (or paused and dragging) */
+ background:transparent;
+ cursor:auto;
+}
+
+.ui360 .sm2-360ui.sm2_buffering .sm2-360btn,
+.ui360 .sm2-360ui.sm2_buffering .sm2-360btn:hover {
+ background:transparent url(icon_loading_spinner.gif) no-repeat 50% 50%;
+ opacity:0.5;
+ visibility:visible;
+}
+
+/* inline list style */
+
+.sm2-inline-list .ui360,
+.sm2-inline-block .ui360 {
+ position:relative;
+ display:inline-block;
+ float:left;
+ _display:inline;
+ margin-bottom:-15px;
+}
+
+.sm2-inline-list .ui360 {
+ margin-bottom:0px;
+}
+
+.sm2-inline-block .ui360 {
+ margin-right:8px;
+}
+
+.sm2-inline-list .ui360 a {
+ display:none;
+}
+
+/* annotations */
+
+ul.ui360playlist {
+ list-style-type:none;
+}
+
+ul.ui360playlist,
+ul.ui360playlist li {
+ margin:0px;
+ padding:0px;
+}
+
+div.ui360 div.metadata {
+ display:none;
+}
+
+div.ui360 a span.metadata,
+div.ui360 a span.metadata * {
+ /* name of track, note etc. */
+ vertical-align:baseline;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization-basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization-basic.html new file mode 100755 index 0000000..789846b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization-basic.html @@ -0,0 +1,125 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>360° MP3 player UI demo (SoundManager 2): Javascript + Canvas Visualization, basic example</title>
+<meta name="description" content="Basic example of 360-degree circular control for MP3 links, with EQ and spectrum visualization options" />
+<!-- demo: make the fonts nicer etc. -->
+<link rel="stylesheet" type="text/css" href="../index.css" />
+
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+
+<!-- required -->
+<link rel="stylesheet" type="text/css" href="360player.css" />
+<link rel="stylesheet" type="text/css" href="360player-visualization.css" />
+
+<!-- special IE-only canvas fix -->
+<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
+
+<!-- Apache-licensed animation library -->
+<script type="text/javascript" src="script/berniecode-animator.js"></script>
+
+<!-- the core stuff -->
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/360player.js"></script>
+
+<script type="text/javascript">
+
+soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
+
+soundManager.useFastPolling = true; // increased JS callback frequency, combined with useHighPerformance = true
+
+threeSixtyPlayer.config.scaleFont = (navigator.userAgent.match(/msie/i)?false:true);
+threeSixtyPlayer.config.showHMSTime = true;
+
+// enable some spectrum stuffs
+
+threeSixtyPlayer.config.useWaveformData = true;
+threeSixtyPlayer.config.useEQData = true;
+
+// enable this in SM2 as well, as needed
+
+if (threeSixtyPlayer.config.useWaveformData) {
+ soundManager.flash9Options.useWaveformData = true;
+}
+if (threeSixtyPlayer.config.useEQData) {
+ soundManager.flash9Options.useEQData = true;
+}
+if (threeSixtyPlayer.config.usePeakData) {
+ soundManager.flash9Options.usePeakData = true;
+}
+
+// favicon is expensive CPU-wise, but can be enabled.
+threeSixtyPlayer.config.useFavIcon = false;
+
+</script>
+
+<link rel="stylesheet" type="text/css" href="demo.css" />
+<style type="text/css">
+
+#left h2 {
+ padding-top:0px;
+ margin-bottom:0.25em;
+ color:#666;
+}
+
+pre.block {
+ margin-top:0.5em;
+}
+
+/* special case */
+
+#left {
+ width:auto;
+ max-width:100%;
+}
+
+</style>
+
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player Demo</a> - Visualization Example, Basic Template</h1>
+
+ <p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI with visualization options. <b>Note: No EQ/spectrum support for IE (too slow.) Data not available in HTML5.</b></p>
+
+ <div style="clear:left"></div>
+
+ <div id="sm2-container">
+ <!-- sm2 flash goes here -->
+ </div>
+
+ <!-- here are the MP3 links, which are decorated with the 360 canvas element/UI etc. -->
+
+ <h2 style="margin-top:1em">Inline list</h2>
+
+ <div class="sm2-inline-list"> <!-- remove this class to have one item per line -->
+
+ <div class="ui360"><a href="../../demo/mpc/audio/CRASH_1.mp3">Crash 1</a></div>
+ <div class="ui360"><a href="../../demo/mpc/audio/CRASH_5.mp3">Crash 5</a></div>
+ <div class="ui360"><a href="../../demo/mpc/audio/CRASH_6.mp3">Crash 6</a></div>
+ <div class="ui360"><a href="../../demo/mpc/audio/CHINA_1.mp3">China 1</a></div>
+
+ </div>
+
+ <h2 style="clear:both;padding-top:1em">Block list</h2>
+
+ <div>
+ <div class="ui360"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: LOUD)</a></div>
+ <div class="ui360"><a href="../../demo/_mp3/1hz-10khz-sweep.mp3">1-10 Khz Sweep (Warning: LOUD)</a></div>
+ </div>
+
+ </div>
+
+ <p style="margin-left:1em">
+ <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
+ </p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization.html new file mode 100755 index 0000000..cb8071f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/canvas-visualization.html @@ -0,0 +1,328 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>360° MP3 player UI demo (SoundManager 2): Javascript + Canvas Visualization</title>
+<meta name="description" content="Javascript + Canvas + SoundManager 2: 360-degree circular control / jog wheel example for playing MP3 links, with EQ and spectrum visualization options" />
+<!-- demo, make the fonts nicer etc. -->
+<link rel="stylesheet" type="text/css" href="../index.css" />
+
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+
+<!-- required -->
+<link rel="stylesheet" type="text/css" href="360player.css" />
+<link rel="stylesheet" type="text/css" href="360player-visualization.css" />
+
+<!-- special IE-only canvas fix -->
+<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
+
+<!-- Apache-licensed animation library -->
+<script type="text/javascript" src="script/berniecode-animator.js"></script>
+
+<!-- the core stuff -->
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/360player.js"></script>
+
+<script type="text/javascript">
+
+soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
+
+soundManager.useFastPolling = true; // increased JS callback frequency, combined with useHighPerformance = true
+
+threeSixtyPlayer.config.scaleFont = (navigator.userAgent.match(/msie/i)?false:true);
+threeSixtyPlayer.config.showHMSTime = true;
+
+// enable some spectrum stuffs
+
+threeSixtyPlayer.config.useWaveformData = true;
+threeSixtyPlayer.config.useEQData = true;
+
+// enable this in SM2 as well, as needed
+
+if (threeSixtyPlayer.config.useWaveformData) {
+ soundManager.flash9Options.useWaveformData = true;
+}
+if (threeSixtyPlayer.config.useEQData) {
+ soundManager.flash9Options.useEQData = true;
+}
+if (threeSixtyPlayer.config.usePeakData) {
+ soundManager.flash9Options.usePeakData = true;
+}
+
+// favicon is expensive CPU-wise, but can be used.
+if (window.location.href.match(/hifi/i)) {
+ threeSixtyPlayer.config.useFavIcon = true;
+}
+
+</script>
+
+<!-- DEMO only, customization UI: Yahoo! YUI colorpicker stuff -->
+<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/slider/assets/skins/sam/slider.css" />
+<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/colorpicker/assets/skins/sam/colorpicker.css" />
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js"></script>
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js"></script>
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/slider/slider-min.js"></script>
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js"></script>
+<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/colorpicker/colorpicker-min.js"></script>
+
+<link rel="stylesheet" type="text/css" href="demo.css" />
+<style type="text/css">
+
+#left h2 {
+ padding-top:0px;
+ margin-bottom:0.25em;
+ color:#666;
+}
+
+pre.block {
+ margin-top:0.5em;
+}
+
+/* special case */
+
+#left {
+ width:auto;
+ max-width:100%;
+}
+
+</style>
+
+<!-- demo configuration stuff, you don't need this -->
+<link rel="stylesheet" type="text/css" href="demo-slider-controls.css" />
+<script type="text/javascript" src="demo-slider-controls.js"></script>
+
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 player project home">SoundManager 2</a> / <a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player Demo</a>: JS + Canvas Visualization</h1>
+
+ <p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI with visualization options. <b>Note: Spectrum/EQ visualizations disabled for IE (too slow.) Data is not currently available under HTML5.</b></p>
+ <p class="note" style="color:#666;margin-bottom:0.5em">You can also <a href="#debug=1" onclick="window.location.href = this.href;window.location.reload()" title="Enable debug mode, show frames per second">show FPS</a><span id="config-link"> or <a href="#customize" onclick="window.location.href=this.href;window.location.reload()">customize the UI</a></span><span id="hifi">, or see the <a href="#hifi=1" onclick="window.location.href=this.href;window.location.reload()">hi-fi version</a></span>. Check the <a href="canvas-visualization-basic.html">basic template</a> for a minimal code example; also see the <a href="../360-player/" title="360° player UI">default 360° UI</a>.</p>
+
+ <!-- customization crap -->
+
+ <div id="config-ui" style="clear:both;position:relative;max-width:1110px;margin-top:1em;display:none">
+
+ <div style="position:relative">
+
+ <form action="#" method="get">
+
+ <div id="controls">
+
+ <div class="checkbox">
+ <div>
+ <input id="use-waveform" type="checkbox" checked="checked" title="Enable waveform feature." onclick="controller.updateExample();controller.updateExampleCode()" value="Apply" /> Waveform
+ <input id="disabled-1" type="checkbox" title="Enable EQ (spectrum) feature." onclick="controller.updateExample();controller.updateExampleCode()" value="Apply" style="margin-left:1em" checked="checked" /> EQ
+ <input type="checkbox" name="use-amplifier" id="use-amplifier" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()" style="margin-left:1em"> Amplifier
+ </div>
+ </div>
+
+ <div style="clear:left"></div>
+
+ <dl class="col">
+
+ <dt>Circle Diameter</dt>
+ <dd class="title">Size</dd>
+ <dd>1-256</dd>
+ <dd class="control">
+ <div class="bar" title="Click to move here"></div>
+ <div class="slider" title="Size of circle"></div>
+ </dd>
+
+ <dt>Waveform Thickness</dt>
+ <dd class="title">thickness</dd>
+ <dd>1-100</dd>
+ <dd class="control">
+ <div class="bar" title="Click to move here"></div>
+ <div class="slider" title="Thickness of line"></div>
+ </dd>
+
+ <dt>Wave Downsample</dt>
+ <dd class="title">(Scale)</dd>
+ <dd>1-16</dd>
+ <dd class="control">
+ <div class="bar" title="Click to move here"></div>
+ <div class="slider" title="Primary (inner circle) colour"></div>
+ </dd>
+
+ <dt>EQ Thickness</dt>
+ <dd class="title">thickness</dd>
+ <dd>1-50</dd>
+ <dd class="control">
+ <div class="bar" title="Click to move here"></div>
+ <div class="slider" title="Thickness of line"></div>
+ </dd>
+
+ <dt>EQ Downsample</dt>
+ <dd class="title">(Scale)</dd>
+ <dd>1-16</dd>
+ <dd class="control">
+ <div class="bar" title="Click to move here"></div>
+ <div class="slider" title="Primary (inner circle) colour"></div>
+ </dd>
+
+ </dl>
+
+ <div id="options" class="col">
+
+ <div>
+ Waveform position:
+ <input type="radio" name="waveform-inside" id="waveform-inside" value="true" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()"> Inside | <input type="radio" name="waveform-inside" id="waveform-inside" value="false" onclick="controller.updateExample();controller.updateExampleCode()"> Outside
+ </div>
+
+ <div>
+ EQ position:
+ <input type="radio" name="eq-inside" id="eq-inside" value="true" onclick="controller.updateExample();controller.updateExampleCode()"> Inside | <input type="radio" name="eq-inside" id="eq-inside" value="false" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()"> Outside
+ </div>
+
+ <div>
+ Waveform color:
+ <input type="text" name="waveform-color" id="waveform-color" value="#000000" onclick="createCP(this,setWaveformColor)" />
+ </div>
+
+ <div>
+ EQ color:
+ <input type="text" name="eq-color" id="eq-color" value="#000000" onclick="createCP(this,setEQColor)" />
+ </div>
+
+ <div>
+ Loaded ring color:
+ <input type="text" name="loaded-ring-color" id="loaded-ring-color" value="#000000" onclick="createCP(this,setLoadedRingColor)" />
+ </div>
+
+ <div>
+ Progress ring color:
+ <input type="text" name="progress-ring-color" id="progress-ring-color" value="#000000" onclick="createCP(this,setProgressRingColor)" />
+ </div>
+
+ <div>
+ Background ring color:
+ <input type="text" name="bg-ring-color" id="bg-ring-color" value="#000000" onclick="createCP(this,setBackgroundRingColor)" />
+ </div>
+
+ <p class="compact">
+ <input type="button" onclick="controller.randomize()" value="Randomize controls" title="Assign random control values" style="font-size:x-small" />
+ </p>
+
+ </form>
+
+ </div>
+
+ <div id="cp-container">
+ <!-- color picker stuff goes here -->
+ </div>
+
+ <div id="config-code-block" style="float:right;display:inline;margin-left:1em;margin-top:-0.7em">
+ <!--
+ <pre id="config-link" class="block"><code style="cursor:pointer" onclick="document.getElementById('config-link').style.display='none';document.getElementById('config-pre-block').style.display='block';return false"> [click to show code] </code></pre>
+ -->
+ <pre id="config-pre-block" class="block"><code id="config-code">Code goes here</code></pre>
+ </div>
+
+ </div>
+
+ </div>
+
+ <p style="clear:left">Get a sound playing, then adjust the values to see real-time updates.</p>
+
+ </div>
+
+ <!-- here are the MP3 links, which are decorated with the 360 canvas element/UI etc. -->
+
+ <div id="sm2-container">
+ <!-- sm2 flash goes here -->
+ </div>
+
+ <h2 style="margin-top:1em">Inline list</h2>
+
+ <div class="sm2-inline-list"> <!-- remove this class to have one item per line -->
+
+ <div class="ui360"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20I%20Tried.mp3">SonReal - I Tried</a></div>
+ <div class="ui360"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20People%20Asking.mp3">SonReal - People Asking</a></div>
+ <div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20060826%20-%20Armstrong.mp3">20060826 - Armstrong Groove</a></div>
+ <div class="ui360"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
+
+ </div>
+
+ <p class="note" style="clear:both;padding-top:1em">"I Tried" and "People Asking" courtesy of <a href="http://sonreal.bandcamp.com/album/the-lightyear-mixtape" title="The Lightyear Mixtape from SonReal, Vancouver-based hip-hop artist">SonReal</a>, from the "Lightyear" Mixtape.</p>
+
+ <h2 style="clear:left;padding-top:1em">Block list</h2>
+
+ <div>
+ <div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20090207%20-%20Loverman.mp3">20090207 - Loverman</a></div>
+ <div class="ui360"><a href="../../demo/_mp3/1hz-10khz-sweep.mp3">1-10 Khz Sweep (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
+ </div>
+
+
+ <div style="clear:left"></div>
+
+ <h2 style="clear:left;padding-top:1em">Variant: Annotations/meta-data</h2>
+
+
+ <ul class="ui360playlist">
+
+ <li>
+
+ <div class="ui360">
+ <a href="http://freshly-ground.com/data/audio/binaural/A%20Virtual%20Haircut%20in%20San%20Francisco%20%283%20Scenes%29.mp3">A Virtual Haircut (3 scenes)</a>
+ <div class="metadata">
+ <div class="duration">4:43</div> <!-- total track time (for positioning while loading, until determined -->
+ <ul>
+ <li><p>Electric razor</p><span>0:00</span></li> <!-- first scene -->
+ <li><p>Water, scissors</p><span>2:41</span></li> <!-- start time of second scene -->
+ <li><p>More razor work</p><span>4:00</span></li>
+ </ul>
+ </div>
+ </div>
+
+ </li>
+
+ <li>
+
+ <div class="ui360">
+ <a href="http://freshly-ground.com/data/audio/binaural/Rubber%20Chicken%20Launch%20%28office%29.mp3">Rubber Chicken Launch (Office)</a>
+
+ <div class="metadata">
+ <div class="duration">0:47</div>
+ <ul>
+ <li><p>First attempt</p><span>0:00</span></li>
+ <li><p>Fire!</p><span>0:02</span></li>
+ <li><p>"Too much angle"</p><span>0:05</span></li>
+ <li><p>Random chicken noise</p><span>0:18</span></li>
+ <li><p>"Wait a second"</p><span>0:31</span></li>
+ <li><p>Derrr..</p><span>0:34</span></li>
+ <li><p>Launch attempt #2</p><span>0:36</span></li>
+ <li><p>"Wrong angle"</p><span>0:39</span></li>
+ <li><p>"Fail"</p><span>0:42</span></li>
+ </ul>
+ </div>
+
+
+ </div>
+
+ </li>
+
+ </ul>
+
+ <div style="clear:both"></div>
+
+ <p style="margin-left:1em">
+ <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
+ </p>
+
+ <script type="text/javascript">
+ if (window.location.toString().match(/#customize/i)) {
+ document.getElementById('config-link').style.display = 'none';
+ document.getElementById('config-ui').style.display = 'block';
+ }
+ </script>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.css new file mode 100755 index 0000000..27281c0 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.css @@ -0,0 +1,179 @@ +#cp-container { position:relative;float:left;display:inline; margin-left:1em;padding: 6px; background-color: #f6f6f6; border:1px solid #eee; width: 320px; height:180px;z-index:2; }
+
+.yui-picker-controls li,
+.yui-picker-controls input {
+ font-size:1em;
+ font-family:"helvetica neue",helvetica,arial,verdana;
+}
+
+#controls {
+ position:relative;
+ margin-top:1.5em;
+ font-size:0.85em;
+}
+
+#options {
+ float:left;
+ display:inline;
+ margin-bottom:0.5em;
+ margin-top:-1.2em;
+}
+
+#controls .checkbox {
+ float:left;
+ display:inline;
+ width:21.2em;
+ margin-right:2.5em;
+}
+
+#controls .checkbox div {
+ /* tab */
+ width:auto;
+ padding:0.4em;
+ border:1px solid #ddd;
+ border-bottom:none;
+ background:#eee;
+}
+
+#controls .checkbox div,
+#controls .checkbox input {
+ font-family:arial,tahoma,verdana,"sans serif";
+ font-size:1em;
+ vertical-align:middle;
+}
+
+#controls dl {
+ width:21em;
+}
+
+#controls dl.col {
+ position:relative;
+ float:left;
+ display:inline;
+ margin:0px;
+ margin-right:1em;
+ padding:0.75em;
+/*
+ height:12.4em;
+*/
+ height:auto;
+ border:1px solid #ddd;
+ background:#f6f6f6;
+}
+
+#controls .disabled {
+ color:#ccc;
+}
+
+#controls .disabled dt,
+#controls .disabled dd {
+ color:#999;
+ opacity:0.5;
+}
+
+#controls dl dd p {
+ margin:0px;
+ padding:0px;
+}
+
+#controls dt,
+#controls dd {
+ margin:0px;
+ padding:0px;
+}
+
+#controls dt {
+ border-bottom:none;
+}
+
+#controls dt {
+ float:left;
+ display:inline;
+ background:transparent;
+ padding-right:0.7em;
+ margin-right:0.7em;
+ border-right:1px solid #ccc;
+ font-size:1.1em;
+ color:#333;
+ font-family:"helvetica neue",helvetica,verdana,arial,"sans serif";
+}
+
+#controls dd {
+ margin:0px;
+ padding:0px;
+ font-size:0.9em;
+ vertical-align:middle;
+ color:#666;
+}
+
+#controls .title {
+ float:left;
+ display:inline;
+ margin-right:0.6em;
+ color:#333;
+}
+
+/* those slider bits you might be wondering about */
+
+#controls .control {
+ position:relative;
+ border-left:0px;
+ width:214px;
+ height:20px;
+}
+
+#controls .control .bar {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:214px;
+ height:20px;
+ background:transparent url(../_image/slider-bar.gif) no-repeat 0px 9px;
+ cursor:pointer;
+ cursor:hand;
+}
+
+#controls .control .slider {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:20px;
+ height:20px;
+ background:transparent url(../_image/slider.png) no-repeat 0px 0px;
+ *background:none;
+ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider.png');
+ cursor:pointer;
+ cursor:hand;
+}
+
+#controls .control .slider:hover {
+ background:transparent url(../_image/slider-1.png) no-repeat 0px 0px;
+ *background:none;
+}
+
+#controls .control .slider.hover {
+ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-1.png');
+}
+
+#controls .disabled .control .slider {
+ background:transparent url(../_image/slider-disabled.png) no-repeat 0px 0px;
+ *background:none;
+ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-disabled.png');
+}
+
+#controls .disabled .control .slider:hover {
+ background:transparent url(../_image/slider-disabled-1.png) no-repeat 0px 0px;
+ *background:none;
+}
+
+#controls .disabled .control .slider.hover {
+ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-disabled-1.png');
+}
+
+#controls input[type=text] {
+ width:5em;
+}
+
+#options div {
+ margin-bottom:0.25em;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.js new file mode 100755 index 0000000..16a02dc --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo-slider-controls.js @@ -0,0 +1,711 @@ +/*
+ Ancient fireworks slider control code (2005)
+ http://schillmania.com/projects/fireworks/
+ --------------------------------------------
+ Not required for your use!
+*/
+
+function Animator2() {
+ var self = this;
+ this.tweens = [];
+ this.tweens['default'] = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1];
+ this.tweens['blast'] = [12,12,11,10,10,9,8,7,6,5,4,3,2,1];
+ this.tweens['fade'] = [10,10,10,10,10,10,10,10,10,10];
+ this.queue = [];
+ this.queue.IDs = [];
+ this.active = false;
+ this.timer = null;
+
+ this.createTween = function(start,end,type) {
+ // return array of tween coordinate data (start->end)
+ type = type||'default';
+ var tween = [start];
+ var tmp = start;
+ var diff = end-start;
+ var x = self.tweens[type].length;
+ for (var i=0; i<x; i++) {
+ tmp += diff*self.tweens[type][i]*0.01;
+ tween[i] = new Object();
+ tween[i].data = tmp;
+ tween[i].event = null;
+ }
+ return tween;
+ }
+
+ this.enqueue = function(o,fMethod,fOnComplete) {
+ // add object and associated methods to animation queue
+ // writeDebug('animator.enqueue()');
+ if (!fMethod) {
+ // writeDebug('animator.enqueue(): missing fMethod');
+ }
+ if (typeof(self.queue.IDs[o.oID])=='undefined') {
+ // writeDebug('animator.enqueue(): added '+o.oID);
+ var i = self.queue.length;
+ self.queue.IDs[o.oID] = i;
+ self.queue[i] = o;
+ } else {
+ // writeDebug('animator.enqueue(): '+o.oID+' already queued');
+ var i = self.queue.IDs[o.oID]; // retrieve queue index
+ self.queue[i].active = true;
+ self.queue[i].frame = 0;
+ }
+ o.active = true; // flag for animation
+ self.queue[i]._method = fMethod;
+ self.queue[i]._oncomplete = fOnComplete?fOnComplete:null;
+ }
+
+ this.animate = function() {
+ var active = 0;
+ for (var i=self.queue.length; i--;) {
+ if (self.queue[i].active) {
+ self.queue[i]._method();
+ active++;
+ }
+ }
+ if (active==0 && self.timer) {
+ // all animations finished
+ self.stop();
+ } else {
+ // writeDebug(active+' active');
+ }
+ }
+
+ this.start = function() {
+ if (self.timer || self.active) {
+ // writeDebug('animator.start(): already active');
+ return false;
+ }
+ // writeDebug('animator.start()'); // report only if started
+ self.active = true;
+ self.timer = setInterval(self.animate,mc.intervalRate);
+ }
+
+ this.stop = function() {
+ // writeDebug('animator.stop()',true);
+ clearInterval(self.timer);
+ self.timer = null;
+ self.active = false;
+ self.queue = [];
+ self.queue.IDs = [];
+ }
+
+}
+
+function MainController() {
+ var self = this;
+ this.intervalRate = 20; // rate (ms) to run animation at, general best default = 20
+ this.DEBUG = true; // debug mode disabled by default
+ this.oFW = null;
+ this.isIE = (navigator.appVersion.indexOf('MSIE')+1);
+ this.isOpera = (navigator.userAgent.toLowerCase().indexOf('opera')+1);
+ if (this.isOpera) this.isIE = false; // no impersonation allowed here!
+ this.animator = null;
+ this.gOID = 0; // global object ID counter (for animation queue)
+ this.particleTypes = 6;
+ this.particleXY = 10;
+ this.tweenFade = [100,90,80,70,60,50,40,30,20,10,0];
+ this.isSafari = (navigator.appVersion.toLowerCase().indexOf('safari')+1?1:0);
+ this.canvasX = null;
+ this.canvasY = null;
+ this.screenY = null; // screen area (not entire page)
+ self.scrollY = null;
+
+ self.getWindowCoords = function() {
+ self.canvasX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth);
+ self.canvasY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
+ self.screenY = self.canvasY;
+ self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
+ self.canvasY += self.scrollY;
+ }
+
+ this.getWindowCoordsAlt = function() {
+ self.canvasX = window.innerWidth;
+ self.canvasY = window.innerHeight;
+ self.screenY = self.canvasY;
+ self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
+ self.canvasY += self.scrollY;
+ }
+
+ this.getPanX = function(x) {
+ x = parseInt(x);
+ var pos = x/self.canvasX;
+ if (pos<0.4) {
+ pos *= -1;
+ } else if (pos >= 0.4 && pos <= 0.6) {
+ pos = 0.5;
+ }
+ pos = parseInt(pos*100);
+ // writeDebug('getPanX('+x+'): '+pos+'%');
+ return pos;
+ }
+
+ this.isEmpty = function(o) {
+ // needs further hacking
+ return (typeof(o)=='undefined'||(o==null&&o!=0)||(o==''&&o!=0)||o=='null');
+ }
+
+ this.init = function() {
+// self.oFW = document.getElementById('fw');
+// self.oFP = document.getElementById('fp');
+// if (typeof(enableDebugMode)!='undefined' && (self.DEBUG||window.location.toString().toLowerCase().indexOf('debug')>=0)) enableDebugMode();
+ self.getWindowCoords();
+ self.animator = new Animator2();
+ }
+
+ this.destructor = function() {
+/*
+ for (var i=self.fireworks.length; i--;) {
+ self.fireworks[i] = null;
+ }
+ self.fireworks = null;
+ if (soundManager) {
+ soundManager.destructor();
+ soundManager = null;
+ }
+*/
+ }
+
+ if (this.isSafari || this.isOpera) this.getWindowCoords = this.getWindowCoordsAlt;
+
+}
+
+
+function Controller(o) {
+ var self = this;
+ this.o = o;
+ this.controls = [];
+ this.cb = [];
+ this.options = [];
+ this.functionExample = document.getElementById('function-example');
+ this.fbIE = null;
+
+ this.randomize = function() {
+ for (var i=1; i<self.controls.length; i++) {
+ setTimeout(self.controls[i].randomize,20+(20*i+1));
+ }
+ }
+
+ this.cbClick = function(nIndex) {
+ document.getElementById('controls').getElementsByTagName('dl')[nIndex].className = 'col'+(this.checked==false||this.checked==''?' disabled':'');
+ self.updateExample();
+ self.updateExampleCode();
+ }
+
+ this.updateExample = function() {
+ if (threeSixtyPlayer) {
+ var val = self.controls[0].value;
+ threeSixtyPlayer.config.circleDiameter = self.controls[0].value;
+ threeSixtyPlayer.config.circleRadius = self.controls[0].value/2;
+ // update some stuff
+
+ // set the cover width/height to match the canvas
+ if (threeSixtyPlayer.lastSound) {
+ // always set cover to max area?
+ // threeSixtyPlayer.lastSound._data.oCover.style.width = 250+'px';
+ // threeSixtyPlayer.lastSound._data.oCover.style.height = 250+'px';
+ // threeSixtyPlayer.lastSound._data.oCover.style.width = threeSixtyPlayer.config.circleDiameter+'px';
+ // threeSixtyPlayer.lastSound._data.oCover.style.height = threeSixtyPlayer.config.circleDiameter+'px';
+ threeSixtyPlayer.refreshCoords(threeSixtyPlayer.lastSound);
+ }
+
+ threeSixtyPlayer.config.waveformDataLineRatio = (self.controls[1].value/100)*2;
+
+ threeSixtyPlayer.config.waveformDataDownsample = (self.controls[2].value);
+
+ threeSixtyPlayer.config.eqDataLineRatio = parseInt((self.controls[3].value/100)*3*1000)/1000;
+
+ threeSixtyPlayer.config.eqDataDownsample = (self.controls[4].value);
+
+ threeSixtyPlayer.config.useEQData = (document.getElementById('disabled-1').checked?true:false);
+
+ // radio buttons
+
+ threeSixtyPlayer.config.useWaveformData=(document.getElementById('use-waveform').checked?true:false);
+
+ threeSixtyPlayer.config.waveformDataOutside = document.getElementById('waveform-inside').checked?false:true;
+
+ threeSixtyPlayer.config.eqDataOutside = document.getElementById('eq-inside').checked?false:true;
+
+ threeSixtyPlayer.config.useAmplifier = (document.getElementById('use-amplifier').checked?true:false);
+
+ // threeSixtyPlayer.refreshCoords();
+ }
+ }
+
+ this.updateExampleCode = function() {
+ // set innerHTML
+document.getElementById('config-code').innerHTML = "\
+// 360player.js, config section\n\
+this.config = {\n\
+ playNext: <span>false</span>,\n\
+ autoPlay: <span>false</span>,\n\
+ loadRingColor: <span>'"+threeSixtyPlayer.config.loadRingColor+"'</span>,\n\
+ playRingColor: <span>'"+threeSixtyPlayer.config.playRingColor+"'</span>,\n\
+ backgroundRingColor: <span>'"+threeSixtyPlayer.config.backgroundRingColor+"'</span>,\n\
+ circleDiameter: <span>"+threeSixtyPlayer.config.circleDiameter+"</span>,\n\
+ circleRadius: <span>"+threeSixtyPlayer.config.circleRadius+"</span>,\n\
+ imageRoot: <span>'"+threeSixtyPlayer.config.imageRoot+"'</span>,\n\
+ animDuration: <span>"+threeSixtyPlayer.config.animDuration+"</span>,\n\
+ animTransition: <span>Animator.tx.bouncy</span>,\n\
+ showHMSTime: <span>"+threeSixtyPlayer.config.showHMSTime+"</span>,\n\
+\n\
+ useWaveformData: <span>"+threeSixtyPlayer.config.useWaveformData+"</span>,\n\
+ waveformDataColor: <span>'"+threeSixtyPlayer.config.waveformDataColor+"'</span>,\n\
+ waveformDataDownsample: <span>"+threeSixtyPlayer.config.waveformDataDownsample+"</span>,\n\
+ waveformDataOutside: <span>"+threeSixtyPlayer.config.waveformDataOutside+"</span>,\n\
+ waveformDataConstrain: <span>false</span>,\n\
+ waveformDataLineRatio: <span>"+threeSixtyPlayer.config.waveformDataLineRatio+"</span>,\n\
+\n\
+ useEQData: <span>"+threeSixtyPlayer.config.useEQData+"</span>,\n\
+ eqDataColor: <span>'"+threeSixtyPlayer.config.eqDataColor+"'</span>,\n\
+ eqDataDownsample: <span>"+threeSixtyPlayer.config.eqDataDownsample+"</span>,\n\
+ eqDataOutside: <span>"+threeSixtyPlayer.config.eqDataOutside+"</span>,\n\
+ eqDataLineRatio: <span>"+threeSixtyPlayer.config.eqDataLineRatio+"</span>,\n\
+\n\
+ usePeakData: <span>"+threeSixtyPlayer.config.usePeakData+"</span>,\n\
+ peakDataColor: <span>'"+threeSixtyPlayer.config.peakDataColor+"'</span>,\n\
+ peakDataOutside: <span>"+threeSixtyPlayer.config.peakDataOutside+"</span>,\n\
+ peakDataLineRatio: <span>"+threeSixtyPlayer.config.peakDataLineRatio+"</span>,\n\
+\n\
+ useAmplifier: <span>"+threeSixtyPlayer.config.useAmplifier+"</span>\n\
+\n\
+}";
+document.getElementById('config-code').style.display = 'block'; // weird Fx fix
+ }
+
+ this.createCustomFirework = function() {
+ }
+
+ this.destructor = function() {
+ for (var i=self.controls.length; i--;) {
+ self.controls[i].destructor();
+ }
+ for (i=self.cb.length; i--;) {
+ self.cb.onclick = null;
+ self.cb[i] = null;
+ }
+ for (i=self.options.length; i--;) {
+ self.options[i] = null;
+ }
+ if (navigator.userAgent.match(/msie/i)) {
+ self.fbIE.onmouseover = null;
+ self.fbIE.onmouseout = null;
+ self.fbIE = null;
+ }
+ self.cb = null;
+ self.options = null;
+ self.controls = null;
+ self.functionExample = null;
+ self.o = null;
+ }
+
+ var items = parseInt(this.o.length/3);
+ for (var i=0; i<items; i++) {
+ this.controls[this.controls.length] = new Slider(this.o[(3*i)+2].getElementsByTagName('div')[1],this.o[(3*i)+1],this.o[(3*i)+2].getElementsByTagName('div')[0]);
+ }
+ this.cb = [document.getElementById('disabled-0'),document.getElementById('disabled-1')];
+/*
+ for (i=this.cb.length; i--;) {
+ this.cb[i]._index = i;
+ this.cb[i].onclick = this.cbClick;
+ }
+*/
+ this.options = [];
+/*
+ this.cb[1].checked = false;
+ this.options = [document.getElementById('opt-random0'),document.getElementById('opt-random1')];
+ this.options[0].checked = false;
+ this.options[1].checked = true;
+ if (navigator.userAgent.match(/msie/i)) {
+ this.fbIE = document.getElementById('fireButton');
+ this.fbIE.onmouseover = function() {this.className='hover';}
+ this.fbIE.onmouseout = function() {this.className='';}
+ }
+*/
+
+ setTimeout(function(){
+ var values = [
+ 256,
+ 65,
+ 40,
+ 72,
+ 48
+ ];
+ for (var i=0; i<values.length; i++) {
+ self.controls[i].setValue(values[i]); // defaults
+ }
+ },1);
+}
+
+function Slider(o,oV,oB) {
+ var self = this;
+ this.o = o;
+ this.oV = oV;
+ this.oB = oB;
+ this.scale = parseInt(oV.innerHTML.toString().substr(2));
+ this.oID = 'sc'+(gOID++);
+ this.offX = 0;
+ this.x = 0;
+ this.xMin = 0-10;
+ this.xMax = self.o.parentNode.offsetWidth-10;
+ this.value = 0;
+ this.timer = null;
+ this._className = this.o.className;
+ this.tween = [];
+ this.frame = 0;
+
+ this.over = function() {
+ this.className = self._className+' hover';
+ event.cancelBubble=true;
+ return false;
+ }
+
+ this.out = function() {
+ this.className = self._className;
+ event.cancelBubble=true;
+ return false;
+ }
+
+ this.down = function(e) {
+ var e = e?e:event;
+ self.offX = e.clientX-self.o.offsetLeft;
+ addEvent(document,'mousemove',self.move);
+ addEvent(document,'mouseup',self.up);
+ return false;
+ }
+
+ this.barClick = function(e) {
+ var e=e?e:event;
+ self.slide(self.x,e.clientX-self.o.parentNode.parentNode.offsetLeft-self.o.offsetWidth);
+ }
+
+ this.move = function(e) {
+ var e=e?e:event;
+ var x = e.clientX-self.offX;
+ if (x>self.xMax) {
+ x = self.xMax;
+ } else if (x<self.xMin) {
+ x = self.xMin;
+ }
+ if (x != self.x) {
+ self.moveTo(x);
+ self.doUpdate();
+ controller.updateExample();
+ controller.updateExampleCode();
+ }
+ e.stopPropgation?e.stopPropagation():e.cancelBubble=true;
+ return false;
+ }
+
+ this.up = function(e) {
+ removeEvent(document,'mousemove',self.move);
+ removeEvent(document,'mouseup',self.up);
+ // controller.updateExample();
+ controller.updateExampleCode();
+ }
+
+ this.slide = function(x0,x1) {
+ self.tween = mc.animator.createTween(x0,x1);
+ mc.animator.enqueue(self,self.animate,function(){
+ controller.updateExample()
+ controller.updateExampleCode();
+ });
+ mc.animator.start();
+ }
+
+ this.moveTo = function(x) {
+ self.x = x;
+ self.o.style.marginLeft = x+'px';
+ }
+
+ this.animate = function() {
+ self.moveTo(self.tween[self.frame].data);
+ self.doUpdate(50);
+ controller.updateExample();
+ if (self.frame++>=self.tween.length-1) {
+ self.active = false;
+ self.frame = 0;
+ if (self._oncomplete) self._oncomplete();
+// self.doUpdate();
+ return false;
+ }
+ self.doUpdate();
+ return true;
+ }
+
+ this.doUpdate = function(t) {
+ // if (!self.timer) self.timer = setTimeout(self.update,t||20);
+ self.update();
+ }
+
+ this.update = function() {
+ self.timer = null;
+ self.value = 1+parseInt(self.x/self.xMax*(self.scale-1));
+ if (self.value<1) self.value = 1;
+ // if (self.oV.innerHTML != self.value) self.oV.innerHTML = self.value;
+ // self.oV.innerHTML = self.value;
+ }
+
+ this.setValue = function(x) {
+ self.slide(self.x,Math.min(self.xMax,x));
+ }
+
+ this.randomize = function() {
+ self.slide(self.x,parseInt(Math.random()*self.xMax));
+ }
+
+ this.destructor = function() {
+ self.o.onmouseover = null;
+ self.o.onmouseout = null;
+ self.o.onmousedown = null;
+ self.o = null;
+ self.oV = null;
+ self.oB.onclick = null;
+ self.oB = null;
+ }
+
+ if (soundManager.isIE) {
+ // IE is lame, no :hover
+ this.o.onmouseover = this.over;
+ this.o.onmouseout = this.out;
+ }
+
+ this.o.onmousedown = this.down;
+ this.oB.onclick = this.barClick;
+ self.update();
+
+}
+
+var gOID = 0;
+
+function demoInit() {
+ controller = new Controller(document.getElementById('controls').getElementsByTagName('dd'));
+}
+
+function demoDestuctor() {
+ controller.destructor();
+ controller = null;
+}
+
+var controller = null;
+
+var mc = new MainController();
+// create null objects if APIs not present
+
+function createCP(oInput,oHandler) {
+ var Event = YAHOO.util.Event;
+
+ cpHandler = oHandler;
+ if (picker != null) {
+ // picker.showcontrols(true);
+ var c = oInput.value.substr(1);
+ picker.setValue(hex2decArray([c.substr(0,2),c.substr(2,2),c.substr(4,2)]),true); // be silent
+ return false;
+ }
+
+ Event.onDOMReady(function() {
+ picker = new YAHOO.widget.ColorPicker("cp-container", {
+ showhsvcontrols: true,
+ showhexcontrols: true,
+ images: {
+ PICKER_THUMB: "../_image/picker_thumb.png",
+ HUE_THUMB: "../_image/hue_thumb.png"
+ }
+ });
+
+// picker.showcontrols(false);
+ //a listener for logging RGB color changes;
+ //this will only be visible if logger is enabled:
+ var onRgbChange = function(o) {
+ /*o is an object
+ { newValue: (array of R, G, B values),
+ prevValue: (array of R, G, B values),
+ type: "rgbChange"
+ }
+ */
+ cpHandler(o.newValue);
+ controller.updateExampleCode();
+ }
+
+ //subscribe to the rgbChange event;
+ picker.on("rgbChange", onRgbChange);
+
+ //use setValue to reset the value to white:
+ Event.on("reset", "click", function(e) {
+ picker.setValue([255, 255, 255], false); //false here means that rgbChange
+ //wil fire; true would silence it
+ });
+
+ //use the "get" method to get the current value
+ //of one of the Color Picker's properties; in
+ //this case, we'll get the hex value and write it
+ //to the log:
+ Event.on("gethex", "click", function(e) {
+ console.log("Current hex value: " + picker.get("hex"));
+ });
+
+ });
+}
+
+var picker = null;
+
+cpHandler = function() {
+}
+
+
+ // hex -> dec / dec -> hex
+ // http://www.southwest.com.au/~jfuller/binary/converter.htm
+
+ function dec2hex(cval) {
+ if (cval > 255) cval = 255;
+ var hexascii = "0123456789ABCDEF";
+ var cval0 = Math.floor(cval/16);
+ var cval1 = cval-(cval0*16);
+ var c1 = hexascii.charAt(cval0);
+ var c2 = hexascii.charAt(cval1);
+ return (c1+c2);
+ }
+
+ function hex2dec(cval) {
+ cval = cval.toUpperCase();
+ var tval = 0;
+ var hexascii = "0123456789ABCDEF";
+ var mychar, ch;
+ for (var c=0; c<cval.length; c++) {
+ mychar = cval.charAt(c);
+ for (ch=0; ch<16; ch++) {
+ if (mychar == hexascii.charAt(ch)) {
+ tval += ch;
+ if (c<cval.length-1) tval *= 16;
+ }
+ }
+ }
+ return tval;
+ }
+
+ function hex2decArray(hArray) {
+ var result = [];
+ for (var i=0,j=hArray.length; i<j; i++) {
+ result[i] = hex2dec(hArray[i]);
+ }
+ return result;
+ }
+
+ function dec2hexArray(dArray) {
+ var result = [];
+ for (var i=0,j=dArray.length; i<j; i++) {
+ result[i] = dec2hex(dArray[i]);
+ }
+ return result;
+ }
+
+
+/*
+
+
+threeSixtyPlayer.config.waveformDataColor = '#'+dec2hexArray([self.controls[5].value,self.controls[6].value,self.controls[7].value]).join('');
+
+threeSixtyPlayer.config.eqDataColor = '#'+dec2hexArray([self.controls[8].value,self.controls[9].value,self.controls[10].value]).join('');
+
+threeSixtyPlayer.config.loadRingColor = '#'+dec2hexArray([self.controls[11].value,self.controls[12].value,self.controls[13].value]).join('');
+
+threeSixtyPlayer.config.playRingColor = '#'+dec2hexArray([self.controls[14].value,self.controls[15].value,self.controls[16].value]).join('');
+
+threeSixtyPlayer.config.waveformDataLineRatio = (self.controls[1].value/100)*2;
+
+threeSixtyPlayer.config.waveformDataDownsample = (self.controls[2].value);
+
+threeSixtyPlayer.config.eqDataLineRatio = (self.controls[3].value/100)*3;
+
+threeSixtyPlayer.config.eqDataDownsample = (self.controls[4].value);
+
+*/
+
+function _id(sID) {
+ return document.getElementById(sID);
+}
+
+function setWaveformColor(sColor) {
+ var value = '#'+(dec2hexArray(sColor).join(''));
+ threeSixtyPlayer.config.waveformDataColor = value;
+ _id('waveform-color').value = value;
+}
+
+function setEQColor(sColor) {
+ var value = '#'+dec2hexArray(sColor).join('');
+ _id('eq-color').value = value;
+ threeSixtyPlayer.config.eqDataColor = value;
+}
+
+function setLoadedRingColor(sColor) {
+ var value = '#'+dec2hexArray(sColor).join('');
+ _id('loaded-ring-color').value = value;
+ threeSixtyPlayer.config.loadRingColor = value;
+}
+
+function setProgressRingColor(sColor) {
+ var value = '#'+dec2hexArray(sColor).join('');
+ _id('progress-ring-color').value = value;
+ threeSixtyPlayer.config.playRingColor = value;
+}
+
+function setBackgroundRingColor(sColor) {
+ var value = '#'+dec2hexArray(sColor).join('');
+ _id('bg-ring-color').value = value;
+ threeSixtyPlayer.config.backgroundRingColor = value;
+}
+
+function addEvent(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+}
+
+function removeEvent(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+}
+
+if (window.location.toString().match(/#customize/i)) {
+ addEvent(window,'resize',mc.getWindowCoords);
+ addEvent(window,'scroll',mc.getWindowCoords);
+ addEvent(window,'load',mc.init);
+ addEvent(window,'load',demoInit);
+}
+
+if (window.location.toString().match(/hifi/i)) {
+ soundManager.onready(function(){
+ document.getElementById('hifi').style.display = 'none';
+ threeSixtyPlayer.config = {
+ playNext: false,
+ autoPlay: false,
+ loadRingColor: '#ccc',
+ playRingColor: '#000',
+ backgroundRingColor: '#eee',
+ circleDiameter: 256,
+ circleRadius: 128,
+ imageRoot: '',
+ animDuration: 500,
+ animTransition: Animator.tx.bouncy,
+ showHMSTime: true,
+
+ useWaveformData: true,
+ waveformDataColor: '#0099ff',
+ waveformDataDownsample: 1,
+ waveformDataOutside: true,
+ waveformDataConstrain: false,
+ waveformDataLineRatio: 0.56,
+
+ useEQData: true,
+ eqDataColor: '#339933',
+ eqDataDownsample: 1,
+ eqDataOutside: true,
+ eqDataLineRatio: 0.72,
+
+ usePeakData: true,
+ peakDataColor: '#ff33ff',
+ peakDataOutside: true,
+ peakDataLineRatio: 0.5,
+
+ useAmplifier: true
+
+ }
+ });
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo.css new file mode 100755 index 0000000..c513764 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/demo.css @@ -0,0 +1,75 @@ +/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:3em arial,tahoma,verdana;
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+h1 {
+ margin-top:0.25em;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h2 {
+ font-size:2em;
+ margin-top:0px;
+ margin-bottom:0.1em;
+}
+
+h3 {
+ font-size:1.5em;
+ margin-bottom:1em;
+}
+
+h1 a,
+h1 a:hover {
+ color:#000;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+ul.notes {
+ margin-left:0px;
+ padding-left:1.5em;
+}
+
+.note {
+ margin-top:0px;
+ font-style:italic;
+ color:#999;
+ margin-bottom:0px;
+}
+
+pre {
+ font-size:1.2em;
+ _font-size:1em;
+}
+
+#left {
+ max-width:56em;
+ margin-left:1em;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/empty.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/empty.gif Binary files differnew file mode 100755 index 0000000..35d42e8 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/empty.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_dots.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_dots.gif Binary files differnew file mode 100755 index 0000000..078b55f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_dots.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner.gif Binary files differnew file mode 100755 index 0000000..9cf90cf --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner_bigger.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner_bigger.gif Binary files differnew file mode 100755 index 0000000..1c72ebb --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/icon_loading_spinner_bigger.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/index.html new file mode 100755 index 0000000..b3ec4b1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/index.html @@ -0,0 +1,166 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>360° MP3 player UI demo (SoundManager 2)</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Javascript-driven sound, canvas-based MP3 player UI demo: 360-degree circular control / jog wheel example for playing MP3 links using SoundManager 2, Javascript and Canvas.">
+
+<!-- required -->
+<link rel="stylesheet" type="text/css" href="360player.css" />
+
+<!-- special IE-only canvas fix -->
+<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
+
+<!-- Apache-licensed animation library -->
+<script type="text/javascript" src="script/berniecode-animator.js"></script>
+
+<!-- the core stuff -->
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/360player.js"></script>
+
+<script type="text/javascript">
+soundManager.url = '../../swf/';
+</script>
+
+<!-- stuff you don't need -->
+<!-- makes the fonts nicer etc. -->
+<link rel="stylesheet" type="text/css" href="../index.css" />
+<link rel="stylesheet" type="text/css" href="demo.css" />
+
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+
+<style type="text/css">
+
+/* Demo page, general layout */
+
+#left {
+ position:relative;
+ width:950px;
+ max-width:100%;
+}
+
+#left h2 {
+ padding-top:0px;
+ margin-bottom:0.25em;
+ color:#666;
+}
+
+pre.block {
+ margin-top:0.5em;
+}
+
+</style>
+
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 player project home">SoundManager 2</a> / <a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player</a>: JS + Canvas UI</h1>
+
+ <p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI. Load progress, seek, play/pause etc. Also see <a href="canvas-visualization.html" title="Javascript canvas visualization with waveform/eq data">360° UI visualization</a> demo.</p>
+
+<div id="sm2-container">
+ <!-- flash movie is added here -->
+</div>
+
+<div style="margin-top:1.25em">
+
+ <div style="float:left;display:inline"> <!-- float is just for this demo layout, you don't need it. -->
+
+ <div class="ui360" style="margin-top:-0.55em"><a href="../jsAMP-preview/audio/rain.mp3">Rain</a></div>
+
+ <div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20090119%20-%20Untitled%20Groove.mp3">20090119 - Untitled Groove</a></div>
+
+ </div>
+
+
+ <div style="float:left;display:inline;margin-left:40px;border-left:1px solid #ccc;padding-left:30px;width:140px">
+
+ <p style="margin-top:1em;margin-bottom:0px">Alternate style: inline</p>
+
+ <div class="sm2-inline-list" style="margin-bottom:10px"> <!-- note the CSS class, changes the layout -->
+
+ <div class="ui360"><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></div>
+ <div class="ui360"><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></div>
+ <div class="ui360"><a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></div>
+
+ </div>
+
+ </div>
+
+</div>
+
+<div style="clear:both"></div>
+
+
+ <h3>How This Works</h3>
+
+ <p>The script looks for a container element matching <code>div.<span>ui360</span></code>, and then the first link inside of it.</p>
+
+ <div>
+
+<pre class="block"><code><div class="<span>ui360</span>">
+ <a href="/path/to/an.mp3">
+</div></code></pre>
+
+ </div>
+
+ <p>When the link is clicked, the script adds a <code>UI</code> template to the block, prepending it in front of the MP3 link:</p>
+
+<pre class="block"><code><div class="<span>ui360</span>">
+ <span><span><-- dynamically-inserted block --></span></span>
+ <div class="<span>ui</span>">
+ <canvas class="<span>sm2-canvas</span>"></canvas>
+ <img class="<span>sm2-360btn</span>" />
+ <div class="<span>sm2-timing</span>"></div>
+ <div class="<span>sm2-cover</span>"></div>
+ </div>
+ <span><span><-- /UI --></span></span>
+ <a href="<span>/path/to/an.mp3</span>">
+</div></code></pre>
+
+<h3>Customizing the UI</h3>
+
+<p>The player's default 50x50-pixel canvas is defined both within JavaScript and CSS. For an example with different values, see this <a href="canvas-visualization.html" title="360° UI: larger version">larger version</a>.</p>
+
+<pre class="block"><code>threeSixtyPlayer.config = {
+ playNext: <span>false</span>, <span><span>// stop after one sound, or play through list until end</span></span>
+ autoPlay: <span>false</span>, <span><span>// start playing the first sound right away</span></span>
+ loadRingColor: <span>'#ccc',</span> <span><span>// amount of sound which has loaded</span></span>
+ playRingColor: <span>'#000'</span>, <span><span>// amount of sound which has played</span></span>
+ backgroundRingColor: <span>'#eee', </span><span><span>// "default" color shown underneath everything else</span></span>
+ imageRoot: <span>''</span>,</span> <span><span>// path to prepend for empty.gif used for play/pause button
+ animDuration: <span>500</span>,
+ animTransition: <span>Animator.tx.bouncy</span> <span><span>// http://www.berniecode.com/writing/animator.html</span></span>
+}</code></pre>
+
+<p>The CSS for the canvas UI block is a bit ugly, but JavaScript reads the width of the <code>.sm2-360ui</code> element in the DOM as set by CSS and uses that to later draw and update the canvas element while playing.</p>
+
+<pre class="block"><code>.ui360,
+.sm2-360ui {
+ <span><span>/* size of the container for the circle, etc. */</span></span>
+ width:<span>50px</span>;</span>
+ height:<span>50px</span>;</span>
+}
+</code></pre>
+
+<h3>Third-party Components</h3>
+
+<p>This demo includes use of <a href="http://www.berniecode.com/writing/animator.html">Bernie's Better Animation Class</a> (Apache licensed) for some animation effects.</p>
+<p>Also, some loader/spinner icons from <a href="http://ajaxload.info">ajaxload.info</a> are used for showing loading/buffering states.</p>
+
+<hr />
+
+ <p>
+ <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
+ </p>
+
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/360player.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/360player.js new file mode 100755 index 0000000..419559c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/360player.js @@ -0,0 +1,1270 @@ +/*
+
+ SoundManager 2 Demo: 360-degree / "donut player"
+ ------------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ An inline player with a circular UI.
+ Based on the original SM2 inline player.
+ Inspired by Apple's preview feature in the
+ iTunes music store (iPhone), among others.
+
+ Requires SoundManager 2 Javascript API.
+ Also uses Bernie's Better Animation Class (BSD):
+ http://www.berniecode.com/writing/animator.html
+
+*/
+
+function ThreeSixtyPlayer() {
+ var self = this;
+ var pl = this;
+ var sm = soundManager; // soundManager instance
+ var uA = navigator.userAgent;
+ var isIE = (uA.match(/msie/i));
+ var isOpera = (uA.match(/opera/i));
+ var isSafari = (uA.match(/safari/i));
+ var isChrome = (uA.match(/chrome/i));
+ var isFirefox = (uA.match(/firefox/i));
+ var isTouchDevice = (uA.match(/ipad|iphone/i));
+ this.excludeClass = 'threesixty-exclude'; // CSS class for ignoring MP3 links
+
+ this.links = [];
+ this.sounds = [];
+ this.soundsByURL = [];
+ this.indexByURL = [];
+ this.lastSound = null;
+ this.soundCount = 0;
+ this.oUITemplate = null;
+ this.oUIImageMap = null;
+ this.vuMeter = null;
+
+ this.config = {
+
+ playNext: false, // stop after one sound, or play through list until end
+ autoPlay: false, // start playing the first sound right away
+ loadRingColor: '#ccc', // how much has loaded
+ playRingColor: '#000', // how much has played
+ backgroundRingColor: '#eee', // color shown underneath load + play ("not yet loaded" color)
+
+ // optional segment/annotation (metadata) stuff..
+ segmentRingColor: 'rgba(255,255,255,0.33)', // metadata/annotation (segment) colors
+ segmentRingColorAlt: 'rgba(0,0,0,0.1)',
+ loadRingColorMetadata: '#ddd', // "annotations" load color
+ playRingColorMetadata: 'rgba(96,160,224,0.99)', // how much has played when metadata is present
+ playRingColorMetadata: 'rgba(128,192,256,0.9)', // how much has played when metadata is present
+
+ circleDiameter: null, // set dynamically according to values from CSS
+ circleRadius: null,
+ imageRoot: '', // image path to prepend for transparent .GIF - eg. /images/
+ animDuration: 500,
+ animTransition: Animator.tx.bouncy, // http://www.berniecode.com/writing/animator.html
+ showHMSTime: false, // hours:minutes:seconds vs. seconds-only
+ scaleFont: false, // also set the font size (if possible) while animating the circle
+
+ // optional: spectrum or EQ graph in canvas (not supported in IE, too slow via ExCanvas)
+ useWaveformData: false,
+ waveformDataColor: '#0099ff',
+ waveformDataDownsample: 3, // use only one in X (of a set of 256 values) - 1 means all 256
+ waveformDataOutside: false,
+ waveformDataConstrain: false, // if true, +ve values only - keep within inside circle
+ waveformDataLineRatio: 0.64,
+
+ // "spectrum frequency" option
+ useEQData: false,
+ eqDataColor: '#339933',
+ eqDataDownsample: 4, // use only one in X (of 256 values)
+ eqDataOutside: true,
+ eqDataLineRatio: 0.54,
+
+ // enable "amplifier" (canvas pulses like a speaker) effect
+ usePeakData: true,
+ peakDataColor: '#ff33ff',
+ peakDataOutside: true,
+ peakDataLineRatio: 0.5,
+
+ useAmplifier: true, // "pulse" like a speaker
+
+ fontSizeMax: null, // set according to CSS
+
+ useFavIcon: false // Experimental (also requires usePeakData: true).. Try to draw a "VU Meter" in the favicon area, if browser supports it (Firefox + Opera as of 2009)
+
+ }
+
+ this.css = {
+ // CSS class names appended to link during various states
+ sDefault: 'sm2_link', // default state
+ sBuffering: 'sm2_buffering',
+ sPlaying: 'sm2_playing',
+ sPaused: 'sm2_paused'
+ }
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.hasClass = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?o.className.match(new RegExp('(\\s|^)'+cStr+'(\\s|$)')):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr || self.hasClass(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr || !self.hasClass(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getElementsByClassName = function(className,tagNames,oParent) {
+ var doc = (oParent||document);
+ var matches = [];
+ var i,j;
+ var nodes = [];
+ if (typeof tagNames != 'undefined' && typeof tagNames != 'string') {
+ for (i=tagNames.length; i--;) {
+ if (!nodes || !nodes[tagNames[i]]) {
+ nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
+ }
+ }
+ } else if (tagNames) {
+ nodes = doc.getElementsByTagName(tagNames);
+ } else {
+ nodes = doc.all||doc.getElementsByTagName('*');
+ }
+ if (typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ for (j=nodes[tagNames[i]].length; j--;) {
+ if (self.hasClass(nodes[tagNames[i]][j],className)) {
+ matches.push(nodes[tagNames[i]][j]);
+ }
+ }
+ }
+ } else {
+ for (i=0; i<nodes.length; i++) {
+ if (self.hasClass(nodes[i],className)) {
+ matches.push(nodes[i]);
+ }
+ }
+ }
+ return matches;
+ }
+
+ this.getParentByNodeName = function(oChild,sParentNodeName) {
+ if (!oChild || !sParentNodeName) return false;
+ sParentNodeName = sParentNodeName.toLowerCase();
+ while (oChild.parentNode && sParentNodeName != oChild.parentNode.nodeName.toLowerCase()) {
+ oChild = oChild.parentNode;
+ }
+ return (oChild.parentNode && sParentNodeName == oChild.parentNode.nodeName.toLowerCase()?oChild.parentNode:null);
+ }
+
+ this.getParentByClassName = function(oChild,sParentClassName) {
+ if (!oChild || !sParentClassName) return false;
+ while (oChild.parentNode && !self.hasClass(oChild.parentNode,sParentClassName)) {
+ oChild = oChild.parentNode;
+ }
+ return (oChild.parentNode && self.hasClass(oChild.parentNode,sParentClassName)?oChild.parentNode:null);
+ }
+
+ this.getSoundByURL = function(sURL) {
+ return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null);
+ }
+
+ this.isChildOfNode = function(o,sNodeName) {
+ if (!o || !o.parentNode) {
+ return false;
+ }
+ sNodeName = sNodeName.toLowerCase();
+ do {
+ o = o.parentNode;
+ } while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName);
+ return (o && o.nodeName.toLowerCase() == sNodeName?o:null);
+ }
+
+ this.isChildOfClass = function(oChild,oClass) {
+ if (!oChild || !oClass) return false;
+ while (oChild.parentNode && !self.hasClass(oChild,oClass)) {
+ oChild = self.findParent(oChild);
+ }
+ return (self.hasClass(oChild,oClass));
+ }
+
+ this.findParent = function(o) {
+ if (!o || !o.parentNode) return false;
+ o = o.parentNode;
+ if (o.nodeType == 2) {
+ while (o && o.parentNode && o.parentNode.nodeType == 2) {
+ o = o.parentNode;
+ }
+ }
+ return o;
+ }
+
+ this.getStyle = function(o,sProp) {
+ // http://www.quirksmode.org/dom/getstyles.html
+ try {
+ if (o.currentStyle) {
+ return o.currentStyle[sProp];
+ } else if (window.getComputedStyle) {
+ return document.defaultView.getComputedStyle(o,null).getPropertyValue(sProp);
+ }
+ } catch(e) {
+ // oh well
+ }
+ return null;
+ }
+
+ this.findXY = function(obj) {
+ var curleft = 0;
+ var curtop = 0;
+ do {
+ curleft += obj.offsetLeft;
+ curtop += obj.offsetTop;
+ } while (obj = obj.offsetParent);
+ return [curleft,curtop];
+ }
+
+ this.getMouseXY = function(e) {
+ // http://www.quirksmode.org/js/events_properties.html
+ e = e?e:event;
+ if (isTouchDevice && e.touches) {
+ e = e.touches[0];
+ }
+ if (e.pageX || e.pageY) {
+ return [e.pageX,e.pageY];
+ } else if (e.clientX || e.clientY) {
+ return [e.clientX+self.getScrollLeft(),e.clientY+self.getScrollTop()];
+ }
+ }
+
+ this.getScrollLeft = function() {
+ return (document.body.scrollLeft+document.documentElement.scrollLeft);
+ }
+
+ this.getScrollTop = function() {
+ return (document.body.scrollTop+document.documentElement.scrollTop);
+ }
+
+ this.events = {
+
+ // handlers for sound events as they're started/stopped/played
+
+ play: function() {
+ pl.removeClass(this._360data.oUIBox,this._360data.className);
+ this._360data.className = pl.css.sPlaying;
+ pl.addClass(this._360data.oUIBox,this._360data.className);
+ self.fanOut(this);
+ },
+
+ stop: function() {
+ pl.removeClass(this._360data.oUIBox,this._360data.className);
+ this._360data.className = '';
+ self.fanIn(this);
+ },
+
+ pause: function() {
+ pl.removeClass(this._360data.oUIBox,this._360data.className);
+ this._360data.className = pl.css.sPaused;
+ pl.addClass(this._360data.oUIBox,this._360data.className);
+ },
+
+ resume: function() {
+ pl.removeClass(this._360data.oUIBox,this._360data.className);
+ this._360data.className = pl.css.sPlaying;
+ pl.addClass(this._360data.oUIBox,this._360data.className);
+ },
+
+ finish: function() {
+ pl.removeClass(this._360data.oUIBox,this._360data.className);
+ this._360data.className = '';
+ // self.clearCanvas(this._360data.oCanvas);
+ this._360data.didFinish = true; // so fan draws full circle
+ self.fanIn(this);
+ if (pl.config.playNext) {
+ var nextLink = (pl.indexByURL[this._360data.oLink.href]+1);
+ if (nextLink<pl.links.length) {
+ pl.handleClick({'target':pl.links[nextLink]});
+ }
+ }
+ },
+
+ whileloading: function() {
+ if (this.paused) {
+ self.updatePlaying.apply(this);
+ }
+ },
+
+ whileplaying: function() {
+ self.updatePlaying.apply(this);
+ this._360data.fps++;
+ },
+
+ bufferchange: function() {
+ if (this.isBuffering) {
+ pl.addClass(this._360data.oUIBox,pl.css.sBuffering);
+ } else {
+ pl.removeClass(this._360data.oUIBox,pl.css.sBuffering);
+ }
+ }
+
+ }
+
+ this.stopEvent = function(e) {
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.getTheDamnLink = (isIE)?function(e) {
+ // I really didn't want to have to do this.
+ return (e && e.target?e.target:window.event.srcElement);
+ }:function(e) {
+ return e.target;
+ }
+
+ this.handleClick = function(e) {
+ // a sound link was clicked
+ if (e.button > 1) {
+ // only catch left-clicks
+ return true;
+ }
+ var o = self.getTheDamnLink(e);
+ if (o.nodeName.toLowerCase() != 'a') {
+ o = self.isChildOfNode(o,'a');
+ if (!o) return true;
+ }
+ if (!self.isChildOfClass(o,'ui360')) {
+ // not a link we're interested in
+ return true;
+ }
+ var sURL = o.getAttribute('href');
+ if (!o.href || !sm.canPlayLink(o) || self.hasClass(o,self.excludeClass)) {
+ return true; // pass-thru for non-MP3/non-links
+ }
+ sm._writeDebug('handleClick()');
+ var soundURL = (o.href);
+ var thisSound = self.getSoundByURL(soundURL);
+ if (thisSound) {
+ // already exists
+ if (thisSound == self.lastSound) {
+ // and was playing (or paused)
+ thisSound.togglePause();
+ } else {
+ // different sound
+ thisSound.togglePause(); // start playing current
+ sm._writeDebug('sound different than last sound: '+self.lastSound.sID);
+ if (self.lastSound) {
+ self.stopSound(self.lastSound);
+ }
+ }
+ } else {
+ // append some dom shiz
+
+ // create sound
+ thisSound = sm.createSound({
+ id:'ui360Sound'+(self.soundCount++),
+ url:soundURL,
+ onplay:self.events.play,
+ onstop:self.events.stop,
+ onpause:self.events.pause,
+ onresume:self.events.resume,
+ onfinish:self.events.finish,
+ onbufferchange:self.events.bufferchange,
+ whileloading:self.events.whileloading,
+ whileplaying:self.events.whileplaying
+ });
+ var oContainer = o.parentNode;
+ // tack on some custom data
+
+ thisSound._360data = {
+ oUI360: self.getParentByClassName(o,'ui360'), // the (whole) entire container
+ oLink: o, // DOM node for reference within SM2 object event handlers
+ className: self.css.sPlaying,
+ oUIBox: self.getElementsByClassName('sm2-360ui','div',oContainer)[0],
+ oCanvas: self.getElementsByClassName('sm2-canvas','canvas',oContainer)[0],
+ oButton: self.getElementsByClassName('sm2-360btn','img',oContainer)[0],
+ oTiming: self.getElementsByClassName('sm2-timing','div',oContainer)[0],
+ oCover: self.getElementsByClassName('sm2-cover','div',oContainer)[0],
+ lastTime: null,
+ didFinish: null,
+ pauseCount:0,
+ radius:0,
+ amplifier: (self.config.usePeakData?0.9:1), // TODO: x1 if not being used, else use dynamic "how much to amplify by" value
+ radiusMax: self.config.circleDiameter*0.175, // circle radius
+ width:0,
+ widthMax: self.config.circleDiameter*0.4, // width of the outer ring
+ lastValues: {
+ bytesLoaded: 0,
+ bytesTotal: 0,
+ position: 0,
+ durationEstimate: 0
+ }, // used to track "last good known" values before sound finish/reset for anim
+ animating: false,
+ oAnim: new Animator({
+ duration: self.config.animDuration,
+ transition:self.config.animTransition,
+ onComplete: function() {
+ // var thisSound = this;
+ // thisSound._360data.didFinish = false; // reset full circle
+ }
+ }),
+ oAnimProgress: function(nProgress) {
+ var thisSound = this;
+ thisSound._360data.radius = parseInt(thisSound._360data.radiusMax*thisSound._360data.amplifier*nProgress);
+ thisSound._360data.width = parseInt(thisSound._360data.widthMax*thisSound._360data.amplifier*nProgress);
+ if (self.config.scaleFont && self.config.fontSizeMax != null) {
+ thisSound._360data.oTiming.style.fontSize = parseInt(Math.max(1,self.config.fontSizeMax*nProgress))+'px';
+ thisSound._360data.oTiming.style.opacity = nProgress;
+ }
+ if (thisSound.paused || thisSound.playState == 0 || thisSound._360data.lastValues.bytesLoaded == 0 || thisSound._360data.lastValues.position == 0) {
+ self.updatePlaying.apply(thisSound);
+ }
+ },
+ fps: 0
+ };
+
+ // "Metadata" (annotations)
+ if (typeof self.Metadata != 'undefined' && self.getElementsByClassName('metadata','div',thisSound._360data.oUI360).length) {
+ thisSound._360data.metadata = new self.Metadata(thisSound,self);
+ }
+
+ // set the cover width/height to match the canvas
+ thisSound._360data.oCover.style.width = self.config.circleDiameter+'px';
+ thisSound._360data.oCover.style.height = self.config.circleDiameter+'px';
+
+ // minimize ze font
+ if (self.config.scaleFont && self.config.fontSizeMax != null) {
+ thisSound._360data.oTiming.style.fontSize = '1px';
+ }
+
+ // set up ze animation
+ thisSound._360data.oAnim.addSubject(thisSound._360data.oAnimProgress,thisSound);
+
+ // animate the radius out nice
+ self.refreshCoords(thisSound);
+
+ self.updatePlaying.apply(thisSound);
+
+ self.soundsByURL[soundURL] = thisSound;
+ self.sounds.push(thisSound);
+ if (self.lastSound) {
+ self.stopSound(self.lastSound);
+ }
+ thisSound.play();
+ }
+
+ self.lastSound = thisSound; // reference for next call
+
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof event != 'undefined') {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.fanOut = function(oSound) {
+ var thisSound = oSound;
+ if (thisSound._360data.animating == 1) {
+ return false;
+ }
+ thisSound._360data.animating = 0;
+ soundManager._writeDebug('fanOut: '+thisSound.sID+': '+thisSound._360data.oLink.href);
+ thisSound._360data.oAnim.seekTo(1); // play to end
+ window.setTimeout(function() {
+ // oncomplete hack
+ thisSound._360data.animating = 0;
+ },self.config.animDuration+20);
+ }
+
+ this.fanIn = function(oSound) {
+ var thisSound = oSound;
+ if (thisSound._360data.animating == -1) {
+ return false;
+ }
+ thisSound._360data.animating = -1;
+ soundManager._writeDebug('fanIn: '+thisSound.sID+': '+thisSound._360data.oLink.href);
+ // massive hack
+ thisSound._360data.oAnim.seekTo(0); // play to end
+ window.setTimeout(function() {
+ // reset full 360 fill after animation has completed (oncomplete hack)
+ thisSound._360data.didFinish = false;
+ thisSound._360data.animating = 0;
+ self.resetLastValues(thisSound);
+ },self.config.animDuration+20);
+
+ }
+
+ this.resetLastValues = function(oSound) {
+ var oData = oSound._360data;
+ oData.lastValues.position = 0;
+ // oData.lastValues.bytesLoaded = 0; // will likely be cached, if file is small
+ // oData.lastValues.bytesTotal = 0;
+ // oData.lastValues.durationEstimate = 0;
+ }
+
+ this.refreshCoords = function(thisSound) {
+ thisSound._360data.canvasXY = self.findXY(thisSound._360data.oCanvas);
+ // thisSound._360data.canvasMid = [Math.floor(thisSound._360data.oCanvas.offsetWidth/2), Math.floor(thisSound._360data.oCanvas.offsetHeight/2)]; // doesn't work in IE, w/h are wrong
+ thisSound._360data.canvasMid = [self.config.circleRadius,self.config.circleRadius];
+ thisSound._360data.canvasMidXY = [thisSound._360data.canvasXY[0]+thisSound._360data.canvasMid[0], thisSound._360data.canvasXY[1]+thisSound._360data.canvasMid[1]];
+ }
+
+ this.stopSound = function(oSound) {
+ soundManager._writeDebug('stopSound: '+oSound.sID);
+ soundManager.stop(oSound.sID);
+ soundManager.unload(oSound.sID);
+ }
+
+ this.buttonClick = function(e) {
+ var o = e?(e.target?e.target:e.srcElement):event.srcElement;
+ self.handleClick({target:self.getParentByClassName(o,'sm2-360ui').nextSibling}); // link next to the nodes we inserted
+ return false;
+ }
+
+ this.buttonMouseDown = function(e) {
+ // user might decide to drag from here
+ // watch for mouse move
+ if (!isTouchDevice) {
+ document.onmousemove = function(e) {
+ // should be boundary-checked, really (eg. move 3px first?)
+ self.mouseDown(e);
+ }
+ } else {
+ self.addEventHandler(document,'touchmove',self.mouseDown);
+ }
+ self.stopEvent(e);
+ return false;
+ }
+
+ this.mouseDown = function(e) {
+ if (!self.lastSound) {
+ self.stopEvent(e);
+ return false;
+ }
+ var thisSound = self.lastSound;
+ // just in case, update coordinates (maybe the element moved since last time.)
+ self.refreshCoords(thisSound);
+ var oData = self.lastSound._360data;
+ self.addClass(oData.oUIBox,'sm2_dragging');
+ oData.pauseCount = (self.lastSound.paused?1:0);
+ // self.lastSound.pause();
+ self.mmh(e?e:event);
+ if (isTouchDevice) {
+ self.removeEventHandler(document,'touchmove',self.mouseDown);
+ self.addEventHandler(document,'touchmove',self.mmh);
+ self.addEventHandler(document,'touchend',self.mouseUp);
+ } else {
+ document.onmousemove = self.mmh;
+ document.onmouseup = self.mouseUp;
+ }
+ self.stopEvent(e);
+ return false;
+ }
+
+ this.mouseUp = function(e) {
+ var oData = self.lastSound._360data;
+ self.removeClass(oData.oUIBox,'sm2_dragging');
+ if (oData.pauseCount == 0) {
+ self.lastSound.resume();
+ }
+ if (!isTouchDevice) {
+ document.onmousemove = null;
+ document.onmouseup = null;
+ } else {
+ self.removeEventHandler(document,'touchmove',self.mmh);
+ self.removeEventHandler(document,'touchend',self.mouseUP);
+ }
+ }
+
+ var fullCircle = 360;
+
+ this.mmh = function(e) {
+ if (typeof e == 'undefined') {
+ var e = event;
+ }
+ var oSound = self.lastSound;
+ var coords = self.getMouseXY(e);
+ var x = coords[0];
+ var y = coords[1];
+ var deltaX = x-oSound._360data.canvasMidXY[0];
+ var deltaY = y-oSound._360data.canvasMidXY[1];
+ var angle = Math.floor(fullCircle-(self.rad2deg(Math.atan2(deltaX,deltaY))+180));
+ oSound.setPosition(oSound.durationEstimate*(angle/fullCircle));
+ self.stopEvent(e);
+ return false;
+ }
+
+ // assignMouseDown();
+
+ this.drawSolidArc = function(oCanvas, color, radius, width, radians, startAngle, noClear) {
+
+ // thank you, http://www.snipersystems.co.nz/community/polarclock/tutorial.html
+
+ var x = radius;
+ var y = radius;
+
+ var canvas = oCanvas;
+
+ if (canvas.getContext){
+ // use getContext to use the canvas for drawing
+ var ctx = canvas.getContext('2d');
+ }
+
+ // var startAngle = 0;
+ var oCanvas = ctx;
+
+ if (!noClear) {
+ self.clearCanvas(canvas);
+ }
+ // ctx.restore();
+
+ if (color) {
+ ctx.fillStyle = color;
+ } else {
+ // ctx.fillStyle = 'black';
+ }
+
+ oCanvas.beginPath();
+
+ if (isNaN(radians)) {
+ radians = 0;
+ }
+
+ var innerRadius = radius-width;
+ var doesntLikeZero = (isOpera || isSafari); // safari 4 doesn't actually seem to mind.
+
+ if (!doesntLikeZero || (doesntLikeZero && radius > 0)) {
+ oCanvas.arc(0, 0, radius, startAngle, radians, false);
+ var endPoint = self.getArcEndpointCoords(innerRadius, radians);
+ oCanvas.lineTo(endPoint.x, endPoint.y);
+ oCanvas.arc(0, 0, innerRadius, radians, startAngle, true);
+ oCanvas.closePath();
+ oCanvas.fill();
+ }
+
+ }
+
+ this.getArcEndpointCoords = function(radius, radians) {
+ return {
+ x: radius * Math.cos(radians),
+ y: radius * Math.sin(radians)
+ };
+ }
+
+
+this.deg2rad = function(nDeg) {
+ return (nDeg * Math.PI/180);
+}
+
+this.rad2deg = function(nRad) {
+ return (nRad * 180/Math.PI);
+}
+
+this.getTime = function(nMSec,bAsString) {
+ // convert milliseconds to mm:ss, return as object literal or string
+ var nSec = Math.floor(nMSec/1000);
+ var min = Math.floor(nSec/60);
+ var sec = nSec-(min*60);
+ // if (min == 0 && sec == 0) return null; // return 0:00 as null
+ return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});
+}
+
+this.clearCanvas = function(oCanvas) {
+ var canvas = oCanvas;
+ var ctx = null;
+ if (canvas.getContext){
+ // use getContext to use the canvas for drawing
+ ctx = canvas.getContext('2d');
+ }
+ var width = canvas.offsetWidth;
+ var height = canvas.offsetHeight;
+ ctx.clearRect(-(width/2), -(height/2), width, height);
+}
+
+
+var fullCircle = (isOpera||isChrome?359.9:360); // I dunno what Opera doesn't like about this.
+
+this.updatePlaying = function() {
+ if (this.bytesLoaded) {
+ this._360data.lastValues.bytesLoaded = this.bytesLoaded;
+ this._360data.lastValues.bytesTotal = this.bytesTotal;
+ }
+ if (this.position) {
+ this._360data.lastValues.position = this.position;
+ }
+ if (this.durationEstimate) {
+ this._360data.lastValues.durationEstimate = this.durationEstimate;
+ }
+
+ self.drawSolidArc(this._360data.oCanvas,self.config.backgroundRingColor,this._360data.width,this._360data.radius,self.deg2rad(fullCircle),false);
+
+ self.drawSolidArc(this._360data.oCanvas,(this._360data.metadata?self.config.loadRingColorMetadata:self.config.loadRingColor),this._360data.width,this._360data.radius,self.deg2rad(fullCircle*(this._360data.lastValues.bytesLoaded/this._360data.lastValues.bytesTotal)),0,true);
+
+ if (this._360data.lastValues.position != 0) {
+ // don't draw if 0 (full black circle in Opera)
+ self.drawSolidArc(this._360data.oCanvas,(this._360data.metadata?self.config.playRingColorMetadata:self.config.playRingColor),this._360data.width,this._360data.radius,self.deg2rad((this._360data.didFinish==1?fullCircle:fullCircle*(this._360data.lastValues.position/this._360data.lastValues.durationEstimate))),0,true);
+ }
+
+ // metadata goes here
+ if (this._360data.metadata) {
+ this._360data.metadata.events.whileplaying();
+ }
+
+ var timeNow = (self.config.showHMSTime?self.getTime(this.position,true):parseInt(this.position/1000));
+
+ if (timeNow != this._360data.lastTime) {
+ this._360data.lastTime = timeNow;
+ this._360data.oTiming.innerHTML = timeNow;
+ }
+
+ // draw spectrum, if applicable
+ if (!isIE) { // IE can render maybe 3 or 4 FPS when including the wave/EQ, so don't bother.
+ self.updateWaveform(this);
+ // self.updateWaveformOld(this);
+ }
+
+ if (self.config.useFavIcon && self.vuMeter) {
+ self.vuMeter.updateVU(this);
+ }
+
+}
+
+ this.updateWaveform = function(oSound) {
+
+ if ((!self.config.useWaveformData && !self.config.useEQData) || (!sm.features.waveformData && !sm.features.eqData)) {
+ // feature not enabled..
+ return false;
+ }
+
+ if (!oSound.waveformData.left.length && !oSound.eqData.length && !oSound.peakData.left) {
+ // no data (or errored out/paused/unavailable?)
+ return false;
+ }
+
+ /* use for testing the data */
+ /*
+ for (i=0; i<256; i++) {
+ oSound.eqData[i] = 1-(i/256);
+ }
+ */
+
+ var oCanvas = oSound._360data.oCanvas.getContext('2d');
+ var offX = 0;
+ var offY = parseInt(self.config.circleDiameter/2);
+ var scale = offY/2; // Y axis (+/- this distance from 0)
+ var lineWidth = Math.floor(self.config.circleDiameter-(self.config.circleDiameter*0.175)/(self.config.circleDiameter/255)); // width for each line
+ lineWidth = 1;
+ var lineHeight = 1;
+ var thisY = 0;
+ var offset = offY;
+
+ if (self.config.useWaveformData) {
+ // raw waveform
+ var downSample = self.config.waveformDataDownsample; // only sample X in 256 (greater number = less sample points)
+ downSample = Math.max(1,downSample); // make sure it's at least 1
+ var dataLength = 256;
+ var sampleCount = (dataLength/downSample);
+ var startAngle = 0;
+ var endAngle = 0;
+ var waveData = null;
+ var innerRadius = (self.config.waveformDataOutside?1:(self.config.waveformDataConstrain?0.5:0.565));
+ var scale = (self.config.waveformDataOutside?0.7:0.75);
+ var perItemAngle = self.deg2rad((360/sampleCount)*self.config.waveformDataLineRatio); // 0.85 = clean pixel lines at 150? // self.deg2rad(360*(Math.max(1,downSample-1))/sampleCount);
+ for (var i=0; i<dataLength; i+=downSample) {
+ startAngle = self.deg2rad(360*(i/(sampleCount)*1/downSample)); // +0.67 - counter for spacing
+ endAngle = startAngle+perItemAngle;
+ waveData = oSound.waveformData.left[i];
+ if (waveData<0 && self.config.waveformDataConstrain) {
+ waveData = Math.abs(waveData);
+ }
+ self.drawSolidArc(oSound._360data.oCanvas,self.config.waveformDataColor,oSound._360data.width*innerRadius,oSound._360data.radius*scale*1.25*waveData,endAngle,startAngle,true);
+ }
+ }
+
+ if (self.config.useEQData) {
+ // EQ spectrum
+ var downSample = self.config.eqDataDownsample; // only sample N in 256
+ var yDiff = 0;
+ downSample = Math.max(1,downSample); // make sure it's at least 1
+ var eqSamples = 192; // drop the last 25% of the spectrum (>16500 Hz), most stuff won't actually use it.
+ var sampleCount = (eqSamples/downSample);
+ var innerRadius = (self.config.eqDataOutside?1:0.565);
+ var direction = (self.config.eqDataOutside?-1:1);
+ var scale = (self.config.eqDataOutside?0.5:0.75);
+ var startAngle = 0;
+ var endAngle = 0;
+ var perItemAngle = self.deg2rad((360/sampleCount)*self.config.eqDataLineRatio); // self.deg2rad(360/(sampleCount+1));
+ var playedAngle = self.deg2rad((oSound._360data.didFinish==1?360:360*(oSound._360data.lastValues.position/oSound._360data.lastValues.durationEstimate)));
+ var j=0;
+ var iAvg = 0;
+ for (var i=0; i<eqSamples; i+=downSample) {
+ startAngle = self.deg2rad(360*(i/eqSamples));
+ endAngle = startAngle+perItemAngle;
+ self.drawSolidArc(oSound._360data.oCanvas,(endAngle>playedAngle?self.config.eqDataColor:self.config.playRingColor),oSound._360data.width*innerRadius,oSound._360data.radius*scale*(oSound.eqData.left[i]*direction),endAngle,startAngle,true);
+ }
+ }
+
+ if (self.config.usePeakData) {
+ if (!oSound._360data.animating) {
+ var nPeak = (oSound.peakData.left||oSound.peakData.right);
+ // GIANT HACK: use EQ spectrum data for bass frequencies
+ var eqSamples = 3;
+ for (var i=0; i<eqSamples; i++) {
+ nPeak = (nPeak||oSound.eqData[i]);
+ }
+ oSound._360data.amplifier = (self.config.useAmplifier?(0.9+(nPeak*0.1)):1);
+ oSound._360data.radiusMax = self.config.circleDiameter*0.175*oSound._360data.amplifier;
+ oSound._360data.widthMax = self.config.circleDiameter*0.4*oSound._360data.amplifier;
+ oSound._360data.radius = parseInt(oSound._360data.radiusMax*oSound._360data.amplifier);
+ oSound._360data.width = parseInt(oSound._360data.widthMax*oSound._360data.amplifier);
+ }
+ }
+
+ }
+
+ this.updateWaveformOld = function(oSound) {
+
+ if ((!self.config.useWaveformData && !self.config.useEQData && !self.config.usePeakData) || (!sm.features.waveformData && !sm.features.eqData && !sm.features.peakData)) {
+ // feature not enabled..
+ return false;
+ }
+
+ if (!oSound.waveformData.left.length && !oSound.eqData.length && !oSound.peakData.left.length) {
+ // no data (or errored out/paused/unavailable?)
+ return false;
+ }
+
+ var oCanvas = oSound._360data.oCanvas.getContext('2d');
+ var offX = 0;
+ var offY = parseInt(self.config.circleDiameter*2/3);
+ var scale = offY*1/3; // Y axis (+/- this distance from 0)
+ var downSample = 1;
+ downSample = Math.max(1,downSample);
+ var j = oSound.waveformData.left.length;
+ var lineWidth = Math.max(1,((j*1/downSample)/self.config.circleDiameter));
+ var lineHeight = scale*2.5;
+ var thisY = 0;
+ var offset = offY;
+ var rotateDeg = -90;
+ oCanvas.rotate(self.deg2rad(rotateDeg*-1)); // compensate for arc starting at EAST // http://stackoverflow.com/questions/319267/tutorial-for-html-canvass-arc-function
+ oCanvas.translate(-self.config.circleRadius,-self.config.circleRadius);
+
+ if (self.config.useWaveformData) {
+ for (var i=0; i<j; i+=downSample) {
+ thisY = offY+(oSound.waveformData.left[i]*scale);
+ oCanvas.fillRect((i/j*(self.config.circleDiameter-lineWidth)+1),thisY,lineWidth,lineHeight);
+ }
+ } else {
+ // EQ spectrum
+ var offset = 9;
+ var yDiff = 0;
+ for (var i=0; i<128; i+=4) {
+ yDiff = oSound.eqData[i]*scale;
+ oCanvas.fillRect(i/128*(self.config.circleDiameter-4),self.config.circleDiameter-yDiff,lineWidth*3,yDiff);
+ }
+ }
+
+ // finished drawing..
+ oCanvas.translate(self.config.circleRadius,self.config.circleRadius);
+ oCanvas.rotate(self.deg2rad(rotateDeg)); // compensate for arc starting at EAST
+
+ }
+
+ this.callbackCount = 0;
+ this.peakDataHistory = [];
+
+ this.getUIHTML = function() {
+ return [
+ '<canvas class="sm2-canvas" width="'+self.config.circleDiameter+'" height="'+self.config.circleDiameter+'"></canvas>',
+ ' <img src="'+self.config.imageRoot+'empty.gif" class="sm2-360btn sm2-360btn-default" style="border:none" />', // note use of imageMap, edit or remove if you use a different-size image.
+ ' <div class="sm2-timing'+(navigator.userAgent.match(/safari/i)?' alignTweak':'')+'"></div>', // + Ever-so-slight Safari horizontal alignment tweak
+ ' <div class="sm2-cover"></div>'
+ ];
+ }
+
+ this.init = function() {
+ sm._writeDebug('threeSixtyPlayer.init()');
+ var oItems = self.getElementsByClassName('ui360','div');
+ var oLinks = [];
+
+ for (var i=0,j=oItems.length; i<j; i++) {
+ oLinks.push(oItems[i].getElementsByTagName('a')[0]);
+ // remove "fake" play button (unsupported case)
+ oItems[i].style.backgroundImage = 'none';
+ }
+ // grab all links, look for .mp3
+ var foundItems = 0;
+ var oCanvas = null;
+ var oCanvasCTX = null;
+ var oCover = null;
+
+ self.oUITemplate = document.createElement('div');
+ self.oUITemplate.className = 'sm2-360ui';
+
+ // fake a 360 UI so we can get some numbers from CSS, etc.
+
+ var oFakeUI = document.createElement('div');
+ oFakeUI.className = 'ui360';
+
+ var oFakeUIBox = oFakeUI.appendChild(self.oUITemplate.cloneNode(true));
+ oFakeUI.style.position = 'absolute';
+ oFakeUI.style.left = '-9999px';
+ var uiHTML = self.getUIHTML();
+
+ oFakeUIBox.innerHTML = uiHTML[1]+uiHTML[2]+uiHTML[3];
+ delete uiHTML;
+
+ var oTemp = document.body.appendChild(oFakeUI);
+
+ self.config.circleDiameter = parseInt(oFakeUIBox.offsetWidth);
+ self.config.circleRadius = parseInt(self.config.circleDiameter/2);
+ var oTiming = self.getElementsByClassName('sm2-timing','div',oTemp)[0];
+ self.config.fontSizeMax = parseInt(self.getStyle(oTiming,'font-size'));
+ if (isNaN(self.config.fontSizeMax)) {
+ // getStyle() etc. didn't work.
+ self.config.fontSizeMax = null;
+ }
+ // soundManager._writeDebug('diameter, font size: '+self.config.circleDiameter+','+self.config.fontSizeMax);
+
+ oFakeUI.parentNode.removeChild(oFakeUI);
+ delete oFakeUI;
+ delete oFakeUIBox;
+ delete oTemp;
+
+ // canvas needs inline width and height, doesn't quite work otherwise
+ self.oUITemplate.innerHTML = self.getUIHTML().join('');
+
+ for (i=0,j=oLinks.length; i<j; i++) {
+ if (sm.canPlayLink(oLinks[i]) && !self.hasClass(oLinks[i],self.excludeClass)) {
+ self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration
+ self.links[foundItems] = (oLinks[i]);
+ self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
+ foundItems++;
+ // add canvas shiz
+ var oUI = oLinks[i].parentNode.insertBefore(self.oUITemplate.cloneNode(true),oLinks[i]);
+
+ if (isIE && typeof G_vmlCanvasManager != 'undefined') { // IE only
+ var o = oLinks[i].parentNode;
+ var o2 = document.createElement('canvas');
+ o2.className = 'sm2-canvas';
+ var oID = 'sm2_canvas_'+parseInt(Math.random()*1048576);
+ o2.id = oID;
+ o2.width = self.config.circleDiameter;
+ o2.height = self.config.circleDiameter;
+ oUI.appendChild(o2);
+ G_vmlCanvasManager.initElement(o2); // Apply ExCanvas compatibility magic
+ oCanvas = document.getElementById(oID);
+ } else {
+ // add a handler for the button
+ oCanvas = oLinks[i].parentNode.getElementsByTagName('canvas')[0];
+ }
+ oCover = self.getElementsByClassName('sm2-cover','div',oLinks[i].parentNode)[0];
+ var oBtn = oLinks[i].parentNode.getElementsByTagName('img')[0];
+ var oBtn = oLinks[i].parentNode.getElementsByTagName('img')[0]
+ self.addEventHandler(oBtn,'click',self.buttonClick);
+ if (!isTouchDevice) {
+ self.addEventHandler(oCover,'mousedown',self.mouseDown);
+ } else {
+ self.addEventHandler(oCover,'touchstart',self.mouseDown);
+ }
+ oCanvasCTX = oCanvas.getContext('2d');
+ oCanvasCTX.translate(self.config.circleRadius,self.config.circleRadius);
+ oCanvasCTX.rotate(self.deg2rad(-90)); // compensate for arc starting at EAST // http://stackoverflow.com/questions/319267/tutorial-for-html-canvass-arc-function
+ }
+ }
+ if (foundItems>0) {
+ self.addEventHandler(document,'click',self.handleClick);
+ if (self.config.autoPlay) {
+ self.handleClick({target:self.links[0],preventDefault:function(){}});
+ }
+ }
+ sm._writeDebug('threeSixtyPlayer.init(): Found '+foundItems+' relevant items.');
+
+ if (self.config.useFavIcon && typeof this.VUMeter != 'undefined') {
+ this.vuMeter = new this.VUMeter(this);
+ }
+
+ }
+
+}
+
+// Optional: VU Meter component
+
+ThreeSixtyPlayer.prototype.VUMeter = function(oParent) {
+
+ var self = oParent;
+ var me = this;
+ this.vuMeterData = [];
+ this.vuDataCanvas = null;
+ var _head = document.getElementsByTagName('head')[0];
+ var isOpera = (navigator.userAgent.match(/opera/i));
+ var isFirefox = (navigator.userAgent.match(/firefox/i));
+
+ this.setPageIcon = function(sDataURL) {
+
+ if (!self.config.useFavIcon || !self.config.usePeakData || !sDataURL) {
+ return false;
+ }
+
+ var link = document.getElementById('sm2-favicon');
+ if (link) {
+ _head.removeChild(link);
+ link = null;
+ }
+ if (!link) {
+ link = document.createElement('link');
+ link.id = 'sm2-favicon';
+ link.rel = 'shortcut icon';
+ link.type = 'image/png';
+ link.href = sDataURL;
+ document.getElementsByTagName('head')[0].appendChild(link);
+ }
+ }
+
+ this.resetPageIcon = function() {
+ if (!self.config.useFavIcon) {
+ return false;
+ }
+ var link = document.getElementById('favicon');
+ if (link) {
+ link.href = '/favicon.ico';
+ }
+ }
+
+ this.updateVU = function(oSound) {
+ if (soundManager.flashVersion >= 9 && self.config.useFavIcon && self.config.usePeakData) {
+ me.setPageIcon(me.vuMeterData[parseInt(16*oSound.peakData.left)][parseInt(16*oSound.peakData.right)]);
+ }
+ }
+
+ this.createVUData = function() {
+ var i=0;
+ var j=0;
+ var canvas = me.vuDataCanvas.getContext('2d');
+ var vuGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ vuGrad.addColorStop(0,'rgb(0,192,0)');
+ vuGrad.addColorStop(0.30,'rgb(0,255,0)');
+ vuGrad.addColorStop(0.625,'rgb(255,255,0)');
+ vuGrad.addColorStop(0.85,'rgb(255,0,0)');
+ var bgGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ var outline = 'rgba(0,0,0,0.2)';
+ bgGrad.addColorStop(0,outline);
+ bgGrad.addColorStop(1,'rgba(0,0,0,0.5)');
+ for (i=0; i<16; i++) {
+ me.vuMeterData[i] = [];
+ }
+ for (var i=0; i<16; i++) {
+ for (j=0; j<16; j++) {
+ // reset/erase canvas
+ me.vuDataCanvas.setAttribute('width',16);
+ me.vuDataCanvas.setAttribute('height',16);
+ // draw new stuffs
+ canvas.fillStyle = bgGrad;
+ canvas.fillRect(0,0,7,15);
+ canvas.fillRect(8,0,7,15);
+ /*
+ // shadow
+ canvas.fillStyle = 'rgba(0,0,0,0.1)';
+ canvas.fillRect(1,15-i,7,17-(17-i));
+ canvas.fillRect(9,15-j,7,17-(17-j));
+ */
+ canvas.fillStyle = vuGrad;
+ canvas.fillRect(0,15-i,7,16-(16-i));
+ canvas.fillRect(8,15-j,7,16-(16-j));
+ // and now, clear out some bits.
+ canvas.clearRect(0,3,16,1);
+ canvas.clearRect(0,7,16,1);
+ canvas.clearRect(0,11,16,1);
+ me.vuMeterData[i][j] = me.vuDataCanvas.toDataURL('image/png');
+ // for debugging VU images
+ /*
+ var o = document.createElement('img');
+ o.style.marginRight = '5px';
+ o.src = vuMeterData[i][j];
+ document.documentElement.appendChild(o);
+ */
+ }
+ }
+ };
+
+ this.testCanvas = function(noOpaque) {
+ // canvas + toDataURL();
+ var c = document.createElement('canvas');
+ var ctx = null;
+ if (!c || typeof c.getContext == 'undefined') {
+ return null;
+ }
+ ctx = c.getContext('2d');
+ if (!ctx || typeof c.toDataURL != 'function') {
+ return null;
+ }
+ // just in case..
+ try {
+ var ok = c.toDataURL('image/png');
+ } catch(e) {
+ // no canvas or no toDataURL()
+ return null;
+ }
+ // assume we're all good.
+ return c;
+ }
+
+ this.init = function() {
+ if (self.config.useFavIcon) {
+ me.vuDataCanvas = me.testCanvas(true);
+ if (me.vuDataCanvas && (isFirefox || isOpera)) {
+ // these browsers support dynamically-updating the favicon
+ me.createVUData();
+ } else {
+ // browser doesn't support doing this
+ self.config.useFavIcon = false;
+ }
+ }
+ }
+
+ this.init();
+
+}
+
+// completely optional: Metadata/annotations/segments code
+
+ThreeSixtyPlayer.prototype.Metadata = function(oSound, oParent) {
+ soundManager._wD('Metadata()');
+ var me = this;
+ var oBox = oSound._360data.oUI360;
+ var o = oBox.getElementsByTagName('ul')[0];
+ var oItems = o.getElementsByTagName('li');
+ var isFirefox = (navigator.userAgent.match(/firefox/i));
+ this.lastWPExec = 0;
+ this.refreshInterval = 250;
+
+ var isAlt = false;
+
+ this.events = {
+ whileplaying: function() {
+ var width = oSound._360data.width;
+ var radius = oSound._360data.radius;
+ var fullDuration = (oSound.durationEstimate||(me.totalTime*1000));
+ var isAlt = null;
+ for (var i=0,j=me.data.length; i<j; i++) {
+ isAlt = (i%2==0);
+ oParent.drawSolidArc(oSound._360data.oCanvas,(isAlt?oParent.config.segmentRingColorAlt:oParent.config.segmentRingColor),isAlt?width:width, isAlt?radius/2:radius/2, oParent.deg2rad(360*(me.data[i].endTimeMS/fullDuration)), oParent.deg2rad(360*((me.data[i].startTimeMS||1)/fullDuration)), true);
+ }
+ var d = new Date();
+ if (d-me.lastWPExec>me.refreshInterval) {
+ me.refresh();
+ me.lastWPExec = d;
+ }
+ }
+ }
+
+ this.refresh = function() {
+ // Display info as appropriate
+ var index = null;
+ var now = oSound.position;
+ var metadata = oSound._360data.metadata.data;
+ for (var i=0, j=metadata.length; i<j; i++) {
+ if (now >= metadata[i].startTimeMS && now <= metadata[i].endTimeMS) {
+ index = i;
+ break;
+ }
+ }
+ if (index != metadata.currentItem && index < metadata.length) {
+ // update
+ oSound._360data.oLink.innerHTML = metadata.mainTitle+' <span class="metadata"><span class="sm2_divider"> | </span><span class="sm2_metadata">'+metadata[index].title+'</span></span>';
+ // self.setPageTitle(metadata[index].title+' | '+metadata.mainTitle);
+ metadata.currentItem = index;
+ }
+ }
+
+ this.totalTime = 0;
+
+ this.strToTime = function(sTime) {
+ var segments = sTime.split(':');
+ var seconds = 0;
+ for (var i=segments.length; i--;) {
+ seconds += parseInt(segments[i])*Math.pow(60,segments.length-1-i,10); // hours, minutes
+ }
+ return seconds;
+ }
+
+ this.data = [];
+ this.data.givenDuration = null;
+ this.data.currentItem = null;
+ this.data.mainTitle = oSound._360data.oLink.innerHTML;
+ for (var i=0; i<oItems.length; i++) {
+ this.data[i] = {
+ o: null,
+ title: oItems[i].getElementsByTagName('p')[0].innerHTML,
+ startTime: oItems[i].getElementsByTagName('span')[0].innerHTML,
+ startSeconds: me.strToTime(oItems[i].getElementsByTagName('span')[0].innerHTML.replace(/[()]/g,'')),
+ duration: 0,
+ durationMS: null,
+ startTimeMS: null,
+ endTimeMS: null,
+ oNote: null
+ }
+ }
+ var oDuration = oParent.getElementsByClassName('duration','div',oBox);
+ this.data.givenDuration = (oDuration.length?me.strToTime(oDuration[0].innerHTML)*1000:0);
+ for (i=0; i<this.data.length; i++) {
+ this.data[i].duration = parseInt(this.data[i+1]?this.data[i+1].startSeconds:(me.data.givenDuration?me.data.givenDuration:oSound.durationEstimate)/1000)-this.data[i].startSeconds;
+ this.data[i].startTimeMS = this.data[i].startSeconds*1000;
+ this.data[i].durationMS = this.data[i].duration*1000;
+ this.data[i].endTimeMS = this.data[i].startTimeMS+this.data[i].durationMS;
+ this.totalTime += this.data[i].duration;
+ }
+}
+
+var threeSixtyPlayer = null;
+
+if (navigator.userAgent.match(/webkit/i) && navigator.userAgent.match(/mobile/i)) {
+ // iPad, iPhone etc.
+ soundManager.useHTML5Audio = true;
+}
+
+soundManager.debugMode = (window.location.href.match(/debug=1/i)); // disable or enable debug output
+soundManager.consoleOnly = true;
+soundManager.flashVersion = 9;
+soundManager.useHighPerformance = true;
+soundManager.useFlashBlock = true;
+
+// soundManager.useFastPolling = true; // for more aggressive, faster UI updates (higher CPU use)
+
+// FPS data, testing/debug only
+if (soundManager.debugMode) {
+ var t = window.setInterval(function(){
+ if (threeSixtyPlayer && threeSixtyPlayer.lastSound && threeSixtyPlayer.lastSound._360data.fps && typeof window.isHome === 'undefined') {
+ soundManager._writeDebug('fps: ~'+threeSixtyPlayer.lastSound._360data.fps);
+ threeSixtyPlayer.lastSound._360data.fps = 0;
+ }
+ },1000);
+}
+
+threeSixtyPlayer = new ThreeSixtyPlayer();
+
+if (threeSixtyPlayer.config.useWaveformData) {
+ soundManager.flash9Options.useWaveformData = true;
+}
+if (threeSixtyPlayer.config.useEQData) {
+ soundManager.flash9Options.useEQData = true;
+}
+if (threeSixtyPlayer.config.usePeakData) {
+ soundManager.flash9Options.usePeakData = true;
+}
+
+soundManager.onready(function(){
+ if (soundManager.supported()) {
+ // soundManager.createSound() etc. may now be called
+ threeSixtyPlayer.init();
+ }
+});
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/berniecode-animator.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/berniecode-animator.js new file mode 100755 index 0000000..1e852e5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/berniecode-animator.js @@ -0,0 +1,674 @@ +/*
+ Animator.js 1.1.9
+
+ This library is released under the BSD license:
+
+ Copyright (c) 2006, Bernard Sumption. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer. Redistributions in binary
+ form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials
+ provided with the distribution. Neither the name BernieCode nor
+ the names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
+*/
+
+// http://www.berniecode.com/writing/animator.html
+
+// Applies a sequence of numbers between 0 and 1 to a number of subjects
+// construct - see setOptions for parameters
+function Animator(options) {
+ this.setOptions(options);
+ var _this = this;
+ this.timerDelegate = function(){_this.onTimerEvent()};
+ this.subjects = [];
+ this.subjectScopes = [];
+ this.target = 0;
+ this.state = 0;
+ this.lastTime = null;
+};
+Animator.prototype = {
+ // apply defaults
+ setOptions: function(options) {
+ this.options = Animator.applyDefaults({
+ interval: 20, // time between animation frames
+ duration: 400, // length of animation
+ onComplete: function(){},
+ onStep: function(){},
+ transition: Animator.tx.easeInOut
+ }, options);
+ },
+ // animate from the current state to provided value
+ seekTo: function(to) {
+ this.seekFromTo(this.state, to);
+ },
+ // animate from the current state to provided value
+ seekFromTo: function(from, to) {
+ this.target = Math.max(0, Math.min(1, to));
+ this.state = Math.max(0, Math.min(1, from));
+ this.lastTime = new Date().getTime();
+ if (!this.intervalId) {
+ this.intervalId = window.setInterval(this.timerDelegate, this.options.interval);
+ }
+ },
+ // animate from the current state to provided value
+ jumpTo: function(to) {
+ this.target = this.state = Math.max(0, Math.min(1, to));
+ this.propagate();
+ },
+ // seek to the opposite of the current target
+ toggle: function() {
+ this.seekTo(1 - this.target);
+ },
+ // add a function or an object with a method setState(state) that will be called with a number
+ // between 0 and 1 on each frame of the animation
+ addSubject: function(subject,scope) {
+ this.subjects[this.subjects.length] = subject;
+ this.subjectScopes[this.subjectScopes.length] = scope;
+ return this;
+ },
+ // remove all subjects
+ clearSubjects: function() {
+ this.subjects = [];
+ this.subjectScopes = [];
+ },
+ // forward the current state to the animation subjects
+ propagate: function() {
+ var value = this.options.transition(this.state);
+ for (var i=0; i<this.subjects.length; i++) {
+ if (this.subjects[i].setState) {
+ this.subjects[i].setState(value);
+ } else {
+ this.subjects[i].apply(this.subjectScopes[i],[value]);
+ }
+ }
+ },
+ // called once per frame to update the current state
+ onTimerEvent: function() {
+ var now = new Date().getTime();
+ var timePassed = now - this.lastTime;
+ this.lastTime = now;
+ var movement = (timePassed / this.options.duration) * (this.state < this.target ? 1 : -1);
+ if (Math.abs(movement) >= Math.abs(this.state - this.target)) {
+ this.state = this.target;
+ } else {
+ this.state += movement;
+ }
+
+ try {
+ this.propagate();
+ } finally {
+ this.options.onStep.call(this);
+ if (this.target == this.state) {
+ window.clearInterval(this.intervalId);
+ this.intervalId = null;
+ this.options.onComplete.call(this);
+ }
+ }
+ },
+ // shortcuts
+ play: function() {this.seekFromTo(0, 1)},
+ reverse: function() {this.seekFromTo(1, 0)},
+ // return a string describing this Animator, for debugging
+ inspect: function() {
+ var str = "#<Animator:\n";
+ for (var i=0; i<this.subjects.length; i++) {
+ str += this.subjects[i].inspect();
+ }
+ str += ">";
+ return str;
+ }
+}
+// merge the properties of two objects
+Animator.applyDefaults = function(defaults, prefs) {
+ prefs = prefs || {};
+ var prop, result = {};
+ for (prop in defaults) result[prop] = prefs[prop] !== undefined ? prefs[prop] : defaults[prop];
+ return result;
+}
+// make an array from any object
+Animator.makeArray = function(o) {
+ if (o == null) return [];
+ if (!o.length) return [o];
+ var result = [];
+ for (var i=0; i<o.length; i++) result[i] = o[i];
+ return result;
+}
+// convert a dash-delimited-property to a camelCaseProperty (c/o Prototype, thanks Sam!)
+Animator.camelize = function(string) {
+ var oStringList = string.split('-');
+ if (oStringList.length == 1) return oStringList[0];
+
+ var camelizedString = string.indexOf('-') == 0
+ ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
+ : oStringList[0];
+
+ for (var i = 1, len = oStringList.length; i < len; i++) {
+ var s = oStringList[i];
+ camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+ }
+ return camelizedString;
+}
+// syntactic sugar for creating CSSStyleSubjects
+Animator.apply = function(el, style, options) {
+ if (style instanceof Array) {
+ return new Animator(options).addSubject(new CSSStyleSubject(el, style[0], style[1]));
+ }
+ return new Animator(options).addSubject(new CSSStyleSubject(el, style));
+}
+// make a transition function that gradually accelerates. pass a=1 for smooth
+// gravitational acceleration, higher values for an exaggerated effect
+Animator.makeEaseIn = function(a) {
+ return function(state) {
+ return Math.pow(state, a*2);
+ }
+}
+// as makeEaseIn but for deceleration
+Animator.makeEaseOut = function(a) {
+ return function(state) {
+ return 1 - Math.pow(1 - state, a*2);
+ }
+}
+// make a transition function that, like an object with momentum being attracted to a point,
+// goes past the target then returns
+Animator.makeElastic = function(bounces) {
+ return function(state) {
+ state = Animator.tx.easeInOut(state);
+ return ((1-Math.cos(state * Math.PI * bounces)) * (1 - state)) + state;
+ }
+}
+// make an Attack Decay Sustain Release envelope that starts and finishes on the same level
+//
+Animator.makeADSR = function(attackEnd, decayEnd, sustainEnd, sustainLevel) {
+ if (sustainLevel == null) sustainLevel = 0.5;
+ return function(state) {
+ if (state < attackEnd) {
+ return state / attackEnd;
+ }
+ if (state < decayEnd) {
+ return 1 - ((state - attackEnd) / (decayEnd - attackEnd) * (1 - sustainLevel));
+ }
+ if (state < sustainEnd) {
+ return sustainLevel;
+ }
+ return sustainLevel * (1 - ((state - sustainEnd) / (1 - sustainEnd)));
+ }
+}
+// make a transition function that, like a ball falling to floor, reaches the target and/
+// bounces back again
+Animator.makeBounce = function(bounces) {
+ var fn = Animator.makeElastic(bounces);
+ return function(state) {
+ state = fn(state);
+ return state <= 1 ? state : 2-state;
+ }
+}
+
+// pre-made transition functions to use with the 'transition' option
+Animator.tx = {
+ easeInOut: function(pos){
+ return ((-Math.cos(pos*Math.PI)/2) + 0.5);
+ },
+ linear: function(x) {
+ return x;
+ },
+ easeIn: Animator.makeEaseIn(1.5),
+ easeOut: Animator.makeEaseOut(1.5),
+ strongEaseIn: Animator.makeEaseIn(2.5),
+ strongEaseOut: Animator.makeEaseOut(2.5),
+ elastic: Animator.makeElastic(1),
+ veryElastic: Animator.makeElastic(3),
+ bouncy: Animator.makeBounce(1),
+ veryBouncy: Animator.makeBounce(3)
+}
+
+// animates a pixel-based style property between two integer values
+function NumericalStyleSubject(els, property, from, to, units) {
+ this.els = Animator.makeArray(els);
+ if (property == 'opacity' && window.ActiveXObject) {
+ this.property = 'filter';
+ } else {
+ this.property = Animator.camelize(property);
+ }
+ this.from = parseFloat(from);
+ this.to = parseFloat(to);
+ this.units = units != null ? units : 'px';
+}
+NumericalStyleSubject.prototype = {
+ setState: function(state) {
+ var style = this.getStyle(state);
+ var visibility = (this.property == 'opacity' && state == 0) ? 'hidden' : '';
+ var j=0;
+ for (var i=0; i<this.els.length; i++) {
+ try {
+ this.els[i].style[this.property] = style;
+ } catch (e) {
+ // ignore fontWeight - intermediate numerical values cause exeptions in firefox
+ if (this.property != 'fontWeight') throw e;
+ }
+ if (j++ > 20) return;
+ }
+ },
+ getStyle: function(state) {
+ state = this.from + ((this.to - this.from) * state);
+ if (this.property == 'filter') return "alpha(opacity=" + Math.round(state*100) + ")";
+ if (this.property == 'opacity') return state;
+ return Math.round(state) + this.units;
+ },
+ inspect: function() {
+ return "\t" + this.property + "(" + this.from + this.units + " to " + this.to + this.units + ")\n";
+ }
+}
+
+// animates a colour based style property between two hex values
+function ColorStyleSubject(els, property, from, to) {
+ this.els = Animator.makeArray(els);
+ this.property = Animator.camelize(property);
+ this.to = this.expandColor(to);
+ this.from = this.expandColor(from);
+ this.origFrom = from;
+ this.origTo = to;
+}
+
+ColorStyleSubject.prototype = {
+ // parse "#FFFF00" to [256, 256, 0]
+ expandColor: function(color) {
+ var hexColor, red, green, blue;
+ hexColor = ColorStyleSubject.parseColor(color);
+ if (hexColor) {
+ red = parseInt(hexColor.slice(1, 3), 16);
+ green = parseInt(hexColor.slice(3, 5), 16);
+ blue = parseInt(hexColor.slice(5, 7), 16);
+ return [red,green,blue]
+ }
+ if (window.DEBUG) {
+ alert("Invalid colour: '" + color + "'");
+ }
+ },
+ getValueForState: function(color, state) {
+ return Math.round(this.from[color] + ((this.to[color] - this.from[color]) * state));
+ },
+ setState: function(state) {
+ var color = '#'
+ + ColorStyleSubject.toColorPart(this.getValueForState(0, state))
+ + ColorStyleSubject.toColorPart(this.getValueForState(1, state))
+ + ColorStyleSubject.toColorPart(this.getValueForState(2, state));
+ for (var i=0; i<this.els.length; i++) {
+ this.els[i].style[this.property] = color;
+ }
+ },
+ inspect: function() {
+ return "\t" + this.property + "(" + this.origFrom + " to " + this.origTo + ")\n";
+ }
+}
+
+// return a properly formatted 6-digit hex colour spec, or false
+ColorStyleSubject.parseColor = function(string) {
+ var color = '#', match;
+ if(match = ColorStyleSubject.parseColor.rgbRe.exec(string)) {
+ var part;
+ for (var i=1; i<=3; i++) {
+ part = Math.max(0, Math.min(255, parseInt(match[i])));
+ color += ColorStyleSubject.toColorPart(part);
+ }
+ return color;
+ }
+ if (match = ColorStyleSubject.parseColor.hexRe.exec(string)) {
+ if(match[1].length == 3) {
+ for (var i=0; i<3; i++) {
+ color += match[1].charAt(i) + match[1].charAt(i);
+ }
+ return color;
+ }
+ return '#' + match[1];
+ }
+ return false;
+}
+// convert a number to a 2 digit hex string
+ColorStyleSubject.toColorPart = function(number) {
+ if (number > 255) number = 255;
+ var digits = number.toString(16);
+ if (number < 16) return '0' + digits;
+ return digits;
+}
+ColorStyleSubject.parseColor.rgbRe = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
+ColorStyleSubject.parseColor.hexRe = /^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
+
+// Animates discrete styles, i.e. ones that do not scale but have discrete values
+// that can't be interpolated
+function DiscreteStyleSubject(els, property, from, to, threshold) {
+ this.els = Animator.makeArray(els);
+ this.property = Animator.camelize(property);
+ this.from = from;
+ this.to = to;
+ this.threshold = threshold || 0.5;
+}
+
+DiscreteStyleSubject.prototype = {
+ setState: function(state) {
+ var j=0;
+ for (var i=0; i<this.els.length; i++) {
+ this.els[i].style[this.property] = state <= this.threshold ? this.from : this.to;
+ }
+ },
+ inspect: function() {
+ return "\t" + this.property + "(" + this.from + " to " + this.to + " @ " + this.threshold + ")\n";
+ }
+}
+
+// animates between two styles defined using CSS.
+// if style1 and style2 are present, animate between them, if only style1
+// is present, animate between the element's current style and style1
+function CSSStyleSubject(els, style1, style2) {
+ els = Animator.makeArray(els);
+ this.subjects = [];
+ if (els.length == 0) return;
+ var prop, toStyle, fromStyle;
+ if (style2) {
+ fromStyle = this.parseStyle(style1, els[0]);
+ toStyle = this.parseStyle(style2, els[0]);
+ } else {
+ toStyle = this.parseStyle(style1, els[0]);
+ fromStyle = {};
+ for (prop in toStyle) {
+ fromStyle[prop] = CSSStyleSubject.getStyle(els[0], prop);
+ }
+ }
+ // remove unchanging properties
+ var prop;
+ for (prop in fromStyle) {
+ if (fromStyle[prop] == toStyle[prop]) {
+ delete fromStyle[prop];
+ delete toStyle[prop];
+ }
+ }
+ // discover the type (numerical or colour) of each style
+ var prop, units, match, type, from, to;
+ for (prop in fromStyle) {
+ var fromProp = String(fromStyle[prop]);
+ var toProp = String(toStyle[prop]);
+ if (toStyle[prop] == null) {
+ if (window.DEBUG) alert("No to style provided for '" + prop + '"');
+ continue;
+ }
+
+ if (from = ColorStyleSubject.parseColor(fromProp)) {
+ to = ColorStyleSubject.parseColor(toProp);
+ type = ColorStyleSubject;
+ } else if (fromProp.match(CSSStyleSubject.numericalRe)
+ && toProp.match(CSSStyleSubject.numericalRe)) {
+ from = parseFloat(fromProp);
+ to = parseFloat(toProp);
+ type = NumericalStyleSubject;
+ match = CSSStyleSubject.numericalRe.exec(fromProp);
+ var reResult = CSSStyleSubject.numericalRe.exec(toProp);
+ if (match[1] != null) {
+ units = match[1];
+ } else if (reResult[1] != null) {
+ units = reResult[1];
+ } else {
+ units = reResult;
+ }
+ } else if (fromProp.match(CSSStyleSubject.discreteRe)
+ && toProp.match(CSSStyleSubject.discreteRe)) {
+ from = fromProp;
+ to = toProp;
+ type = DiscreteStyleSubject;
+ units = 0; // hack - how to get an animator option down to here
+ } else {
+ if (window.DEBUG) {
+ alert("Unrecognised format for value of "
+ + prop + ": '" + fromStyle[prop] + "'");
+ }
+ continue;
+ }
+ this.subjects[this.subjects.length] = new type(els, prop, from, to, units);
+ }
+}
+
+CSSStyleSubject.prototype = {
+ // parses "width: 400px; color: #FFBB2E" to {width: "400px", color: "#FFBB2E"}
+ parseStyle: function(style, el) {
+ var rtn = {};
+ // if style is a rule set
+ if (style.indexOf(":") != -1) {
+ var styles = style.split(";");
+ for (var i=0; i<styles.length; i++) {
+ var parts = CSSStyleSubject.ruleRe.exec(styles[i]);
+ if (parts) {
+ rtn[parts[1]] = parts[2];
+ }
+ }
+ }
+ // else assume style is a class name
+ else {
+ var prop, value, oldClass;
+ oldClass = el.className;
+ el.className = style;
+ for (var i=0; i<CSSStyleSubject.cssProperties.length; i++) {
+ prop = CSSStyleSubject.cssProperties[i];
+ value = CSSStyleSubject.getStyle(el, prop);
+ if (value != null) {
+ rtn[prop] = value;
+ }
+ }
+ el.className = oldClass;
+ }
+ return rtn;
+
+ },
+ setState: function(state) {
+ for (var i=0; i<this.subjects.length; i++) {
+ this.subjects[i].setState(state);
+ }
+ },
+ inspect: function() {
+ var str = "";
+ for (var i=0; i<this.subjects.length; i++) {
+ str += this.subjects[i].inspect();
+ }
+ return str;
+ }
+}
+// get the current value of a css property,
+CSSStyleSubject.getStyle = function(el, property){
+ var style;
+ if(document.defaultView && document.defaultView.getComputedStyle){
+ style = document.defaultView.getComputedStyle(el, "").getPropertyValue(property);
+ if (style) {
+ return style;
+ }
+ }
+ property = Animator.camelize(property);
+ if(el.currentStyle){
+ style = el.currentStyle[property];
+ }
+ return style || el.style[property]
+}
+
+
+CSSStyleSubject.ruleRe = /^\s*([a-zA-Z\-]+)\s*:\s*(\S(.+\S)?)\s*$/;
+CSSStyleSubject.numericalRe = /^-?\d+(?:\.\d+)?(%|[a-zA-Z]{2})?$/;
+CSSStyleSubject.discreteRe = /^\w+$/;
+
+// required because the style object of elements isn't enumerable in Safari
+/*
+CSSStyleSubject.cssProperties = ['background-color','border','border-color','border-spacing',
+'border-style','border-top','border-right','border-bottom','border-left','border-top-color',
+'border-right-color','border-bottom-color','border-left-color','border-top-width','border-right-width',
+'border-bottom-width','border-left-width','border-width','bottom','color','font-size','font-size-adjust',
+'font-stretch','font-style','height','left','letter-spacing','line-height','margin','margin-top',
+'margin-right','margin-bottom','margin-left','marker-offset','max-height','max-width','min-height',
+'min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding',
+'padding-top','padding-right','padding-bottom','padding-left','quotes','right','size','text-indent',
+'top','width','word-spacing','z-index','opacity','outline-offset'];*/
+
+
+CSSStyleSubject.cssProperties = ['azimuth','background','background-attachment','background-color','background-image','background-position','background-repeat','border-collapse','border-color','border-spacing','border-style','border-top','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','border-top-width','border-right-width','border-bottom-width','border-left-width','border-width','bottom','clear','clip','color','content','cursor','direction','display','elevation','empty-cells','css-float','font','font-family','font-size','font-size-adjust','font-stretch','font-style','font-variant','font-weight','height','left','letter-spacing','line-height','list-style','list-style-image','list-style-position','list-style-type','margin','margin-top','margin-right','margin-bottom','margin-left','max-height','max-width','min-height','min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding','padding-top','padding-right','padding-bottom','padding-left','pause','position','right','size','table-layout','text-align','text-decoration','text-indent','text-shadow','text-transform','top','vertical-align','visibility','white-space','width','word-spacing','z-index','opacity','outline-offset','overflow-x','overflow-y'];
+
+
+// chains several Animator objects together
+function AnimatorChain(animators, options) {
+ this.animators = animators;
+ this.setOptions(options);
+ for (var i=0; i<this.animators.length; i++) {
+ this.listenTo(this.animators[i]);
+ }
+ this.forwards = false;
+ this.current = 0;
+}
+
+AnimatorChain.prototype = {
+ // apply defaults
+ setOptions: function(options) {
+ this.options = Animator.applyDefaults({
+ // by default, each call to AnimatorChain.play() calls jumpTo(0) of each animator
+ // before playing, which can cause flickering if you have multiple animators all
+ // targeting the same element. Set this to false to avoid this.
+ resetOnPlay: true
+ }, options);
+ },
+ // play each animator in turn
+ play: function() {
+ this.forwards = true;
+ this.current = -1;
+ if (this.options.resetOnPlay) {
+ for (var i=0; i<this.animators.length; i++) {
+ this.animators[i].jumpTo(0);
+ }
+ }
+ this.advance();
+ },
+ // play all animators backwards
+ reverse: function() {
+ this.forwards = false;
+ this.current = this.animators.length;
+ if (this.options.resetOnPlay) {
+ for (var i=0; i<this.animators.length; i++) {
+ this.animators[i].jumpTo(1);
+ }
+ }
+ this.advance();
+ },
+ // if we have just play()'d, then call reverse(), and vice versa
+ toggle: function() {
+ if (this.forwards) {
+ this.seekTo(0);
+ } else {
+ this.seekTo(1);
+ }
+ },
+ // internal: install an event listener on an animator's onComplete option
+ // to trigger the next animator
+ listenTo: function(animator) {
+ var oldOnComplete = animator.options.onComplete;
+ var _this = this;
+ animator.options.onComplete = function() {
+ if (oldOnComplete) oldOnComplete.call(animator);
+ _this.advance();
+ }
+ },
+ // play the next animator
+ advance: function() {
+ if (this.forwards) {
+ if (this.animators[this.current + 1] == null) return;
+ this.current++;
+ this.animators[this.current].play();
+ } else {
+ if (this.animators[this.current - 1] == null) return;
+ this.current--;
+ this.animators[this.current].reverse();
+ }
+ },
+ // this function is provided for drop-in compatibility with Animator objects,
+ // but only accepts 0 and 1 as target values
+ seekTo: function(target) {
+ if (target <= 0) {
+ this.forwards = false;
+ this.animators[this.current].seekTo(0);
+ } else {
+ this.forwards = true;
+ this.animators[this.current].seekTo(1);
+ }
+ }
+}
+
+// an Accordion is a class that creates and controls a number of Animators. An array of elements is passed in,
+// and for each element an Animator and a activator button is created. When an Animator's activator button is
+// clicked, the Animator and all before it seek to 0, and all Animators after it seek to 1. This can be used to
+// create the classic Accordion effect, hence the name.
+// see setOptions for arguments
+function Accordion(options) {
+ this.setOptions(options);
+ var selected = this.options.initialSection, current;
+ if (this.options.rememberance) {
+ current = document.location.hash.substring(1);
+ }
+ this.rememberanceTexts = [];
+ this.ans = [];
+ var _this = this;
+ for (var i=0; i<this.options.sections.length; i++) {
+ var el = this.options.sections[i];
+ var an = new Animator(this.options.animatorOptions);
+ var from = this.options.from + (this.options.shift * i);
+ var to = this.options.to + (this.options.shift * i);
+ an.addSubject(new NumericalStyleSubject(el, this.options.property, from, to, this.options.units));
+ an.jumpTo(0);
+ var activator = this.options.getActivator(el);
+ activator.index = i;
+ activator.onclick = function(){_this.show(this.index)};
+ this.ans[this.ans.length] = an;
+ this.rememberanceTexts[i] = activator.innerHTML.replace(/\s/g, "");
+ if (this.rememberanceTexts[i] === current) {
+ selected = i;
+ }
+ }
+ this.show(selected);
+}
+
+Accordion.prototype = {
+ // apply defaults
+ setOptions: function(options) {
+ this.options = Object.extend({
+ // REQUIRED: an array of elements to use as the accordion sections
+ sections: null,
+ // a function that locates an activator button element given a section element.
+ // by default it takes a button id from the section's "activator" attibute
+ getActivator: function(el) {return document.getElementById(el.getAttribute("activator"))},
+ // shifts each animator's range, for example with options {from:0,to:100,shift:20}
+ // the animators' ranges will be 0-100, 20-120, 40-140 etc.
+ shift: 0,
+ // the first page to show
+ initialSection: 0,
+ // if set to true, document.location.hash will be used to preserve the open section across page reloads
+ rememberance: true,
+ // constructor arguments to the Animator objects
+ animatorOptions: {}
+ }, options || {});
+ },
+ show: function(section) {
+ for (var i=0; i<this.ans.length; i++) {
+ this.ans[i].seekTo(i > section ? 1 : 0);
+ }
+ if (this.options.rememberance) {
+ document.location.hash = this.rememberanceTexts[section];
+ }
+ }
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/excanvas.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/excanvas.js new file mode 100755 index 0000000..d748873 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/360-player/script/excanvas.js @@ -0,0 +1,17 @@ +// Excanvas (Explorer Canvas) R43
+// http://excanvas.sourceforge.net/
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+if(!document.createElement("canvas").getContext){(function(){var u=Math;var v=u.round;var r=u.sin;var C=u.cos;var l=u.abs;var B=u.sqrt;var a=10;var n=a/2;function g(){return this.context_||(this.context_=new p(this))}var t=Array.prototype.slice;function D(j,m,E){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}var h={init:function(i){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",D(this.init_,this,j))}},init_:function(F){if(!F.namespaces.g_vml_){F.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!F.namespaces.g_o_){F.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!F.styleSheets.ex_canvas_){var E=F.createStyleSheet();E.owningElement.id="ex_canvas_";E.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var m=F.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=g;j.innerHTML="";j.attachEvent("onpropertychange",A);j.attachEvent("onresize",b);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j}};function A(j){var i=j.srcElement;switch(j.propertyName){case"width":i.style.width=i.attributes.width.nodeValue+"px";i.getContext().clearRect();break;case"height":i.style.height=i.attributes.height.nodeValue+"px";i.getContext().clearRect();break}}function b(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}h.init();var e=[];for(var y=0;y<16;y++){for(var x=0;x<16;x++){e[y*16+x]=y.toString(16)+x.toString(16)}}function q(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(E,m){var j=q();for(var i=0;i<3;i++){for(var H=0;H<3;H++){var F=0;for(var G=0;G<3;G++){F+=E[i][G]*m[G][H]}j[i][H]=F}}return j}function w(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}function c(m){var G,F=1;m=String(m);if(m.substring(0,3)=="rgb"){var I=m.indexOf("(",3);var j=m.indexOf(")",I+1);var H=m.substring(I+1,j).split(",");G="#";for(var E=0;E<3;E++){G+=e[Number(H[E])]}if(H.length==4&&m.substr(3,1)=="a"){F=H[3]}}else{G=m}return{color:G,alpha:F}}function s(i){switch(i){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function p(j){this.m_=q();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=a*1;this.globalAlpha=1;this.canvas=j;var i=j.ownerDocument.createElement("div");i.style.width=j.clientWidth+"px";i.style.height=j.clientHeight+"px";i.style.overflow="hidden";i.style.position="absolute";j.appendChild(i);this.element_=i;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var k=p.prototype;k.clearRect=function(){this.element_.innerHTML=""};k.beginPath=function(){this.currentPath_=[]};k.moveTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};k.lineTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};k.bezierCurveTo=function(m,j,J,I,H,F){var i=this.getCoords_(H,F);var G=this.getCoords_(m,j);var E=this.getCoords_(J,I);o(this,G,E,i)};function o(i,E,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:E.x,cp1y:E.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}k.quadraticCurveTo=function(H,m,j,i){var G=this.getCoords_(H,m);var F=this.getCoords_(j,i);var I={x:this.currentX_+2/3*(G.x-this.currentX_),y:this.currentY_+2/3*(G.y-this.currentY_)};var E={x:I.x+(F.x-this.currentX_)/3,y:I.y+(F.y-this.currentY_)/3};o(this,I,E,F)};k.arc=function(K,I,J,F,j,m){J*=a;var O=m?"at":"wa";var L=K+C(F)*J-n;var N=I+r(F)*J-n;var i=K+C(j)*J-n;var M=I+r(j)*J-n;if(L==i&&!m){L+=0.125}var E=this.getCoords_(K,I);var H=this.getCoords_(L,N);var G=this.getCoords_(i,M);this.currentPath_.push({type:O,x:E.x,y:E.y,radius:J,xStart:H.x,yStart:H.y,xEnd:G.x,yEnd:G.y})};k.rect=function(m,j,i,E){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+E);this.lineTo(m,j+E);this.closePath()};k.strokeRect=function(m,j,i,E){var F=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+E);this.lineTo(m,j+E);this.closePath();this.stroke();this.currentPath_=F};k.fillRect=function(m,j,i,E){var F=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+E);this.lineTo(m,j+E);this.closePath();this.fill();this.currentPath_=F};k.createLinearGradient=function(j,E,i,m){var F=new z("gradient");F.x0_=j;F.y0_=E;F.x1_=i;F.y1_=m;return F};k.createRadialGradient=function(E,G,m,j,F,i){var H=new z("gradientradial");H.x0_=E;H.y0_=G;H.r0_=m;H.x1_=j;H.y1_=F;H.r1_=i;return H};k.drawImage=function(R,m){var K,I,M,Z,P,N,T,ab;var L=R.runtimeStyle.width;var Q=R.runtimeStyle.height;R.runtimeStyle.width="auto";R.runtimeStyle.height="auto";var J=R.width;var X=R.height;R.runtimeStyle.width=L;R.runtimeStyle.height=Q;if(arguments.length==3){K=arguments[1];I=arguments[2];P=N=0;T=M=J;ab=Z=X}else{if(arguments.length==5){K=arguments[1];I=arguments[2];M=arguments[3];Z=arguments[4];P=N=0;T=J;ab=X}else{if(arguments.length==9){P=arguments[1];N=arguments[2];T=arguments[3];ab=arguments[4];K=arguments[5];I=arguments[6];M=arguments[7];Z=arguments[8]}else{throw Error("Invalid number of arguments")}}}var aa=this.getCoords_(K,I);var E=T/2;var j=ab/2;var Y=[];var i=10;var G=10;Y.push(" <g_vml_:group",' coordsize="',a*i,",",a*G,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",G,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var F=[];F.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",v(aa.x/a),",","Dy=",v(aa.y/a),"");var V=aa;var U=this.getCoords_(K+M,I);var S=this.getCoords_(K,I+Z);var O=this.getCoords_(K+M,I+Z);V.x=u.max(V.x,U.x,S.x,O.x);V.y=u.max(V.y,U.y,S.y,O.y);Y.push("padding:0 ",v(V.x/a),"px ",v(V.y/a),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",F.join(""),", sizingmethod='clip');")}else{Y.push("top:",v(aa.y/a),"px;left:",v(aa.x/a),"px;")}Y.push(' ">','<g_vml_:image src="',R.src,'"',' style="width:',a*M,"px;"," height:",a*Z,'px;"',' cropleft="',P/J,'"',' croptop="',N/X,'"',' cropright="',(J-P-T)/J,'"',' cropbottom="',(X-N-ab)/X,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",Y.join(""))};k.stroke=function(ae){var J=[];var K=false;var ap=c(ae?this.fillStyle:this.strokeStyle);var aa=ap.color;var ak=ap.alpha*this.globalAlpha;var F=10;var M=10;J.push("<g_vml_:shape",' filled="',!!ae,'"',' style="position:absolute;width:',F,"px;height:",M,'px;"',' coordorigin="0 0" coordsize="',a*F," ",a*M,'"',' stroked="',!ae,'"',' path="');var L=false;var ao={x:null,y:null};var V={x:null,y:null};for(var aj=0;aj<this.currentPath_.length;aj++){var ai=this.currentPath_[aj];var an;switch(ai.type){case"moveTo":an=ai;J.push(" m ",v(ai.x),",",v(ai.y));break;case"lineTo":J.push(" l ",v(ai.x),",",v(ai.y));break;case"close":J.push(" x ");ai=null;break;case"bezierCurveTo":J.push(" c ",v(ai.cp1x),",",v(ai.cp1y),",",v(ai.cp2x),",",v(ai.cp2y),",",v(ai.x),",",v(ai.y));break;case"at":case"wa":J.push(" ",ai.type," ",v(ai.x-this.arcScaleX_*ai.radius),",",v(ai.y-this.arcScaleY_*ai.radius)," ",v(ai.x+this.arcScaleX_*ai.radius),",",v(ai.y+this.arcScaleY_*ai.radius)," ",v(ai.xStart),",",v(ai.yStart)," ",v(ai.xEnd),",",v(ai.yEnd));break}if(ai){if(ao.x==null||ai.x<ao.x){ao.x=ai.x}if(V.x==null||ai.x>V.x){V.x=ai.x}if(ao.y==null||ai.y<ao.y){ao.y=ai.y}if(V.y==null||ai.y>V.y){V.y=ai.y}}}J.push(' ">');if(!ae){var U=this.lineScale_*this.lineWidth;if(U<1){ak*=U}J.push("<g_vml_:stroke",' opacity="',ak,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',s(this.lineCap),'"',' weight="',U,'px"',' color="',aa,'" />')}else{if(typeof this.fillStyle=="object"){var N=this.fillStyle;var S=0;var ah={x:0,y:0};var ab=0;var Q=1;if(N.type_=="gradient"){var P=N.x0_/this.arcScaleX_;var m=N.y0_/this.arcScaleY_;var O=N.x1_/this.arcScaleX_;var aq=N.y1_/this.arcScaleY_;var am=this.getCoords_(P,m);var al=this.getCoords_(O,aq);var I=al.x-am.x;var G=al.y-am.y;S=Math.atan2(I,G)*180/Math.PI;if(S<0){S+=360}if(S<0.000001){S=0}}else{var am=this.getCoords_(N.x0_,N.y0_);var j=V.x-ao.x;var E=V.y-ao.y;ah={x:(am.x-ao.x)/j,y:(am.y-ao.y)/E};j/=this.arcScaleX_*a;E/=this.arcScaleY_*a;var ag=u.max(j,E);ab=2*N.r0_/ag;Q=2*N.r1_/ag-ab}var Z=N.colors_;Z.sort(function(H,i){return H.offset-i.offset});var T=Z.length;var Y=Z[0].color;var X=Z[T-1].color;var ad=Z[0].alpha*this.globalAlpha;var ac=Z[T-1].alpha*this.globalAlpha;var af=[];for(var aj=0;aj<T;aj++){var R=Z[aj];af.push(R.offset*Q+ab+" "+R.color)}J.push('<g_vml_:fill type="',N.type_,'"',' method="none" focus="100%"',' color="',Y,'"',' color2="',X,'"',' colors="',af.join(","),'"',' opacity="',ac,'"',' g_o_:opacity2="',ad,'"',' angle="',S,'"',' focusposition="',ah.x,",",ah.y,'" />')}else{J.push('<g_vml_:fill color="',aa,'" opacity="',ak,'" />')}}J.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",J.join(""))};k.fill=function(){this.stroke(true)};k.closePath=function(){this.currentPath_.push({type:"close"})};k.getCoords_=function(E,j){var i=this.m_;return{x:a*(E*i[0][0]+j*i[1][0]+i[2][0])-n,y:a*(E*i[0][1]+j*i[1][1]+i[2][1])-n}};k.save=function(){var i={};w(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=d(q(),this.m_)};k.restore=function(){w(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};k.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];this.m_=d(i,this.m_)};k.rotate=function(j){var E=C(j);var m=r(j);var i=[[E,m,0],[-m,E,0],[0,0,1]];this.m_=d(i,this.m_)};k.scale=function(G,F){this.arcScaleX_*=G;this.arcScaleY_*=F;var j=[[G,0,0],[0,F,0],[0,0,1]];var i=this.m_=d(j,this.m_);var E=i[0][0]*i[1][1]-i[0][1]*i[1][0];this.lineScale_=B(l(E))};k.clip=function(){};k.arcTo=function(){};k.createPattern=function(){return new f};function z(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}z.prototype.addColorStop=function(j,i){i=c(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function f(){}G_vmlCanvasManager=h;CanvasRenderingContext2D=p;CanvasGradient=z;CanvasPattern=f})()};
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot1.png Binary files differnew file mode 100755 index 0000000..8684432 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot2.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot2.png Binary files differnew file mode 100755 index 0000000..b0700fe --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot2.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot3.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot3.png Binary files differnew file mode 100755 index 0000000..8ba6617 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot3.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot4.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot4.png Binary files differnew file mode 100755 index 0000000..ab67cc7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/360ui-screenshot4.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/8tracks-logo.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/8tracks-logo.png Binary files differnew file mode 100755 index 0000000..e1dbc64 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/8tracks-logo.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/discogs.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/discogs.gif Binary files differnew file mode 100755 index 0000000..d039d51 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/discogs.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9-dark.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9-dark.png Binary files differnew file mode 100755 index 0000000..d76a3a1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9-dark.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9.png Binary files differnew file mode 100755 index 0000000..77da060 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/flash9.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/getsatisfaction-icon.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/getsatisfaction-icon.gif Binary files differnew file mode 100755 index 0000000..f3762c7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/getsatisfaction-icon.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/hue_thumb.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/hue_thumb.png Binary files differnew file mode 100755 index 0000000..413ee98 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/hue_thumb.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/lastfm.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/lastfm.png Binary files differnew file mode 100755 index 0000000..623005a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/lastfm.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/mixcrate.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/mixcrate.png Binary files differnew file mode 100755 index 0000000..7e21115 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/mixcrate.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/muxtape-logo.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/muxtape-logo.png Binary files differnew file mode 100755 index 0000000..a29bfd7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/muxtape-logo.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-bw.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-bw.png Binary files differnew file mode 100755 index 0000000..e9dc665 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-bw.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-dark.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-dark.png Binary files differnew file mode 100755 index 0000000..549158d --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new-dark.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new.png Binary files differnew file mode 100755 index 0000000..62e05e4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/new.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/opera.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/opera.png Binary files differnew file mode 100755 index 0000000..9baf845 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/opera.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/picker_thumb.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/picker_thumb.png Binary files differnew file mode 100755 index 0000000..f757cc6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/picker_thumb.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-1.png Binary files differnew file mode 100755 index 0000000..b7a5f32 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-bar.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-bar.gif Binary files differnew file mode 100755 index 0000000..8e25d0e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider-bar.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider.png Binary files differnew file mode 100755 index 0000000..abcbf8b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/slider.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/soundcloud-thecloudplayer-logo.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/soundcloud-thecloudplayer-logo.png Binary files differnew file mode 100755 index 0000000..f88af99 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/soundcloud-thecloudplayer-logo.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/speaker.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/speaker.png Binary files differnew file mode 100755 index 0000000..9197793 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/speaker.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/wedge.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/wedge.png Binary files differnew file mode 100755 index 0000000..b55dd08 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_image/wedge.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/1hz-10khz-sweep.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/1hz-10khz-sweep.mp3 Binary files differnew file mode 100755 index 0000000..226ac1e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/1hz-10khz-sweep.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/440hz.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/440hz.mp3 Binary files differnew file mode 100755 index 0000000..e2dd5e0 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/440hz.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/880hz.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/880hz.mp3 Binary files differnew file mode 100755 index 0000000..756e8d9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/880hz.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background0.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background0.mp3 Binary files differnew file mode 100755 index 0000000..3816dd7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background0.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background1.mp3 Binary files differnew file mode 100755 index 0000000..9e9c638 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background2.mp3 Binary files differnew file mode 100755 index 0000000..ec251cf --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/background2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/bass.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/bass.mp3 Binary files differnew file mode 100755 index 0000000..adc281f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/bass.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-0.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-0.mp3 Binary files differnew file mode 100755 index 0000000..243c3e5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-0.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-1.mp3 Binary files differnew file mode 100755 index 0000000..a2833fd --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/button-1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-high.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-high.mp3 Binary files differnew file mode 100755 index 0000000..afb09d7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-high.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-low.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-low.mp3 Binary files differnew file mode 100755 index 0000000..9cbe8fe --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/click-low.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/coins.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/coins.mp3 Binary files differnew file mode 100755 index 0000000..f0c2401 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/coins.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/fancy-beer-bottle-pop.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/fancy-beer-bottle-pop.mp3 Binary files differnew file mode 100755 index 0000000..4498874 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/fancy-beer-bottle-pop.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mak.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mak.mp3 Binary files differnew file mode 100755 index 0000000..9bc9af3 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mak.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover.mp3 Binary files differnew file mode 100755 index 0000000..9e9a4f4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover2.mp3 Binary files differnew file mode 100755 index 0000000..9273f99 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover3.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover3.mp3 Binary files differnew file mode 100755 index 0000000..93d04be --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/mouseover3.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/select.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/select.mp3 Binary files differnew file mode 100755 index 0000000..9f9c711 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/select.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/sine, square, sawtooth, rando.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/sine, square, sawtooth, rando.mp3 Binary files differnew file mode 100755 index 0000000..a649164 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/_mp3/sine, square, sawtooth, rando.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/css/animation.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/css/animation.css new file mode 100755 index 0000000..380a671 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/css/animation.css @@ -0,0 +1,74 @@ +body {
+ font-size:75%;
+}
+
+h1, h2, h3 {
+ font:normal 3em "Helvetica Neue Light","Helvetica Neue",helvetica,georgia,"times new roman","Arial Rounded MT Bold",verdana,tahoma,arial,"sans serif";
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h1, h2, h3 {
+ padding-bottom:1px;
+ margin-bottom:0.25em;
+}
+
+h1 {
+ margin-top:0px;
+ margin-bottom:0px;
+ background-color:#666;
+ color:#ccc;
+ margin-left:-5px;
+ padding-left:5px;
+ padding-right:5px;
+ padding-bottom:5px;
+}
+
+h1,
+h1 a {
+ color:#fff;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+h2 {
+ font-size:2em;
+ margin-top:1em;
+ background-color:#aaa;
+ color:#fff;
+ padding:5px;
+ margin-left:-5px;
+ min-width:23em;
+}
+
+h3 {
+ font-size:1.65em;
+ margin-top:0.5em;
+ margin-bottom:0.25em;
+ color:#333;
+ min-width:28em;
+}
+
+h3 a {
+ font-size:small;
+}
+
+h4 {
+ color:#444;
+}
+p {
+ font:normal 1em/2em verdana,tahoma,arial,"sans serif";
+}
+
+.balls img {
+ position:absolute;
+ width:12px;
+ height:12px;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/image/ball.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/image/ball.gif Binary files differnew file mode 100755 index 0000000..0f13534 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/image/ball.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/index.html new file mode 100755 index 0000000..7d010a8 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/index.html @@ -0,0 +1,46 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<link rel="stylesheet" href="../template/template.css" media="screen" />
+<link rel="stylesheet" href="css/animation.css" media="screen" />
+<script type="text/javascript" src="../../script/soundmanager2-nodebug-jsmin.js"></script>
+<script type="text/javascript" src="script/animation.js"></script>
+</head>
+<body>
+
+<div style="margin-right:43em">
+
+<h1>Interval-based animation (with sound)</h1>
+
+<p>
+ Click + drag for fun.
+</p>
+
+<h2>Speeding Up ExternalInterface: Keep .swf in view</h2>
+
+<p>SoundManager 2 now incorporates a "high performance" mode, which has been shown to noticeably improve timing and frequency of flash callbacks. This is important for timing, reducing delay between a JS call and the sound being played, etc.</p>
+
+<p>To reduce audio delay and timing issues from slow JS/Flash communication, SM2 will try to ensure that the flash movie is visible on screen at all times. If hidden or otherwise off-screen, Flash will be given lower priority and thus JS/flash "lag" (ie., delay) will be introduced when trying to play audio "in sync."</p>
+
+<p>Generally, positioning the flash movie using position:fixed and bottom/left or bottom/right 0px is the less-intrusive option.</p>
+
+<p style="margin:0px;padding:0px">
+ <input id="useMouse" name="usemouse" value="usemouse" type="checkbox"> Throw from mouse
+</p>
+<p style="margin:0px;padding:0px">
+ <button id="b-start" onclick="startAnimation()" disabled="disabled">Start</button>
+ <button id="b-stop" onclick="stopAnimation()" disabled="disabled">Stop</button>
+</p>
+
+
+<p>Sound source: <a href="http://freesound.iua.upf.edu/samplesViewSingle.php?id=19987">"Acclivity"</a>, Free Sound Project</p>
+
+</div>
+
+<div id="ball-container" class="balls">
+ <img src="image/ball.gif" alt="" />
+</div>
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/script/animation.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/script/animation.js new file mode 100755 index 0000000..f167761 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-1/script/animation.js @@ -0,0 +1,189 @@ +var balls = [];
+var canvasX = 0;
+var canvasY = 0;
+var timer = null;
+var m_lastX = 0;
+var m_lastY = 0;
+var M_SPACE = 24;
+var B_VMIN = 5;
+var B_VMAX = 5;
+var B_WIDTH = 13;
+var B_HEIGHT = 13;
+var useMouse = null;
+var ballSound = null;
+var ballPopSound = null;
+
+function rnd(n) {
+ return Math.random()*n;
+}
+
+function rndI(n) {
+ return parseInt(rnd(n));
+}
+
+function createBall(oParent) {
+ oParent.appendChild(balls[0].cloneNode(true));
+ initBall(balls[balls.length-1],balls.length);
+}
+
+function createBallAtMouse(e) {
+ e = e?e:event;
+ createBall(document.getElementById('ball-container'));
+ with (balls[balls.length-1]) {
+ _x = e.clientX;
+ _y = e.clientY;
+ if (useMouse.checked != false) {
+ _vX = (m_lastX-e.clientX)*-0.7;
+ _vY = (m_lastY-e.clientY)*-0.7;
+ } else {
+ _vX = 0;
+ _vY = 0;
+ }
+ }
+ moveBall(balls[balls.length-1]);
+}
+
+function initBall(oBall,i) {
+ oBall._id = 'ball'+i;
+ oBall._active = true;
+ oBall._x = rnd(canvasX);
+ oBall._y = rnd(canvasY);
+ oBall._vX = B_VMIN+rnd(B_VMAX)*(Math.random()>0.5?1:-1);
+ oBall._vY = B_VMIN+rnd(B_VMAX);
+ oBall.style.display = 'block';
+}
+
+function moveBall(oBall) {
+ oBall._x += oBall._vX;
+ oBall._y += (oBall._vY++); // gravity!
+ var bounce = false;
+ if ((oBall._vX>0 && oBall._x+oBall._vX+B_WIDTH>canvasX) || (oBall._vX<0 && oBall._x+oBall._vX<0)) {
+ oBall._vX *= -1;
+ bounce = true;
+ }
+ if ((oBall._vY>0 && oBall._y+oBall._vY+B_HEIGHT>canvasY) || (oBall._vY<0 && oBall._y+oBall._vY<0)) {
+ // bounce on Y axis - with resistance on both axes
+ if (oBall._vY>0) oBall._y = canvasY-B_HEIGHT; // bounce exactly from bottom
+ oBall._vY *= -(oBall._vY>1?0.6:1);
+ bounce = true;
+ if (Math.abs(oBall._vX)>0.5) {
+ oBall._vX *= 0.85;
+ } else {
+ oBall._vX = 0;
+ }
+ if (Math.abs(oBall._vY)<=3 && Math.abs(oBall._vX==0)) {
+ oBall._active = false;
+ bounce = false;
+ ballPopSound.play();
+ oBall.style.display = 'none';
+ }
+ }
+ oBall.style.left = oBall._x+'px';
+ oBall.style.top = oBall._y+'px';
+ if (bounce) ballSound.play({pan:getPan(oBall._x,canvasX)});
+}
+
+function getPan(x,canvasX) {
+ var pos = x/canvasX;
+ var pan = null;
+ if (pos<=0.4) {
+ pan = Math.floor(-100+(pos/0.4*100));
+ } else if (pos>0.4 && pos<=0.5) {
+ pan = 0;
+ } else {
+ pan = Math.floor(pos*100);
+ }
+ return pan;
+}
+
+function animateStuff() {
+ for (var i=balls.length; i--;) {
+ if (balls[i]._active) moveBall(balls[i]);
+ }
+}
+
+function startAnimation() {
+ if (!timer) timer = setInterval(animateStuff,20);
+ document.getElementById('b-start').disabled = true;
+ document.getElementById('b-stop').disabled = false;
+}
+
+function stopAnimation() {
+ if (!timer) return false;
+ clearInterval(timer);
+ timer = null;
+ document.getElementById('b-start').disabled = false;
+ document.getElementById('b-stop').disabled = true;
+}
+
+function mouseDown(e) {
+ e = e?e:event;
+ m_lastX = e.clientX;
+ m_lastY = e.clientY;
+ document.onmousemove = mouseMove;
+ document.onmouseup = mouseUp;
+ return false;
+}
+
+function mouseMove(e) {
+ e = e?e:event;
+ if (Math.abs(e.clientX-m_lastX)>M_SPACE || Math.abs(e.clientY-m_lastY)>M_SPACE) {
+ createBallAtMouse(e);
+ m_lastX = e.clientX;
+ m_lastY = e.clientY;
+ }
+ return false;
+}
+
+function mouseUp() {
+ document.onmousemove = null;
+ document.onmouseup = null;
+}
+
+function init() {
+ ballSound = soundManager.createSound({
+ id: 'ballSound',
+ url: '../animation/audio/fingerplop.mp3',
+ volume: 50,
+ multiShot: true,
+ autoLoad: true
+ });
+ ballPopSound = soundManager.createSound({
+ id: 'ballPopSound',
+ url: '../animation/audio/fingerplop2.mp3',
+ volume: 50,
+ multiShot: true,
+ autoLoad: true
+ });
+ balls = document.getElementById('ball-container').getElementsByTagName('img');
+ for (var i=balls.length; i--;) {
+ initBall(balls[i],i);
+ }
+ useMouse = document.getElementById('useMouse');
+ useMouse.checked = true;
+ getWindowCoords();
+ startAnimation();
+ document.onmousedown = mouseDown;
+}
+
+// I know this is kinda broken in Opera.
+getWindowCoords = (navigator.userAgent.toLowerCase().indexOf('opera')>0||navigator.appVersion.toLowerCase().indexOf('safari')!=-1)?function() {
+ canvasX = window.innerWidth;
+ canvasY = window.innerHeight;
+}:function() {
+ canvasX = document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth;
+ canvasY = document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight;
+}
+
+window.onresize = getWindowCoords;
+
+soundManager.flashVersion = 9;
+soundManager.url = '../../swf/';
+soundManager.useHighPerformance = true;
+soundManager.debugMode = false; // disable debug mode
+soundManager.defaultOptions.multiShot = true;
+
+soundManager.onload = function() {
+ // soundManager is ready to use (create sounds and so on)
+ init();
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-land.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-land.png Binary files differnew file mode 100755 index 0000000..e87b2d7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-land.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-sky.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-sky.png Binary files differnew file mode 100755 index 0000000..f05abde --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/bg-sky.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-10.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-10.cur Binary files differnew file mode 100755 index 0000000..1f78e9e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-10.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-11.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-11.cur Binary files differnew file mode 100755 index 0000000..c559d34 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-11.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-3.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-3.cur Binary files differnew file mode 100755 index 0000000..5864f78 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-3.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-4.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-4.cur Binary files differnew file mode 100755 index 0000000..668fba6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-4.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-5.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-5.cur Binary files differnew file mode 100755 index 0000000..54de2c9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-5.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-6.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-6.cur Binary files differnew file mode 100755 index 0000000..d6c536f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-6.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-7.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-7.cur Binary files differnew file mode 100755 index 0000000..779af62 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-7.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-8.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-8.cur Binary files differnew file mode 100755 index 0000000..07c406e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-8.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-9.cur b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-9.cur Binary files differnew file mode 100755 index 0000000..98bf364 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-9.cur diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-shadow.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-shadow.png Binary files differnew file mode 100755 index 0000000..f200f35 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/cursor-shadow.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/dot.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/dot.png Binary files differnew file mode 100755 index 0000000..8d5592b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/dot.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/index.html new file mode 100755 index 0000000..1d2201c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2a/index.html @@ -0,0 +1,360 @@ +<html>
+<head>
+<title>SoundManager Demo</title> +<meta name="robots" content="noindex" />
+<style type="text/css">
+
+html, body {
+ margin:0px;
+ padding:0px;
+}
+
+body {
+ color:#fff;
+ font-size:75%;
+ text-shadow:0 0 0 #fff; /* Safari nonsense */
+ font-family:verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:lighter 3em "Helvetica Neue Light","Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+
+h1 {
+ margin-top:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h2 {
+ font-size:2em;
+ margin-top:0px;
+ color:#fff;
+}
+
+h2 span {
+ text-indent:1em;
+ font-family:verdana,tahoma,arial;
+ font-size:small;
+}
+
+p {
+ position:absolute;
+ left:1em;
+ bottom:0px;
+ font-size:x-small;
+ opacity:0.5;
+}
+
+#instructions {
+ position:absolute;
+ left:1em;
+ top:0px;
+}
+
+#canvas {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ overflow:hidden;
+}
+
+#horizon {
+ position:relative;
+ height:50%;
+ background:transparent url(bg-sky.png) 0px 0px repeat-x;
+}
+
+#land {
+ position:absolute;
+ bottom:0px;
+ left:0px;
+ width:100%;
+ height:50%;
+ border-top:1px solid #339933;
+ margin-bottom:0px;
+ background:#669966 url(bg-land.png) 0px 0px repeat-x;
+}
+
+#content {
+ position:relative;
+ border-top:1px solid #ccc;
+}
+
+#cursor-shade {
+ position:absolute;
+ left:-100px;
+ top:-100px;
+ margin:0px 0px 0px -2px;
+ width:20px;
+ height:24px;
+ opacity:0.75;
+}
+
+#sun {
+ position:absolute;
+ top:50%;
+ width:100%;
+ height:128px;
+ margin-top:-66px;
+ background:transparent url(sun-test.png) 50% 0px no-repeat;
+ display:none;
+}
+
+.dot {
+ position:absolute;
+ width:32px;
+ height:32px;
+}
+
+#overlay {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ cursor:url(cursor-11.cur),default;
+}
+
+</style>
+<script type="text/javascript" src="../../script/soundmanager2-nodebug-jsmin.js"></script>
+<script type="text/javascript">
+
+function _id(sID) {return document.getElementById(sID);}
+
+function Cursor() {
+ var self = this;
+ this.o = null;
+ this.offX = 20;
+ this.offY = 40;
+ this.screenX = null;
+ this.screenY = null;
+ this.screenXHalf = null;
+ this.screenYHalf = null;
+ this.lastCursor = null;
+ this.cursorRange = 9;
+ this.oDots = _id('dots');
+
+ this.painting = 0;
+
+ this.sounds = [];
+ this.soundIndex = 0;
+ this.soundTimer = null;
+
+ this.oDot = document.createElement('img');
+ this.oDot.className = 'dot';
+ this.oDot.src = 'dot.png';
+
+ this.refreshCoords = function() {
+ self.screenX = (window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth);
+ self.screenY = (window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight);
+ self.screenXHalf = parseInt(self.screenX/2);
+ self.screenYHalf = parseInt(self.screenY/2);
+ }
+
+ this.mousedown = function(e) {
+ self.painting = true;
+ return false;
+ }
+
+ this.mouseup = function(e) {
+ self.painting = false;
+ return false;
+ }
+
+ this.mousemove = function(e) {
+ var evt = e?e:event;
+ var x = evt.clientX;
+ var y = evt.clientY;
+ var xHalf = self.screenXHalf;
+ var yHalf = self.screenYHalf;
+ var scaleX = (x>xHalf?(x-xHalf)/xHalf:-((xHalf-x)/xHalf));
+ var scaleY = (y>yHalf?(y-yHalf)/yHalf:0);
+ var xScale = (self.offX*scaleY)*scaleX;
+ var yScale = self.offY*scaleY;
+ var cursor = parseInt(self.cursorRange*scaleY);
+ if (cursor != self.lastCursor) {
+ var curString = 'cursor-'+(Math.min(11,cursor+3))+'.cur';
+ document.documentElement.style.cursor = 'url("'+curString+'"),default';
+ _id('overlay').style.cursor = 'url("'+curString+'"),default';
+ self.lastCursor = cursor;
+ }
+ var xDiff = (x+xScale);
+ self.o.style.left = (xDiff)+'px';
+ self.o.style.top = (y+yScale)+'px';
+ self.o.style.width = ((20*scaleY)+'px');
+ self.o.style.height = ((24*scaleY)+'px');
+ self.o.style.opacity = Math.max((scaleY-0.33),0.33);
+ if (self.painting && scaleY>0) self.paint(x,y,scaleX,scaleY);
+ return false;
+ }
+
+ this.paint = function(x,y,scaleX,scaleY) {
+ var oD = self.oDot.cloneNode(false);
+ var size = 32*scaleY;
+ oD.style.left = (x-size)+'px';
+ oD.style.top = (y-size)+'px';
+ oD.style.width = (size+'px');
+ oD.style.height = (size+'px');
+ oD.style.opacity = Math.min(1,Math.max(scaleY*1.5,0.1));
+ self.oDots.appendChild(oD);
+
+ // var sID = self.sounds[0].sID;
+ if (!self.soundTimer) {
+ // self.soundTimer = window.setTimeout(function(){soundManager.play(sID,{volume:100*scaleY,pan:100*scaleX});self.soundTimer=null;},20);
+ self.sounds[Math.random()>0.5?1:0].play({pan:100*scaleX,volume:100*scaleY});
+ }
+ // if (self.soundIndex++>=self.sounds.length-1) self.soundIndex = 0;
+ }
+
+ this.createSounds = function() {
+ self.sounds[0] = soundManager.createSound('paint','../animation/audio/fingerplop.mp3');
+ self.sounds[1] = soundManager.createSound('paint2','../animation/audio/fingerplop2.mp3');
+ }
+
+ this.createSounds();
+
+ this.o = _id('cursor-shade');
+ this.refreshCoords();
+
+ window.onresize = this.refreshCoords;
+ _id('overlay').onmousedown = this.mousedown;
+ _id('overlay').onmouseup = this.mouseup;
+ document.onmousemove = this.mousemove;
+
+}
+
+var cursor = null;
+
+var sounds = [];
+
+soundManager.allowPolling = false;
+
+function doEvil() {
+
+// HIGHLY EXPERIMENTAL (and dangerous) optimation testing - attempting to override Flash's ExternalInterface JS. :D - The below may have only been relevant to Flash 8.
+
+if (typeof window.__flash__argumentsToXML !== 'undefined') {
+
+ window.__flash__argumentsToXML = function(obj,index) {
+ var s = ["<arguments>"];
+ for (var i=index, j=obj.length; i<j; i++) {
+ s[s.length] = __flash__toXML(obj[i]);
+ }
+ s[s.length] = "</arguments>";
+ // console.log('argumentsToXML: '+s.length+' items');
+ return s.join('');
+ }
+
+ window.__flash__arrayToXML = function(obj) {
+ var s = ["<array>"];
+ for (var i=0,j=obj.length; i<j; i++) {
+ s[s.length] = "<property id=\"" + i + "\">" + __flash__toXML(obj[i]) + "</property>";
+ }
+ s[s.length] = "</array>";
+ // console.log('arrayToXML: '+s.length+' items');
+ return s.join('');
+ }
+
+ window.__flash__escapeXML = function(s) {
+ // console.log('escapeXML'); // '+s.length);
+ return s; // s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
+ }
+
+ window.__flash__objectToXML = function(obj) {
+ console.log('objectToXML');
+ var s = ["<object>"];
+ for (var prop in obj) {
+ s[s.length] = "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
+ }
+ s[s.length] = "</object>";
+ return s.join('');
+ }
+
+ window.__flash__toXML = function(value) {
+ // console.log('toXML');
+ var type = typeof(value);
+ if (type == "string") {
+ return "<string>" + __flash__escapeXML(value) + "</string>";
+ } else if (type == "undefined") {
+ return "<undefined/>";
+ } else if (type == "number") {
+ return "<number>" + value + "</number>";
+ } else if (value == null) {
+ return "<null/>";
+ } else if (type == "boolean") {
+ return value ? "<true/>" : "<false/>";
+ } else if (value instanceof Date) {
+ return "<date>" + value.getTime() + "</date>";
+ } else if (value instanceof Array) {
+ return __flash__arrayToXML(value);
+ } else if (type == "object") {
+ return __flash__objectToXML(value);
+ } else {
+ return "<null/>"; //???
+ }
+ }
+
+ // this one non-IE, only?
+
+ if (!navigator.userAgent.match(/MSIE/i)) {
+ window.__flash__request.prototype = function(name) {
+ return "<invoke name=\"" + name + "\" returntype=\"javascript\">" + __flash__argumentstoXML(arguments, 1) + "</invoke>";
+ }
+ }
+}
+
+}
+
+function doInit() {
+ doEvil(); // NOTE: highly experimental, only a performance test; probably doesn't apply to Flash 9, and/or does nothing, or bad things.
+ cursor = new Cursor();
+}
+
+soundManager.flashVersion = 9;
+soundManager.url = '../../swf/';
+soundManager.useHighPerformance = true;
+soundManager.wmode = 'transparent';
+soundManager.debugMode = false;
+soundManager.onload = doInit;
+
+</script>
+</head>
+
+<body>
+
+<div>
+
+<div id="canvas">
+
+ <div id="horizon"></div>
+ <div id="land">
+ <div id="content">
+ </div>
+ </div>
+
+ <div id="sun"></div>
+ <div id="dots"></div>
+ <img id="cursor-shade" src="cursor-shadow.png" alt="" />
+
+</div>
+
+<div id="instructions">
+ <h1>SoundManager 2: JS/DOM + Sound Demo</h1>
+ <h2>Heavy DOM manipulation + Javascript Sound <span>(see code for experimental ideas)</code></h2>
+</div>
+
+<p>Click and drag to draw.. Noisily.</p>
+<div id="overlay"></div>
+
+</div>
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/bonk.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/bonk.mp3 Binary files differnew file mode 100755 index 0000000..2bce046 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/bonk.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop.mp3 Binary files differnew file mode 100755 index 0000000..663155e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop2.mp3 Binary files differnew file mode 100755 index 0000000..10f8bb2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/audio/fingerplop2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/css/animation.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/css/animation.css new file mode 100755 index 0000000..2764bc2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/css/animation.css @@ -0,0 +1,36 @@ +body {
+ font-size:75%;
+ background:#667788;
+ color:#fff;
+ text-shadow:0 0 0 #fff; /* Safari nonsense */
+}
+
+h1, h2, h3 {
+ font:normal 3em "Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+
+h1 {
+ margin-top:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h2 {
+ font-size:2em;
+ margin-top:0.25em;
+}
+
+p {
+ font:normal 1em verdana,tahoma,arial,"sans serif";
+}
+
+.point {
+ position:absolute;
+ width:32px;
+ height:32px;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/ball.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/ball.gif Binary files differnew file mode 100755 index 0000000..0f13534 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/ball.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/point.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/point.png Binary files differnew file mode 100755 index 0000000..043a88f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/image/point.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/index.html new file mode 100755 index 0000000..e51dcf5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/index.html @@ -0,0 +1,21 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<link rel="stylesheet" href="css/animation.css" media="screen" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/animation.js"></script>
+</head>
+<body>
+
+<div>
+
+ <h1>SoundManager 2 demo: A Noisy Page</h1>
+ <h2>Example of sound tied to javascript/DOM event handlers</h2>
+
+ <p>Click and drag for fun.</p>
+
+</div>
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/script/animation.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/script/animation.js new file mode 100755 index 0000000..61d2382 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation-2b/script/animation.js @@ -0,0 +1,94 @@ +soundManager.flashVersion = 9;
+soundManager.url = '../../swf/';
+soundManager.useHighPerformance = true;
+soundManager.wmode = 'transparent';
+soundManager.debugMode = false;
+
+var points = [];
+var o = null;
+var lastX = 0;
+var lastY = 0;
+var threshhold = 4;
+var threshMax = 32;
+var noise = null;
+var screenX = 0;
+
+function doPaint(e) {
+ var x = (e||event).clientX;
+ var y = (e||event).clientY;
+ var diff = Math.max(Math.abs(x-lastX),Math.abs(y-lastY));
+ if (diff>threshhold) {
+ lastX = x;
+ lastY = y;
+ points.push(new Point(x,y,Math.min(diff/(32),3)));
+ }
+ return false;
+}
+
+function stopPaint() {
+ document.onmousemove = null;
+ document.onmouseup = null;
+ // soundManager.play('up');
+}
+
+function startPaint(e) {
+ // soundManager.play('down');
+ document.onmousemove = doPaint;
+ document.onmouseup = stopPaint;
+ lastX = (e||event).clientX;
+ lastY = (e||event).clientY;
+ screenX = (window.innerWidth?window.innerWidth:document.documentElement.clientWidth||document.body.clientWidth);
+ e?e.stopPropagation():event.returnValue = false;
+ return false;
+}
+
+function initPoints() {
+ o = document.createElement('img');
+ o.src = 'image/point.png';
+ o.className = 'point';
+ document.onmousedown = startPaint;
+ document.onmouseup = stopPaint;
+}
+
+function Point(x,y,scale) {
+ var self = this;
+ this.data = {
+ x: x,
+ y: y,
+ scale: scale,
+ scalePX: parseInt(32*scale)
+ }
+ this.o = o.cloneNode(false);
+ this.o.style.left = (x-(this.data.scalePX/2))+'px';
+ this.o.style.top = (y-(this.data.scalePX/2))+'px';
+ this.o.style.width = this.o.style.height = this.data.scalePX+'px';
+ var screenX2 = parseInt(screenX/2);
+ noise.play({volume:parseInt(Math.min(1,scale/3)*100),pan:(x<screenX2?(screenX2-x)/screenX2*-100:(x-screenX2)/screenX2*100)});
+ document.body.appendChild(this.o);
+}
+
+soundManager.onload = function() {
+ noise = soundManager.createSound({
+ id:'noise',
+ url:'../animation/audio/fingerplop.mp3',
+ multiShot: true,
+ autoLoad: true
+ });
+ soundManager.createSound({
+ id:'down',
+ url:'../_mp3/click-low.mp3',
+ multiShot: true,
+ autoLoad: true
+ });
+ soundManager.createSound({
+ id:'up',
+ url:'../_mp3/click-high.mp3',
+ multiShot: true,
+ autoLoad: true
+ });
+ initPoints();
+}
+
+soundManager.onerror = function() {
+ alert('d\'oh, something didn\'t work - SM2 failed to start.');
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/bonk.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/bonk.mp3 Binary files differnew file mode 100755 index 0000000..2bce046 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/bonk.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop.mp3 Binary files differnew file mode 100755 index 0000000..0f956ee --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop2.mp3 Binary files differnew file mode 100755 index 0000000..fab2070 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/audio/fingerplop2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/index.html new file mode 100755 index 0000000..4290634 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/animation/index.html @@ -0,0 +1,55 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Animation + Sound Demos</title> +<meta name="robots" content="noindex" />
+<link rel="stylesheet" href="../index.css" media="screen" />
+</head>
+<body>
+
+<div style="margin:1em">
+
+<h1>Javascript Animation + Sound Demos using <a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a></h1>
+
+<ol>
+ <li><a href="../animation-1/">Interval-based animation (with sound)</a></li>
+ <li><a href="../christmas-lights/">Smashable Christmas Lights</a></li>
+ <li><a href="../animation-2a/">JS-DOM "painting" + Sound, V1</a></li>
+ <li><a href="../animation-2b/">JS-DOM "painting" + Sound, V2</a></li>
+</ol>
+
+<p>External demo: <a href="http://www.schillmania.com/content/demos/yui-sm2/noisy-events/">A Noisy DOM</a> - part of a Yahoo! User Interface blog post, <a href="http://www.yuiblog.com/blog/2009/06/30/yui-soundmanager/">Enhancing YUI-based Apps with Audio</a>.</p>
+
+<script type="text/javascript">
+function fixLinks() {
+ if (document.location.protocol.match(/http/i)) {
+ return false;
+ }
+ // presumably offline - add index.html to local links, so offline browsing is seamless
+ var l = document.getElementsByTagName('a');
+ var s = null;
+ var tmp = null;
+ var cn = null;
+ for (var i=l.length; i--;) {
+ s = l[i].href.toString();
+ cn = l[i].className;
+ if (!s.match(/http/i) && !cn.match(/norewrite/i) && (s.match(/doc/i) || s.match(/demo/i) || s.match(/../))) {
+ // yep, local.
+ tmp = Math.max(s.lastIndexOf('?'),-1);
+ tmp = Math.max(s.lastIndexOf('#'),tmp);
+ tmp = Math.max(s.lastIndexOf('/')+1,tmp);
+ // console.log(s+' '+s.lastIndexOf('?')+', '+s.lastIndexOf('#')+', '+s.lastIndexOf('/')+' = '+tmp);
+ if (tmp == -1) {
+ tmp = s.length;
+ }
+ if (!s.match(/\.html/i)) {
+ l[i].setAttribute('href',s.substr(0,tmp)+'index.html'+s.substr(tmp));
+ }
+ }
+ }
+}
+fixLinks();
+</script>
+
+</div> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/api/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/api/index.html new file mode 100755 index 0000000..8ccd5b9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/api/index.html @@ -0,0 +1,676 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Basic API Demo, Examples</title> +<meta name="robots" content="noindex" />
+<meta name="author" content="Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="keywords" content="javascript sound library api" />
+<meta name="description" content="API demo and code examples for SoundManager 2, Javascript Sound method calls and functions etc." />
+<link rel="stylesheet" href="../index.css" media="screen" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<style type="text/css">
+
+h1 {
+ padding-top:0.2em;
+ padding-bottom:0.1em;
+ border-bottom:4px solid #000;
+ letter-spacing:-0.03em;
+}
+
+h2 {
+ margin-top:1em;
+ padding-bottom:0.1em;
+ border-bottom:2px solid #000;
+}
+
+pre,
+code,
+.code,
+dt,
+#soundmanager-debug {
+ color:#336699;
+ line-height:1.5em;
+}
+
+p {
+ line-height:1.5em;
+ margin-bottom:1em;
+}
+
+#soundmanager-debug {
+ position:fixed;
+ _position:absolute; /* IE <7 */
+ bottom:1em;
+ right:1em;
+ width:38em;
+ height:30em;
+ overflow:auto;
+ padding:0px;
+ margin:1em;
+ font-family:monaco,"VT-100",terminal,"lucida console",courier,system;
+ opacity:0.9;
+ color:#333;
+ border:1px solid #ccddee;
+ -moz-border-radius:3px;
+ -khtml-border-radius:3px;
+ -webkit-border-radius:3px;
+ background:#f3f9ff;
+}
+
+/*
+#soundmanager-debug code {
+ font-size:1.1em;
+ *font-size:1em;
+}
+*/
+
+#soundmanager-debug div {
+ font-size:x-small;
+ padding:0.2em;
+ margin:0px;
+}
+
+</style>
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript">
+
+// flash version URL switch (for this demo page)
+var winLoc = window.location.toString();
+if (winLoc.match(/flash9/i)) {
+ soundManager.flashVersion = 9;
+ if (winLoc.match(/highperformance/i)) {
+ soundManager.useHighPerformance = true;
+ soundManager.useFastPolling = true;
+ }
+} else if (winLoc.match(/flash8/i)) {
+ soundManager.flashVersion = 8;
+}
+
+soundManager.useFlashBlock = true;
+soundManager.url = '../../swf/'; // path to SoundManager2 SWF files (note trailing slash)
+soundManager.debugMode = true;
+soundManager.consoleOnly = false;
+
+soundManager.onready(function(oStatus) {
+ if (!oStatus.success) {
+ return false;
+ }
+ // soundManager is initialised, ready to use. Create a sound for this demo page.
+
+ if (soundManager.flashVersion > 8) {
+ t = window.setInterval(checkRAM,500);
+ document.getElementById('flash-ram-use').style.display = 'inline';
+ checkRAM();
+ }
+
+ soundManager.createSound({
+ id: 'aDrumSound',
+ url: '../mpc/audio/AMB_SN13.mp3'
+ });
+
+ soundManager.createSound({
+ id: 'aCymbalSound',
+ url: '../mpc/audio/SPLASH_1.mp3',
+ autoLoad: true
+ });
+
+ soundManager.createSound({
+ id: 'chinaCymbal',
+ url: '../mpc/audio/CHINA_1.mp3',
+ autoLoad: true
+ });
+
+ soundManager.createSound({
+ id: 's440hz',
+ url: '../_mp3/440hz.mp3',
+ autoLoad: true,
+ volume:50
+ });
+
+});
+
+function checkRAM() {
+ if (soundManager.supported()) {
+ var ram = (soundManager.getMemoryUse()/1024/1024).toFixed(2);
+ if (!isNaN(ram)) {
+ document.getElementById('flash-ram-use').innerHTML = ram+' MB';
+ } else {
+ document.getElementById('flash-ram-use').style.display = 'none';
+ }
+ }
+}
+
+var t = null;
+
+function doEval(sHTML) {
+ var html = sHTML.replace(/\<(span|code)\>/gi,'');
+ html = html.replace(/\<[\/](span|code)\>/gi,'');
+ html = html.replace(/>/gi,'>');
+ eval(html);
+ return false;
+}
+
+function getRandomMP3URL() {
+ return 'http://freshly-ground.com/data/audio/mpc/20060826%20-%20Armstrong.mp3?rnd='+parseInt(Math.random()*1048576);
+}
+
+</script>
+</head>
+
+<body>
+
+<div id="flash9" style="padding-left:1em;margin-right:38em">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" style="color:#000;text-decoration:none">SoundManager 2</a> / API Demo and Code Examples</h1>
+
+ <p class="note">You can run the API demos with <a href="#sm2-usehtml5audio=1" onclick="window.location.replace(this.href);window.location.reload()">HTML5</a> enabled, <a href="#flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (API default), <a href="#flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal) or <a href="#flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance + fastPolling</a> modes (higher JS callback frequency).</p>
+
+ <p>Wondering where to start? This page has inline executable code examples using the SoundManager 2 API.</p>
+
+ <p>If you're wondering <em>"How to include SM2 in my page?"</em>, the <a href="../template/" title="SoundManager 2 bare-bones template" onclick="if (!document.domain) this.href=this.href+'index.html'">basic template</a> will get you started.</p>
+
+ <div id="sm2-container">
+ <!-- flash is appended here -->
+ </div>
+
+ <h2>The basics (old-skool style): onload() + onerror()</h2>
+
+ <p>Once you have SM2 included in your page, you merely need to hook into its <code>onload()</code>/<code>onerror()</code> events:</p>
+
+<pre class="block"><code>soundManager.onload = function() {
+ <span><span>// soundManager is ready to use.
+ // createSound() / play() etc. can now be called</span>
+</span>}
+soundManager.onerror = function() {
+ <span><span>// Oh no! No sound support.
+ // Maybe configure your app to ignore sound calls.
+ // (SM2 calls will silently return false after this point.)</span>
+</span>}
+</code></pre>
+
+ <h2>The modern method: Adding "onready" listeners</h2>
+
+ <p>You can register listeners by passing a function to <code>onready()</code>, and it will be called when SoundManager has finished starting up:</p>
+
+<pre class="block"><code>soundManager.onready(function() {<span>
+ if (soundManager.supported()) {
+ <span>// createSound() / play() etc. can now be called</span>
+ } else {
+ <span>// uh-oh, SM2 failed to start - error, unsupported etc.</span>
+ }
+</span>});
+</code></pre>
+
+ <p>An optional status object is actually passed to your onready() listener, which you can use instead of checking <code>soundManager.supported()</code>:</p>
+
+<pre class="block"><code>soundManager.onready(function(oStatus) {
+ <span><span>// oStatus: object containing "success" parameter</span>
+ if (oStatus.success) {
+ <span>// createSound() / play() etc. can now be called</span>
+ } else {
+ <span>// uh-oh, SM2 failed to start - error, unsupported etc.</span>
+ }
+</span>});
+</code></pre>
+
+<p>SoundManager first processes the <code>onready</code> queue in the order items were added, and then fires <code>soundManager.onload()</code> or <code>onerror()</code>. If you call <code>onready()</code> after SM2 has loaded, your callback will be fired immediately.</p>
+
+ <h2>A note about initialization</h2>
+
+ <p class="compact">Keep in mind SoundManager's core methods (createSound, etc.) will not be available until soundManager.onload() fires. The initialization time for SM2 can vary across browsers/platforms, and should effectively be assumed to be "asynchronous." Because of this, it is recommended you write your code to handle soundManager.onload() being called either before or after window.onload().</p>
+ <p class="compact">If you wish to have SM2 always wait for window.onload() before calling soundManager.onload()/onerror(), you can apply the following:</p>
+<pre>soundManager.waitForWindowLoad = true;</pre>
+
+ <h2>Debug Output, disabling and minified versions</h2>
+ <p class="compact">SoundManager 2 has debug mode enabled by default and will write to agents supporting <em>console.log</em>-style debugging, and/or a custom <div> element in the absence of a console.</p>
+ <p>To disable debug output, set <code>soundManager.debugMode = false;</code></p>
+ <p>Alternately, you may use the no-debug, minified version of the SM2 javascript library (which has internal debug code removed, and will silently return false.)</p>
+
+ <h2>Demo 1a: Create + play (simple method)</h2>
+<pre>soundManager.play('<span>mySound0</span>','<span>../mpc/audio/AMB_SN_5.mp3</span>');</pre>
+ <button onclick="soundManager._writeDebug('Demo 1a',1);soundManager.play('mySound0','../mpc/audio/AMB_SN_5.mp3')">Do this</button>
+ <p>Creates and plays a sound with ID "mySound0", at the specified URL. The sound can then be referenced by that ID later, eg. soundManager.play('mySound0');</p>
+ <p>Note that this method is only provided for convenience, and allows only ID and URL as parameters. If you want to specify other options (volume, loop, event handlers), you must use the object literal syntax as given below.</p>
+
+ <h2>Demo 1b: Create + play (better method)</h2>
+
+<pre class="block"><code>soundManager.createSound({
+ id:'<span>mySound1</span>',
+ url:'<span>../mpc/audio/CHINA_1.mp3</span>'
+});
+soundManager.play('<span>mySound1</span>');</code></pre>
+ <button onclick="soundManager._writeDebug('Demo 1b',1);soundManager.createSound({id:'mySound1',url:'../mpc/audio/CHINA_1.mp3'});soundManager.play('mySound1')">Do this</button>
+ <p>Creates, then plays a sound. This object literal method allows for other parameters to be used (see demo 2)</p>
+
+ <h3>Variant: Use object returned from createSound() (best method)</h3>
+
+<pre class="block"><code>var aSoundObject = soundManager.createSound({
+ id:'<span>mySound2</span>',
+ url:'<span>../mpc/audio/CHINA_1.mp3</span>'
+});
+aSoundObject.play();</code></pre>
+ <button onclick="soundManager._writeDebug('Demo 1b variant',1);var aSoundObject = soundManager.createSound({id:'mySound2',url:'../mpc/audio/CHINA_1.mp3'});aSoundObject.play()">Do this</button>
+ <p>Creates, then plays a sound. This object literal method allows for other parameters to be used (see demo 2)</p>
+
+ <h2>Demo 2: Create with onfinish event handler + play with volume argument</h2>
+<pre id="demo2" class="block"><code>var demo2Sound = soundManager.createSound({
+ id:'<span>mySound4</span>',
+ url:'<span>../mpc/audio/CHINA_1.mp3</span>',
+ onfinish:function() {
+ soundManager._writeDebug(this.sID+'<span> finished playing</span>');
+ }
+});
+demo2Sound.play({volume:50});
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo2').innerHTML)">Do this</button>
+ <p>(creates, then plays a new sound - a function is called when the sound finishes playing)</p>
+
+ <h2>Demo 3: Play a pre-existing sound</h2>
+<pre>soundManager.play('<span>aDrumSound</span>');</pre>
+ <button onclick="soundManager._writeDebug('Demo 3',1);soundManager.play('aDrumSound')">Do this</button>
+ <p>This plays an existing sound which was created by soundManager.onload() (for reference, view source of this page.)</p>
+
+ <h2>Demo 4a: Play a sequence of sounds via "onfinish", with multiShot*</h2>
+<pre>soundManager.play('<span>aDrumSound</span>',{multiShotEvents:true,onfinish:function(){soundManager.play('<span>aCymbalSound</span>');}})</pre>
+<p>Differently formatted:</p>
+<pre class="block"><code>soundManager.play('<span>aDrumSound</span>',{
+ multiShotEvents: true, <span>// allow onfinish() to fire for each "shot" (default: only fire onfinish() for last shot.)</span>
+ onfinish:function() {
+ soundManager.play('<span>aCymbalSound</span>');
+ }
+});</code></pre>
+ <button onclick="soundManager._writeDebug('Demo 4a',1);soundManager.play('aDrumSound',{multiShotEvents:true,onfinish:function(){soundManager.play('aCymbalSound');}})">Do this</button>
+ <p>This will play an existing sound (created in-page), and uses the "onfinish" handler to make a call to play a second, pre-existing sound.</p>
+ <p>Also note that the button can be clicked multiple times, and the sound will be "layered" as multiShot is enabled for both of these sounds when using Flash 9. An onfinish event will also fire as each sound finishes.</p>
+ <p><strong>Bug/behaviour note:</strong> Whenever "play" is called on a SMSound object, any parameters passed in will apply to all currently-playing instances of the sound if multiShot is allowed. For example, the onfinish handler from demo 4a will apply to demo 3 if 4a is started while 3 is still playing.</p>
+ <p class="note">* Multishot is Flash 9+ only.</p>
+
+ <h2>Demo 4b: Create and play a sequence of new sounds via "onfinish"</h2>
+<pre class="block"><code>soundManager.createSound({
+ id:'<span>aBassDrum</span>',
+ url:'<span>../mpc/audio/AMB_BD_1.mp3</span>',
+ multiShot:false,
+ onfinish:function() {
+ soundManager.play('<span>aRimSound</span>','<span>AMB_RIM1.mp3</span>');
+ }
+});
+soundManager.play('<span>aRimSound</span>');</code></pre>
+ <button onclick="soundManager._writeDebug('Demo 4b',1);soundManager.createSound({id:'aBassDrum',url:'../mpc/audio/AMB_BD_1.mp3',multiShot:false,onfinish:function(){soundManager.play('aRimSound','../mpc/audio/AMB_RIM1.mp3');}});soundManager.play('aBassDrum')">Do this</button>
+ <p>This will crate and play a new sound, using the "onfinish" handler to create and play a second, new sound.</p>
+ <p>It is recommended to create sound objects first, to simplify troubleshooting.</p>
+
+<h2 id="looping-conventional">Demo 4c: Looping a sound (conventional, onfinish()-based)</h2>
+<pre id="demo4c" class="block"><code>var s = soundManager.createSound({
+ id:'<span>hhCymbal</span>',
+ url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
+});
+
+s.play({
+ onfinish: function() {
+ this.play();
+ <span><span>// or, soundManager.play('<span>hhCymbal</span>');</span></span>
+ }
+});
+</code></pre>
+
+<button onclick="return doEval(document.getElementById('demo4c').innerHTML);return false">Do this</button> | <button onclick="soundManager.stop('hhCymbal')">make it stop!</button>
+<p>Note that there are issues with seamlessly-looping sounds, it is "close, but not perfect" with Flash 8/9 at this point.</p>
+
+<h2 id="looping">Demo 4d: Looping a sound ("loops" parameter method)</h2>
+<pre id="demo4d" class="block"><code>var s = soundManager.createSound({
+ id:'<span>hhCymbal</span>',
+ url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
+});
+
+s.play({
+ loops: 3
+});
+</code></pre>
+
+<button onclick="return doEval(document.getElementById('demo4d').innerHTML);return false">Do this</button> | <button onclick="soundManager.stop('hhCymbal')">make it stop!</button>
+<p>Looping is possible as shown above using Flash 9. <b>With flash 8, the sound must be preloaded before looping can begin</b> - eg. <code>autoLoad: true, onload: function() { this.play{loops:3} }</code>. For tighter looping, see See <a href="http://www.flickr.com/photos/schill/4499319436/" title="Seamless looping MP3 sounds in Flash">Seamless Looping MP3 in Flash</a> for further details.</p>
+
+
+<h2 id="onposition">Demo 4e: Sound timing notifications using onposition()</h2>
+<pre id="demo4e" class="block"><code>var s = soundManager.getSoundById('<span>aCymbalSound</span>'); <span><span>// existing sound object</span></span>
+
+<span><span>// register some listeners (only do this once, they will work for subsequent plays)</span></span>
+
+if (typeof addedListeners === '<span>undefined</span>') {
+ addedListeners = true;
+
+ s.onposition(<span>500</span>, function(eventPosition) { <span><span>// fire at 0.5 seconds</span></span>
+ soundManager._writeDebug(<span>'Sound '+this.sID+' has reached position '+eventPosition</span>);
+ });
+
+ s.onposition(<span>1000</span>, function(eventPosition) {<span><span>// fire at 1 second</span></span>
+ soundManager._writeDebug(<span>'Sound '+this.sID+' has reached position '+eventPosition</span>);
+ });
+}
+
+s.play({
+ whileplaying:function() {
+ <span><span>// demo only: show sound position while playing, for context</span></span>
+ soundManager._writeDebug('position = ' + this.position);
+ }
+});
+</code></pre>
+
+<button onclick="return doEval(document.getElementById('demo4e').innerHTML);return false">Do this</button>
+<p>onposition() allows you to add an event listener for a given time (in miliseconds, watching the position property); the event fires when that time has been reached while a sound is playing.</p>
+<p>Note that for multiShot cases, the listeners will only fire for the original (first) shot because its position is the only one that is tracked within Flash.</p>
+
+<h2>Demo 5a: Set sound parameters, then play</h2>
+<pre class="block"><code>var sound = soundManager.getSoundById('<span>chinaCymbal</span>'); <span><span>// predefined/preloaded sound</span></span>
+sound.setPosition(<span>500</span>); <span><span>// 500 msec into sound</span></span>
+sound.setPan(<span>-75</span>); <span><span>// 75% left pan</span></span>
+sound.play();
+</code></pre>
+<button onclick="soundManager._writeDebug('Demo 5',1);var sound=soundManager.getSoundById('chinaCymbal');sound.setPosition(500);sound.setPan(-75);sound.play()">Do this</button> | <button onclick="soundManager._writeDebug('Demo 5: sound from position:0',1);var sound=soundManager.getSoundById('chinaCymbal');sound.setPosition(0);sound.setPan(-75);sound.play()">Play from position:0</button>
+<p>This will set the position of an existing, pre-loaded sound, then play it.</p>
+
+<h3>Variant: play()</h3>
+<pre class="block"><code>var sound = soundManager.getSoundById('<span>chinaCymbal</span>');
+sound.play({position:<span>500</span>,pan:<span>-75</span>});
+</code></pre>
+<button onclick="soundManager._writeDebug('Demo 5 variant',1);var sound=soundManager.getSoundById('chinaCymbal');sound.play({position:500,pan:-75})">Do this</button> | <button onclick="soundManager._writeDebug('Demo 5: variant: sound from position:0',1);var sound = soundManager.getSoundById('chinaCymbal');sound.play({position:0,pan:-75})">Play from position:0</button>
+<p>Note that if planning to layer sounds with multiShot (Flash 9 only), this variant method will give best results as each new "channel" is started with parameters.</p>
+
+<h2>Demo 5b: Global sound muting</h2>
+<p>If not passed a sound ID, soundManager.mute() will mute all existing and newly-created sounds. soundManager.unmute() can also be passed a sound ID, and performs the inverse either on a single sound or all sounds.</p>
+<p>In this demo, all sounds are globally muted and unmuted a few times. Different parameters are used to help audibly separate the sounds.</p>
+<pre id="demo5b-1" class="block"><code>soundManager.mute(); <span><span>// mute all sounds</span></span>
+
+soundManager.createSound({
+ id: '<span>880hz</span>',
+ url: '<span>../_mp3/880hz.mp3</span>',
+ autoLoad:true,
+ onload: function() {
+ <span><span>// soundManager.mute(); // mute all sounds</span></span>
+ <span><span>// play (muted) cymbal sound..</span></span>
+ this.play({
+ volume:75, <span><span>// volume for when un-muted</span></span>
+ pan:-75, <span><span>// mostly on left channel</span></span>
+ <span><span>// .. and clean-up afterwards</span></span>
+ onfinish:function() {
+ this.destruct();
+ }
+ });
+
+ this.setVolume(25); <span><span>// new volume for when un-muted..</span></span>
+
+ soundManager.play('<span>s440hz</span>',{
+ pan:<span>75</span>,
+ onfinish:function() {
+ document.getElementById('<span>btn-d5b</span>').disabled = false;
+ }
+ });
+
+ <span><span>// once playing, toggle all sounds some more</span></span>
+ setTimeout(soundManager.unmute,500);
+ setTimeout(soundManager.mute,1000);
+ setTimeout(soundManager.unmute,1500);
+ setTimeout(soundManager.mute,2000);
+ setTimeout(soundManager.unmute,2500);
+ }
+});</code></pre>
+<button id="btn-d5b" onclick="this.disabled=true;return doEval(document.getElementById('demo5b-1').innerHTML)">Do this</button>
+<script type="text/javascript">document.getElementById('btn-d5b').disabled = false;</script>
+
+<h2>Demo 5c: Per-object sound muting</h2>
+<pre id="demo5c-1" class="block"><code>soundManager.createSound({
+ id: '<span>880hz</span>',
+ url: '<span>../_mp3/880hz.mp3</span>',
+ autoLoad:true,
+ onload: function() {
+ soundManager.mute('<span>880hz</span>'); <span><span>// mute this - alternately, this.mute() would work here</span></span>
+ soundManager.play('<span>s440hz</span>',{ <span><span>// play another sound to demo muting</span></span>
+ onfinish: function() {
+ document.getElementById('<span>btn-d5c</span>').disabled = false;
+ }
+ });
+
+ <span><span>// play 880hz (muted)..</span></span>
+ this.play({
+ volume:75,
+ <span><span>// .. and clean-up afterwards</span></span>
+ onfinish:function() {
+ this.destruct();
+ }
+ });
+
+ this.setVolume(50); <span><span>// still muted, however..</span></span>
+
+ <span><span>// mute/unmute china cymbal some more</span></span>
+ <span><span>// mute sound calls: soundManager.mute('<span>880hz</span>'), or soundManager.getSoundById('<span>880hz</span>').mute();</span></span>
+ setTimeout(this.unmute,250);
+ setTimeout(this.mute,500);
+ setTimeout(this.unmute,750);
+ setTimeout(this.mute,1000);
+ setTimeout(this.unmute,1250);
+ }
+});</code></pre>
+<button id="btn-d5c" onclick="this.disabled=true;return doEval(document.getElementById('demo5c-1').innerHTML)">Do this</button>
+<script type="text/javascript">document.getElementById('btn-d5c').disabled = false;</script>
+
+<h2>Demo 6: Create, play, unload and destroy a sound</h2>
+<pre id="demo6" class="block"><code>var foo = soundManager.createSound({
+ id: '<span>fooSound</span>',
+ url: '<span>../mpc/audio/AMB_BD_1.mp3</span>'
+});
+
+<span><span>// soundManager.play('<span>fooSound</span>');
+
+// (Some time later on...)
+// soundManager.unload('<span>fooSound</span>'); - release the loaded MP3
+// soundManager.destroySound('<span>fooSound</span>'); - destroy the sound, freeing up memory etc. Also calls unload().
+
+// Alternate (demo) approach, call methods directly on sound object itself:</span></span>
+foo.play({
+ onfinish:function() {
+ <span><span>// once sound has loaded and played, unload and destroy it.</span></span>
+ this.destruct(); <span><span>// will also try to unload before destroying.</span></span>
+ }
+});</code></pre>
+<button onclick="return doEval(document.getElementById('demo6').innerHTML)">Do this</button>
+
+
+<h2>Demo 7: Create, manually pre-load and finally play a sound</h2>
+<pre id="demo7" class="block"><code>var preload = soundManager.createSound({
+ id: '<span>preloadSound</span>',
+ url: '<span>../mpc/audio/AMB_HHOP.mp3</span>'
+});
+
+preload.load(); <span><span>// load the sound ahead of time</span></span>
+setTimeout(preload.play,1500); <span><span>// and start playing it 1.5 seconds from now</span></span>
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo7').innerHTML)">Do this</button>
+
+<h2>Demo 8: Create and play an invalid sound (404)</h2>
+<pre id="demo8" class="block"><code>var bad = soundManager.createSound({
+ id:'<span>badSound</span>',
+ url:'<span>badurl.mp3</span>',
+ onload: function(bSuccess) {
+ soundManager._writeDebug('<span>sound </span>'+(bSuccess?'<span>loaded!</span>':'<span>did NOT load.</span>'));
+ }
+});
+bad.play();
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo8').innerHTML)">Do this</button>
+
+<h2>Demo 9: Create and destroy a sound at once (unusual crash testcase)</h2>
+<pre id="demo9" class="block"><code>var s = soundManager.createSound({
+ id:'<span>testcase</span>',
+ url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
+});
+s.play();
+s.destruct();
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo9').innerHTML)">Do this</button>
+
+<h2>Demo 10: Sound timing (position accuracy testcase)</h2>
+<p>The Flash 9 version seems to resume the sound 1 msec earlier than it should, perhaps related to the timing/delay issue most noticeable on Windows.</p>
+<pre id="demo10" class="block"><code>var count = 0;
+var pos = -1;
+var s = soundManager.createSound({
+ id: '<span>s</span>',
+ url: '<span>../mpc/audio/CHINA_1.mp3</span>',
+ whileplaying: function() {
+ if (count == 0) {
+ if (this.position > 1000) {
+ this.pause();
+ pos = this.position;
+ count++;
+ this.resume();
+ }
+ } else if (count == 1) {
+ soundManager._writeDebug('<span>old position: </span>' + pos);
+ soundManager._writeDebug('<span>new position: </span>' + this.position);
+ <span><span>// See that this.position is less than pos!</span></span>
+ count++;
+ }
+ },
+ onfinish: function() {
+ this.destruct();
+ }
+});
+s.play();</code></pre>
+<button onclick="return doEval(document.getElementById('demo10').innerHTML)">Do this</button>
+
+<h2>Demo 11: Inline whileplaying() event assignment</h2>
+<p class="in">Note that when using the Flash 9 version of SM2 with Flash 9 and 10 plugins, flash/OS-related delay conditions may result in the <code>position</code> property being less than the <code>duration</code> property, even by the end of the sound.</p>
+<pre id="demo11" class="block"><code>var foo = soundManager.createSound({
+ id: '<span>bar</span>',
+ url: '<span>../mpc/audio/CRASH_1.mp3</span>'
+});
+foo.options.whileplaying = function() {
+ soundManager._writeDebug('<span>whileplaying(): </span>'+this.position+'<span> / </span>'+this.duration);
+}
+foo.play();
+
+<span><span>// note: assign .options before calling .play(), as that "bakes" the options into a play instance object.
+// the below "late" event handler assignment will have no effect on the already-playing instance.</span></span>
+foo.options.onfinish = function() { soundManager._writeDebug(this.sID+'<span> stopped.</span>'); }
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo11').innerHTML)">Do this</button>
+
+<h2>Demo 12: 48 KHz MP3 sampling rate playback issue workaround</h2>
+<p>To work around a known "chipmunk" <a href="http://bugs.adobe.com/jira/browse/FP-862">sampling rate issue with 48 KHz MP3s</a> in Flash, one can apparently load a sound using Flash 9 with stream = false, and then call play() once the sound has fully-loaded. Exactly why this works is not known.</p>
+<pre id="demo12" class="block"><code>var fortyeight = soundManager.createSound({
+ id: '<span>s-48khz</span>',
+ url: '<span>http://freshly-ground.com/data/audio/48khz-test.mp3</span>'
+});
+
+if (!fortyeight.loaded) {
+ <span><span>// first time loading/playing</span></span>
+ fortyeight.load({
+ stream: false,
+ onload: function() {
+ <span><span>// sound has fully-loaded</span></span>
+ this.play();
+ }
+ });
+} else {
+ <span><span>// sound has already loaded</span></span>
+ fortyeight.play();
+}
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo12').innerHTML)">Do this</button> <button onclick="soundManager.stop('s-48khz')">Make it stop!</button>
+
+<h2>Demo 13: onbeforefinish() testcase</h2>
+<p class="in">This event fires when the sound's position property is equal to or less than <code>onbeforefinishtime</code> msec from the end of the sound, as defined by <code>duration</code>. If unspecified, a default value is used (eg. 5000 msec.)</p>
+<pre id="demo13" class="block"><code>var d13 = soundManager.createSound({
+ id: '<span>demo13</span>',
+ url: '<span>../mpc/audio/CRASH_1.mp3</span>',
+ onbeforefinish: function() {
+ soundManager._writeDebug(this.sID+'<span>.onbeforefinish(): </span>'+this.position+'<span> of </span>'+this.duration);
+ },
+ onbeforefinishtime: 1000
+});
+d13.play();
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo13').innerHTML)">Do this</button>
+
+<h2>Demo 14: autoLoad:true + play() testcase</h2>
+<p>Bug testcase (Flash 8 version-specific): creating a sound with autoLoad:true and immediately calling play() does not work.</p>
+<pre id="demo14" class="block"><code>var autoLoadTest = soundManager.createSound({
+ id: '<span>autoLoadTest</span>',
+ url: getRandomMP3URL(),
+ onload: function() {
+ soundManager._writeDebug(this.sID+'<span> loaded.</span>');
+ },
+ onplay: function() {
+ soundManager._writeDebug('<span>Starting sound: </span>'+this.sID);
+ },
+ autoPlay: false,
+ autoLoad: true,
+ stream: true
+ });
+ <span><span>// autoLoadTest.play(); // sound will not start</span></span>
+ setTimeout(autoLoadTest.play,1000); <span><span>// may work with a delay?</span></span>
+</code></pre>
+<p>Under Flash 8, this case does not work as expected. Even with the delay, the sound does not begin playing as soon as expected - sometimes it fires after the sound loads, in fact. For this reason, avoid using <code class="in">autoLoad:true</code> if you intend to play the sound shortly after creating it when using Flash 8.</p>
+<button onclick="return doEval(document.getElementById('demo14').innerHTML)">Do this</button> <button onclick="soundManager.stop('autoLoadTest')">Make it stop!</button>
+
+<h2>Demo 15: autoPlay + onfinish() testcase</h2>
+<p>Bug testcase (Flash 8 version-specific): onfinish() does not fire with autoPlay:true</p>
+<pre id="demo15" class="block"><code>var sound = soundManager.createSound({
+ id: '<span>demo15</span>',
+ url: '<span>../mpc/audio/AMB_SN13.mp3</span>',
+ onfinish: function() {
+ soundManager._writeDebug(this.sID+'<span> finished (now destroying)</span>');
+ <span><span>// destroy this sound</span></span>
+ this.destruct();
+ },
+ autoPlay: true,
+ multiShot: false
+});
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo15').innerHTML)">Do this</button>
+
+<h2>Demo 16: onstop() -> unload() testcase</h2>
+<p>Bug testcase: unload() from onstop() does not work</p>
+<pre id="demo16" class="block"><code>var sound16 = soundManager.createSound({
+ id: '<span>demo16</span>',
+ url: getRandomMP3URL(),
+ onstop: function() {
+ soundManager.unload(this.sID);
+ },
+ onload: function() {
+ soundManager._writeDebug('<span>loaded</span>');
+ }
+});
+sound16.play();
+setTimeout(sound16.stop,1500);
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo16').innerHTML)">Do this</button>
+
+<h2>Demo 17: Buffering event handler/property example (Flash 9 only)</h2>
+<p>Reporting the isBuffering property of a SMSound object</p>
+<pre id="demo17" class="block"><code>if (soundManager.flashVersion != 8) {
+ var sound17 = soundManager.createSound({
+ id: '<span>demo17</span>',
+ url: getRandomMP3URL(),
+ onbufferchange: function() {
+ soundManager._writeDebug('<span>Buffering </span>'+(this.isBuffering?'<span>started</span>':'<span>stopped</span>')+'<span>.</span>');
+ },
+ onload: function() {
+ soundManager._writeDebug(this.sID+'<span> loaded.</span>');
+ }
+ });
+ sound17.play();
+}
+</code></pre>
+<button onclick="return doEval(document.getElementById('demo17').innerHTML)">Do this</button> <button onclick="soundManager.stop('demo17')">Make it stop!</button>
+
+
+<span id="flash-ram-use" title="Flash plugin RAM use (across this browser)" style="position:fixed;_position:absolute;top:0.5em;right:0.5em;background:#666;color:#fff;font-weight:bold;padding:0.3em 0.4em;cursor:pointer;cursor:hand;display:none" onclick="this.style.display='none';window.clearTimeout(t)">N/A</span>
+
+</div>
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights-home.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights-home.js new file mode 100755 index 0000000..2ebc4fa --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights-home.js @@ -0,0 +1,510 @@ +// Christmas Light Smashfest
+// Adapted from XLSF 2007 as originally used on http://schillmania.com/?theme=2007&christmas=1
+
+var Y = {
+ // shortcuts
+ A: YAHOO.util.Anim,
+ D: YAHOO.util.Dom,
+ E: YAHOO.util.Event,
+ UE: YAHOO.util.Easing,
+ CA: YAHOO.util.ColorAnim,
+ BG: YAHOO.util.BgPosAnim
+}
+
+function XLSF(oTarget,urlBase,lightClass) {
+ var writeDebug = soundManager._wD;
+ writeDebug('XLSF()');
+ var IS_MOON_COMPUTER = false;
+ var isIE = navigator.userAgent.match(/msie/i);
+ var self = this;
+ var xlsf = self;
+ var animDuration = 1;
+ this.oFrag = document.createDocumentFragment();
+ this.oTarget = (oTarget?oTarget:document.documentElement);
+ this.oExplosionBox = document.createElement('div');
+ this.oExplosionBox.className = 'xlsf-fragment-box';
+ this.oExplosionFrag = document.createElement('div');
+ this.oExplosionFrag.className = 'xlsf-fragment';
+ this.lights = [];
+ this.lightClasses = {
+ pico: 32,
+ tiny: 50,
+ small: 64,
+ medium: 72,
+ large: 96
+ }
+ this.urlBase = (typeof urlBase == 'undefined' || !urlBase?'demo/christmas-lights/':urlBase);
+
+ if (window.innerWidth || window.innerHeight) {
+ var screenX = window.innerWidth; // -(!isIE?24:2);
+ var screenY = window.innerHeight;
+ } else {
+ var screenX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth); // -(!isIE?8:0);
+ var screenY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
+ }
+
+ this.lightClass = (screenX>1280?'small':'pico'); // kind of light to show (32px to 96px square)
+
+ if (typeof lightClass != 'undefined') {
+ // hack: override
+ this.lightClass = lightClass;
+ }
+
+ if (window.location.href.match(/size=/i)) {
+ this.lightClass = window.location.href.substr(window.location.href.indexOf('size=')+5);
+ }
+
+ this.lightXY = this.lightClasses[this.lightClass]; // shortcut to w/h
+
+ this.lightGroups = {
+ left: [],
+ top: [],
+ right: [],
+ bottom: []
+ }
+ this.lightSmashCounter = 0;
+ this.lightIndex = 0;
+ this.lightInterval = 250;
+ this.timer = null;
+ this.bgBaseX = 0;
+ this.bgBaseY = 0;
+ this.soundIDs = 0;
+ this.soundPan = {
+ panValue: 75,
+ left: 0,
+ mid: 481,
+ right: 962
+ }
+
+ this.cover = document.createElement('div');
+ this.cover.className = 'xlsf-cover';
+ document.documentElement.appendChild(this.cover);
+
+ this.initSounds = function() {
+ for (var i=0; i<6; i++) {
+ soundManager.createSound({
+ id: 'smash'+i,
+ url: xlsf.urlBase+'sound/glass'+i+'.mp3',
+ autoLoad: true,
+ multiShot: true,
+ volume:50
+ });
+ }
+ self.initSounds = function() {} // safety net
+ }
+
+ this.appendLights = function() {
+ writeDebug('xlsf.appendLights()');
+ self.oTarget.appendChild(self.oFrag);
+ self.oFrag = document.createDocumentFragment();
+ }
+
+ function ExplosionFragment(nType,sClass,x,y,vX,vY) {
+ var self = this;
+ this.o = xlsf.oExplosionFrag.cloneNode(true);
+ this.nType = nType;
+ this.sClass = sClass;
+ this.x = x;
+ this.y = y;
+ this.w = 50;
+ this.h = 50;
+ this.bgBaseX = 0;
+ this.bgBaseY = this.h*this.nType;
+ this.vX = vX*(1.5+Math.random());
+ this.vY = vY*(1.5+Math.random());
+ this.oA = null;
+ this.oA2 = null;
+ this.burstPhase = 3; // starting background offset point
+ this.burstPhases = 4; // 1+offset (ignore large size)
+ this.o.style.backgroundPosition = ((this.w*-this.burstPhase)+'px '+(this.h*-nType)+'px');
+
+ // boundary checks
+ if (self.sClass == 'left') {
+ this.vX = Math.abs(this.vX);
+ } else if (self.sClass == 'right') {
+ this.vX = Math.abs(this.vX)*-1;
+ }
+
+ this.burstTween = function() {
+ // determine frame to show
+ var phase = 1+Math.floor((this.currentFrame/this.totalFrames)*self.burstPhases);
+ if (phase != self.burstPhase) {
+ self.burstPhase = phase;
+ self.o.style.backgroundPosition = ((self.w*-self.burstPhase)+'px '+(self.h*-nType)+'px');
+ }
+ }
+
+ this.burst = function() {
+ self.oA = new Y.A(self.o,{marginLeft:{to:(self.vX*8)},marginTop:{to:(self.vY*8)}},animDuration,Y.UE.easeOutStrong);
+ self.oA.onTween.subscribe(self.burstTween);
+ // self.oA.onComplete.subscribe(self.hide);
+ self.oA.animate();
+ }
+
+ this.hide = function() {
+ if (!isIE) self.o.style.opacity = 0;
+ }
+
+ this.reset = function() {
+ self.o.style.left = '0px';
+ self.o.style.top = '0px';
+ self.o.style.marginLeft = '0px';
+ self.o.style.marginTop = '0px';
+ if (!isIE) self.o.style.opacity = 1;
+ }
+
+ this.animate = function() {
+ self.reset();
+ self.burst();
+ }
+
+ }
+
+ function Explosion(nType,sClass,x,y) {
+ var oParent = this;
+ var self = this;
+ this.o = null;
+ this.nType = nType;
+ this.sClass = sClass;
+ this.x = x;
+ this.y = y;
+ this.boxVX = 0;
+ this.boxVY = 0;
+ this.o = xlsf.oExplosionBox.cloneNode(true);
+ this.o.style.left = x+'px';
+ this.o.style.top = y+'px';
+ // this.oFrag = document.createDocumentFragment();
+ this.fragments = [];
+
+ var mX = x;
+ var mY = y;
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,-5,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,0,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,-5));
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,-5,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,0,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,0));
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,5));
+
+ this.init = function() {
+ for (var i=self.fragments.length; i--;) {
+ self.o.appendChild(self.fragments[i].o);
+ }
+ // xlsf.oTarget.appendChild(self.o);
+ // self.oFrag = document.createDocumentFragment();
+ if (!IS_MOON_COMPUTER) {
+ // faster rendering, particles get cropped
+ xlsf.oFrag.appendChild(self.o);
+ } else {
+ // slower rendering, can overlay body
+ // _id('header').appendChild(self.o);
+ // (document.documentElement?document.documentElement:document.body).appendChild(o);
+ xlsf.oFrag.appendChild(self.o);
+ }
+ }
+
+ this.reset = function() {
+ // clean-up
+ // self.o.parentNode.removeChild(self.o);
+ self.o.style.display = 'none';
+ self.o.style.marginLeft = '0px';
+ self.o.style.marginTop = '0px';
+ self.o.style.left = self.x+'px';
+ self.o.style.top = self.y+'px';
+ if (!isIE) self.o.style.opacity = 1;
+ for (var i=self.fragments.length; i--;) {
+ self.fragments[i].reset();
+ }
+ }
+
+ this.trigger = function(boxVX,boxVY) {
+ self.o.style.display = 'block';
+ self.boxVX = boxVX;
+ self.boxVY = boxVY;
+ // boundary checks
+ if (self.sClass == 'right') {
+ self.boxVX = Math.abs(self.boxVX)*-1;
+ } else if (self.sClass == 'left') {
+ self.boxVX = Math.abs(self.boxVX);
+ }
+ for (var i=self.fragments.length; i--;) {
+ self.fragments[i].animate();
+ }
+ if (!isIE && (IS_MOON_COMPUTER)) {
+ var oAExplode = new Y.A(self.o,{marginLeft:{to:100*self.boxVX},marginTop:{to:150*self.boxVY},opacity:{to:0.01}},animDuration,Y.UE.easeInStrong);
+ } else {
+ // even IE 7 sucks w/alpha-transparent PNG + CSS opacity. Boo urns.
+ var oAExplode = new Y.A(self.o,{marginLeft:{to:100*self.boxVX},marginTop:{to:150*self.boxVY}},animDuration,Y.UE.easeInStrong);
+ }
+ oAExplode.onComplete.subscribe(self.reset);
+ oAExplode.animate();
+ // setTimeout(self.reset,animDuration*1000*1.5);
+ }
+
+ this.init();
+
+ // this.trigger(); // boooom!
+
+ }
+
+ function Light(sSizeClass,sClass,nType,x,y) {
+ var self = this;
+ this.o = document.createElement('div');
+ this.sClass = sClass;
+ this.sSizeClass = sSizeClass;
+ this.nType = (nType||0);
+ this.useY = (sClass == 'left' || sClass == 'right');
+ this.state = null;
+ this.broken = 0;
+ this.w = xlsf.lightClasses[sSizeClass];
+ this.h = xlsf.lightClasses[sSizeClass];
+ this.x = x;
+ this.y = y;
+ this.bg = xlsf.urlBase+'image/bulbs-'+this.w+'x'+this.h+'-'+this.sClass+'.png';
+ this.o.style.width = this.w+'px';
+ this.o.style.height = this.h+'px';
+ this.o.style.background = 'url('+this.bg+') no-repeat 0px 0px';
+ this.bgBaseX = (self.useY?-self.w*this.nType:0);
+ this.bgBaseY = (!self.useY?-self.h*this.nType:0);
+ this.glassType = parseInt(Math.random()*6);
+ this.oExplosion = null;
+ this.soundID = 'smash'+this.glassType;
+ var panValue = xlsf.soundPan.panValue; // eg. +/- 80%
+ this.pan = parseInt(this.x<=xlsf.soundPan.mid?-panValue+((this.x/xlsf.soundPan.mid)*panValue):(this.x-xlsf.soundPan.mid)/(xlsf.soundPan.right-xlsf.soundPan.mid)*panValue);
+
+ this.initSound = function() {
+ }
+
+ this.setBGPos = function(x,y) {
+ self.o.style.backgroundPosition = ((self.bgBaseX+x)+'px '+(self.bgBaseY+y)+'px');
+ }
+
+ this.setLight = function(bOn) {
+ if (self.broken || self.state == bOn) return false;
+ if (!self.w || !self.h) self.getDimensions();
+ self.state = bOn;
+ if (self.useY) {
+ self.setBGPos(0,-this.h*(bOn?0:1));
+ } else {
+ self.setBGPos(-this.w*(bOn?0:1),0);
+ }
+ }
+
+ this.getDimensions = function() {
+ self.w = self.o.offsetWidth;
+ self.h = self.o.offsetHeight;
+ self.bgBaseX = (self.useY?-self.w*self.nType:0);
+ self.bgBaseY = (!self.useY?-self.h*self.nType:0);
+ }
+
+ this.on = function() {
+ self.setLight(1);
+ }
+
+ this.off = function() {
+ self.setLight(0);
+ }
+
+ this.flickr = function() {
+ self.setLight(Math.random()>=0.5?1:0);
+ }
+
+ this.toggle = function() {
+ self.setLight(!self.state?1:0);
+ }
+
+ this.explode = function(e) {
+ // self.oExplosion = new Explosion(self.nType,self.sClass,self.x,self.y);
+ self.oExplosion.trigger(0,1); // boooom!
+ }
+
+ this.smash = function(e) {
+ if (self.broken) return false;
+ self.broken = true;
+ if (soundManager && soundManager.supported()) {
+ soundManager.play(self.soundID,{pan:self.pan});
+ // soundManager.sounds[self.soundID].play({pan:self.pan});
+ // if (self.bonusSound != null) window.setTimeout(self.smashBonus,1000);
+ }
+ self.explode(e);
+ var rndFrame = 2; // +parseInt(Math.random()*3);
+ if (self.useY) {
+ self.setBGPos(0,self.h*-rndFrame);
+ } else {
+ self.setBGPos(self.w*-rndFrame,0);
+ }
+ xlsf.lightSmashCounter++;
+ }
+
+ this.smashBonus = function() {
+ // soundManager.play(self.bonusSounds[self.bonusSound],urlBase+'sound/'+self.bonusSounds[self.bonusSound]+'.mp3');
+ }
+
+ this.reset = function() {
+ if (!self.broken) return false;
+ self.broken = false;
+ self.state = null;
+ xlsf.lightSmashCounter--;
+ self.flickr();
+ }
+
+ this.init = function() {
+ self.o.className = 'xlsf-light '+this.sizeClass+' '+this.sClass;
+ self.o.style.left = self.x+'px';
+ self.o.style.top = self.y+'px';
+ self.o.style.width = self.w+'px';
+ self.o.style.height = self.h+'px';
+ self.o.onmouseover = self.smash;
+ self.o.onclick = self.smash;
+ self.flickr();
+ xlsf.oFrag.appendChild(self.o);
+ self.oExplosion = new Explosion(self.nType,self.sClass,self.x,self.y);
+ }
+
+ this.init();
+
+ } // Light()
+
+ this.createLight = function(sClass,nType,x,y) {
+ var oLight = new Light(self.lightClass,sClass,nType,x,y);
+ self.lightGroups[sClass].push(oLight);
+ self.lights.push(oLight);
+ return oLight;
+ }
+
+ this.rotateLights = function() {
+ self.lights[self.lightIndex==self.lights.length?self.lights.length-1:self.lightIndex].off();
+ self.lightIndex++;
+ if (self.lightIndex == self.lights.length) {
+ self.lightIndex = 0;
+ }
+ self.lights[self.lightIndex].on();
+ }
+
+ this.randomLights = function() {
+ self.lights[parseInt(Math.random()*self.lights.length)].toggle();
+ }
+
+
+ this.destroyLights = function() {
+ self.startSequence(self.destroyLight,20);
+ }
+
+ this.destroyLight = function() {
+ var groupSize = 2; // # to smash at a time
+ if (self.lightSmashCounter<self.lights.length) {
+ var limit = Math.min(self.lightSmashCounter+groupSize,self.lights.length);
+ for (var i=self.lightSmashCounter; i<limit; i++) {
+ self.lights[self.lightSmashCounter].smash();
+ }
+ } else {
+ self.stopSequence();
+ }
+
+ }
+
+ this.uberSmash = function() {
+ // make everything explode - including your CPU.
+ self.stopSequence();
+/*
+ for (var i=0; i<self.lights.length; i++) {
+ if (!self.lights[i].broken) {
+ setTimeout(self.lights[i].smash,parseInt(Math.random()*1000));
+ }
+ }
+*/
+
+ function getRandomLight() {
+ return parseInt(Math.random()*self.lights.length);
+ }
+
+ function smashItUp() {
+ var smashed = 0;
+ var rnd = getRandomLight();
+ if (self.lights[rnd].broken) {
+ for (var i=self.lights.length; i--;) {
+ if (self.lights[i].broken) {
+ smashed++;
+ }
+ }
+ if (smashed < self.lights.length-1) {
+ // missed - do it again
+ smashItUp();
+ } else {
+ // all are done
+ window.clearInterval(t);
+ }
+ } else {
+ // we've got a live one
+ self.lights[rnd].smash();
+ // do some more, too
+ for (var j=parseInt(Math.random()*8); j--;) {
+ self.lights[getRandomLight()].smash();
+ }
+ }
+ }
+ var t = window.setInterval(smashItUp,20);
+ }
+
+ this.smashGroup = function(oGroup) {
+ for (var i=oGroup.length; i--;) {
+ oGroup[i].smash();
+ }
+ }
+
+ this.startSequence = function(fSequence,nInterval) {
+ if (self.timer) self.stopSequence();
+ self.timer = window.setInterval(fSequence,(typeof nInterval != 'undefined'?nInterval:self.lightInterval));
+ }
+
+ this.stopSequence = function() {
+ if (self.timer) {
+ window.clearInterval(self.timer);
+ self.timer = null;
+ }
+ }
+
+ var i=0;
+ var j=0;
+
+ _id('lights').style.display = 'block';
+
+ // start lights to the right of <h1>
+ var offset = parseInt(document.getElementsByTagName('h1')[0].offsetWidth)+16;
+
+ var jMax = Math.floor((screenX-offset-16)/self.lightXY);
+ var iMax = Math.floor((screenY-offset-16)/self.lightXY);
+
+ for (j=0; j<jMax; j++) {
+ this.createLight('top',j%3,offset+j*self.lightXY,0);
+ // this.createLight('bottom',j%3,offset+j*self.lightXY,screenY-offset-offset+1);
+ }
+
+ if (typeof isFun != 'undefined') {
+ for (i=0; i<iMax; i++) {
+ this.createLight('left',i%3,0,offset+i*self.lightXY);
+ // this.createLight('right',i%3,screenX-offset-offset,offset+i*self.lightXY);
+ }
+ }
+
+ this.appendLights();
+
+ this.startSequence(self.randomLights);
+
+ // setTimeout(this.destroyLights,10000);
+ // setTimeout(this.uberSmash,10000);
+
+} // --- XLSF2007()
+
+var xlsf = null;
+
+function smashInit(urlBase,lightClass) {
+ xlsf = new XLSF(document.getElementById('lights'),urlBase,lightClass);
+ xlsf.initSounds();
+ // document.getElementById('loading').style.display = 'none';
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.css new file mode 100755 index 0000000..f857e60 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.css @@ -0,0 +1,111 @@ +/* XLSF 2007 */
+
+body {
+ background:#333 url(image/bg-strip-dark.png) 0px 0px;
+ font-family:lighter "Helvetica Neue Light","Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ font-size:75%;
+ color:#666;
+}
+
+h1, h1 a {
+ color:#999;
+ text-decoration:none;
+}
+
+h1 {
+ color:#999;
+ margin-bottom:0;
+ margin-left:-5px;
+ margin-top:0;
+ padding-left:5px;
+ padding-right:5px;
+}
+
+h1, h2, h3 {
+ clear:both;
+ float:left;
+ font-family:lighter "Helvetica Neue Light","Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ font-size:3em;
+ font-size-adjust:none;
+ margin-bottom:0.25em;
+ padding-bottom:1px;
+}
+
+h1, h2 {
+ letter-spacing:-1px;
+ margin-bottom:0;
+ margin-left:-5px;
+ margin-top:0;
+ padding-left:5px;
+ padding-right:5px;
+}
+
+a {
+ color:#6699cc;
+ padding:0px 2px;
+ text-decoration:none;
+}
+
+a:hover {
+ background:#6699cc;
+ color:#fff;
+}
+
+#lights {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ overflow:hidden;
+}
+
+.xlsf-light {
+ position:absolute;
+}
+
+body.fast .xlsf-light {
+ opacity:0.9;
+}
+
+.xlsf-fragment {
+ position:absolute;
+ background:transparent url(image/bulbs-50x50-fragments.png) no-repeat 0px 0px;
+ width:50px;
+ height:50px;
+}
+
+.xlsf-fragment-box {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:50px;
+ height:50px;
+ *width:100%;
+ *height:100%;
+ display:none;
+}
+
+.xlsf-cover {
+ position:fixed;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ background:#fff;
+ opacity:1;
+ z-index:999;
+ display:none;
+}
+
+/*
+.xlsf-light.bottom {
+ height:49px;
+ border-bottom:1px solid #006600;
+}
+
+.xlsf-light.top {
+ height:49px;
+ border-top:1px solid #009900;
+}
+*/
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.js new file mode 100755 index 0000000..9916d90 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/christmaslights.js @@ -0,0 +1,519 @@ +// Christmas Light Smashfest
+// Adapted from XLSF 2007 as originally used on http://schillmania.com/?theme=2007&christmas=1
+
+var Y = {
+ // shortcuts
+ A: YAHOO.util.Anim,
+ D: YAHOO.util.Dom,
+ E: YAHOO.util.Event,
+ UE: YAHOO.util.Easing,
+ CA: YAHOO.util.ColorAnim,
+ BG: YAHOO.util.BgPosAnim
+}
+
+function XLSF(oTarget) {
+ var writeDebug = soundManager._wD;
+ writeDebug('XLSF()');
+ var IS_MOON_COMPUTER = false;
+ var isIE = navigator.userAgent.match(/msie/i);
+ var self = this;
+ var xlsf = self;
+ var animDuration = 1;
+ this.oFrag = document.createDocumentFragment();
+ this.oTarget = (oTarget?oTarget:document.documentElement);
+ this.oExplosionBox = document.createElement('div');
+ this.oExplosionBox.className = 'xlsf-fragment-box';
+ this.oExplosionFrag = document.createElement('div');
+ this.oExplosionFrag.className = 'xlsf-fragment';
+ this.lights = [];
+ this.lightClasses = {
+ pico: 32,
+ tiny: 50,
+ small: 64,
+ medium: 72,
+ large: 96
+ }
+
+ this.lightClass = 'tiny'; // kind of light to show (32px to 96px square)
+
+ if (window.location.href.match(/size=/i)) {
+ this.lightClass = window.location.href.substr(window.location.href.indexOf('size=')+5);
+ }
+
+ this.lightXY = this.lightClasses[this.lightClass]; // shortcut to w/h
+
+ this.lightGroups = {
+ left: [],
+ top: [],
+ right: [],
+ bottom: []
+ }
+ this.lightSmashCounter = 0;
+ this.lightIndex = 0;
+ this.lightInterval = 250;
+ this.timer = null;
+ this.bgBaseX = 0;
+ this.bgBaseY = 0;
+ this.soundIDs = 0;
+ this.soundPan = {
+ panValue: 75,
+ left: 0,
+ mid: 481,
+ right: 962
+ }
+
+ // this.beavis = null;
+ this.cover = document.createElement('div');
+ this.cover.className = 'xlsf-cover';
+ document.documentElement.appendChild(this.cover);
+
+ this.initSounds = function() {
+ for (var i=0; i<6; i++) {
+ soundManager.createSound({
+ id: 'smash'+i,
+ url: 'sound/glass'+i+'.mp3',
+ autoLoad: true,
+ multiShot: true
+ });
+ }
+ /*
+ for (var i=self.lights.length; i--;) {
+ self.lights[i].initSound();
+ }
+ */
+ self.initSounds = function() {} // safety net
+ }
+
+ this.appendLights = function() {
+ writeDebug('xlsf.appendLights()');
+ self.oTarget.appendChild(self.oFrag);
+ self.oFrag = document.createDocumentFragment();
+ }
+
+ function ExplosionFragment(nType,sClass,x,y,vX,vY) {
+ var self = this;
+ this.o = xlsf.oExplosionFrag.cloneNode(true);
+ this.nType = nType;
+ this.sClass = sClass;
+ this.x = x;
+ this.y = y;
+ this.w = 50;
+ this.h = 50;
+ this.bgBaseX = 0;
+ this.bgBaseY = this.h*this.nType;
+ this.vX = vX*(1.5+Math.random());
+ this.vY = vY*(1.5+Math.random());
+ this.oA = null;
+ this.oA2 = null;
+ this.burstPhase = 1; // starting background offset point
+ this.burstPhases = 4; // 1+offset (ignore large size)
+ this.o.style.backgroundPosition = ((this.w*-this.burstPhase)+'px '+(this.h*-nType)+'px');
+
+ // boundary checks
+ if (self.sClass == 'left') {
+ this.vX = Math.abs(this.vX);
+ } else if (self.sClass == 'right') {
+ this.vX = Math.abs(this.vX)*-1;
+ }
+// */
+
+ this.burstTween = function() {
+ // determine frame to show
+ var phase = 1+Math.floor((this.currentFrame/this.totalFrames)*self.burstPhases);
+ if (phase != self.burstPhase) {
+ self.burstPhase = phase;
+ self.o.style.backgroundPosition = ((self.w*-self.burstPhase)+'px '+(self.h*-nType)+'px');
+ }
+ }
+
+ this.burst = function() {
+ self.oA = new Y.A(self.o,{marginLeft:{to:(self.vX*8)},marginTop:{to:(self.vY*8)}},animDuration,Y.UE.easeOutStrong);
+ self.oA.onTween.subscribe(self.burstTween);
+ // self.oA.onComplete.subscribe(self.hide);
+ self.oA.animate();
+ }
+
+ this.hide = function() {
+ if (!isIE) self.o.style.opacity = 0;
+ }
+
+ this.reset = function() {
+ self.o.style.left = '0px';
+ self.o.style.top = '0px';
+ self.o.style.marginLeft = '0px';
+ self.o.style.marginTop = '0px';
+ if (!isIE) self.o.style.opacity = 1;
+ }
+
+ this.animate = function() {
+ self.reset();
+ self.burst();
+ }
+
+ }
+
+ function Explosion(nType,sClass,x,y) {
+ var oParent = this;
+ var self = this;
+ this.o = null;
+ this.nType = nType;
+ this.sClass = sClass;
+ this.x = x;
+ this.y = y;
+ this.boxVX = 0;
+ this.boxVY = 0;
+ this.o = xlsf.oExplosionBox.cloneNode(true);
+ this.o.style.left = x+'px';
+ this.o.style.top = y+'px';
+ // this.oFrag = document.createDocumentFragment();
+ this.fragments = [];
+
+ var mX = x;
+ var mY = y;
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,-5,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,0,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,-5));
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,-5,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,0,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,0));
+
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,-5));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,0));
+ this.fragments.push(new ExplosionFragment(nType,sClass,mX,mY,5,5));
+
+ this.init = function() {
+ for (var i=self.fragments.length; i--;) {
+ self.o.appendChild(self.fragments[i].o);
+ }
+ // xlsf.oTarget.appendChild(self.o);
+ // self.oFrag = document.createDocumentFragment();
+ if (!IS_MOON_COMPUTER) {
+ // faster rendering, particles get cropped
+ xlsf.oFrag.appendChild(self.o);
+ } else {
+ // slower rendering, can overlay body
+ // _id('header').appendChild(self.o);
+ // (document.documentElement?document.documentElement:document.body).appendChild(o);
+ xlsf.oFrag.appendChild(self.o);
+ }
+ }
+
+ this.reset = function() {
+ // clean-up
+ // self.o.parentNode.removeChild(self.o);
+ self.o.style.display = 'none';
+ self.o.style.marginLeft = '0px';
+ self.o.style.marginTop = '0px';
+ self.o.style.left = self.x+'px';
+ self.o.style.top = self.y+'px';
+ if (!isIE) self.o.style.opacity = 1;
+ for (var i=self.fragments.length; i--;) {
+ self.fragments[i].reset();
+ }
+ }
+
+ this.trigger = function(boxVX,boxVY) {
+ self.o.style.display = 'block';
+ self.boxVX = boxVX;
+ self.boxVY = boxVY;
+ // boundary checks
+// /*
+ if (self.sClass == 'right') {
+ self.boxVX = Math.abs(self.boxVX)*-1;
+ } else if (self.sClass == 'left') {
+ self.boxVX = Math.abs(self.boxVX);
+ }
+// */
+ for (var i=self.fragments.length; i--;) {
+ self.fragments[i].animate();
+ }
+ if (!isIE && (IS_MOON_COMPUTER)) {
+ var oAExplode = new Y.A(self.o,{marginLeft:{to:100*self.boxVX},marginTop:{to:150*self.boxVY},opacity:{to:0.01}},animDuration,Y.UE.easeInStrong);
+ } else {
+ // even IE 7 sucks w/alpha-transparent PNG + CSS opacity. Boo urns.
+ var oAExplode = new Y.A(self.o,{marginLeft:{to:100*self.boxVX},marginTop:{to:150*self.boxVY}},animDuration,Y.UE.easeInStrong);
+ }
+ oAExplode.onComplete.subscribe(self.reset);
+ oAExplode.animate();
+ // setTimeout(self.reset,animDuration*1000*1.5);
+ }
+
+ this.init();
+
+ // this.trigger(); // boooom!
+
+ }
+
+ function Light(sSizeClass,sClass,nType,x,y) {
+ var self = this;
+ this.o = document.createElement('div');
+// this.o.src = 'image/empty.gif';
+ this.sClass = sClass;
+ this.sSizeClass = sSizeClass;
+ this.nType = (nType||0);
+ this.useY = (sClass == 'left' || sClass == 'right');
+ this.state = null;
+ this.broken = 0;
+ this.w = xlsf.lightClasses[sSizeClass];
+ this.h = xlsf.lightClasses[sSizeClass];
+ this.x = x;
+ this.y = y;
+ this.bg = 'image/bulbs-'+this.w+'x'+this.h+'-'+this.sClass+'.png';
+ this.o.style.width = this.w+'px';
+ this.o.style.height = this.h+'px';
+ this.o.style.background = 'url('+this.bg+') no-repeat 0px 0px';
+ this.bgBaseX = (self.useY?-self.w*this.nType:0);
+ this.bgBaseY = (!self.useY?-self.h*this.nType:0);
+ this.glassType = parseInt(Math.random()*6);
+ // this.bonusSounds = ['griffin-laugh','bblaff','bblaff2'];
+ // this.bonusSound = null;
+ this.oExplosion = null;
+ this.soundID = 'smash'+this.glassType;
+ var panValue = xlsf.soundPan.panValue; // eg. +/- 80%
+ this.pan = parseInt(this.x<=xlsf.soundPan.mid?-panValue+((this.x/xlsf.soundPan.mid)*panValue):(this.x-xlsf.soundPan.mid)/(xlsf.soundPan.right-xlsf.soundPan.mid)*panValue);
+
+ this.initSound = function() {
+ // soundManager.createSound({id:self.soundID,url:urlBase+'sound/glass'+this.glassType+'.mp3',autoLoad:true,pan:self.pan});
+ }
+
+ this.setBGPos = function(x,y) {
+ self.o.style.backgroundPosition = ((self.bgBaseX+x)+'px '+(self.bgBaseY+y)+'px');
+ }
+
+ this.setLight = function(bOn) {
+ if (self.broken || self.state == bOn) return false;
+ if (!self.w || !self.h) self.getDimensions();
+ self.state = bOn;
+ if (self.useY) {
+ self.setBGPos(0,-this.h*(bOn?0:1));
+ } else {
+ self.setBGPos(-this.w*(bOn?0:1),0);
+ }
+ }
+
+ this.getDimensions = function() {
+ self.w = self.o.offsetWidth;
+ self.h = self.o.offsetHeight;
+ self.bgBaseX = (self.useY?-self.w*self.nType:0);
+ self.bgBaseY = (!self.useY?-self.h*self.nType:0);
+ }
+
+ this.on = function() {
+ self.setLight(1);
+ }
+
+ this.off = function() {
+ self.setLight(0);
+ }
+
+ this.flickr = function() {
+ self.setLight(Math.random()>=0.5?1:0);
+ }
+
+ this.toggle = function() {
+ self.setLight(!self.state?1:0);
+ }
+
+ this.explode = function(e) {
+ // self.oExplosion = new Explosion(self.nType,self.sClass,self.x,self.y);
+ self.oExplosion.trigger(0,1); // boooom!
+ }
+
+ this.smash = function(e) {
+ if (self.broken) return false;
+ self.broken = true;
+ if (soundManager && soundManager.supported()) {
+ soundManager.play(self.soundID,{pan:self.pan});
+ // soundManager.sounds[self.soundID].play({pan:self.pan});
+ // if (self.bonusSound != null) window.setTimeout(self.smashBonus,1000);
+ }
+ self.explode(e);
+ var rndFrame = 2; // +parseInt(Math.random()*3);
+ if (self.useY) {
+ self.setBGPos(0,self.h*-rndFrame);
+ } else {
+ self.setBGPos(self.w*-rndFrame,0);
+ }
+ xlsf.lightSmashCounter++;
+ // xlsf.doNukeCheck();
+ // window.setTimeout(self.reset,3000); // respawn
+ }
+
+ this.smashBonus = function() {
+ // soundManager.play(self.bonusSounds[self.bonusSound],urlBase+'sound/'+self.bonusSounds[self.bonusSound]+'.mp3');
+ }
+
+ this.reset = function() {
+ if (!self.broken) return false;
+ self.broken = false;
+ self.state = null;
+ xlsf.lightSmashCounter--;
+ // self.oExplosion.reset(); // may not be necessary
+ self.flickr();
+ }
+
+ this.init = function() {
+ self.o.className = 'xlsf-light '+this.sizeClass+' '+this.sClass;
+ self.o.style.left = self.x+'px';
+ self.o.style.top = self.y+'px';
+ self.o.style.width = self.w+'px';
+ self.o.style.height = self.h+'px';
+ // self.o.onmouseover = self.toggle;
+ // self.o.onmouseout = self.toggle;
+ self.o.onmouseover = self.smash;
+ self.o.onclick = self.smash;
+ self.flickr();
+ xlsf.oFrag.appendChild(self.o);
+ self.oExplosion = new Explosion(self.nType,self.sClass,self.x,self.y);
+ }
+
+ this.init();
+
+ } // Light()
+
+ this.createLight = function(sClass,nType,x,y) {
+ var oLight = new Light(self.lightClass,sClass,nType,x,y);
+ self.lightGroups[sClass].push(oLight);
+ self.lights.push(oLight);
+ return oLight;
+ }
+
+ this.rotateLights = function() {
+ self.lights[self.lightIndex==self.lights.length?self.lights.length-1:self.lightIndex].off();
+ self.lightIndex++;
+ if (self.lightIndex == self.lights.length) {
+ self.lightIndex = 0;
+ }
+ self.lights[self.lightIndex].on();
+ }
+
+ this.randomLights = function() {
+ self.lights[parseInt(Math.random()*self.lights.length)].toggle();
+ }
+
+
+ this.destroyLights = function() {
+ self.startSequence(self.destroyLight,20);
+ }
+
+ this.destroyLight = function() {
+ var groupSize = 2; // # to smash at a time
+ if (self.lightSmashCounter<self.lights.length) {
+ var limit = Math.min(self.lightSmashCounter+groupSize,self.lights.length);
+ for (var i=self.lightSmashCounter; i<limit; i++) {
+ self.lights[self.lightSmashCounter].smash();
+ }
+ } else {
+ self.stopSequence();
+ }
+
+ }
+
+ this.uberSmash = function() {
+ // make everything explode - including your CPU.
+ self.stopSequence();
+ var ebCN = Y.D.getElementsByClassName;
+/*
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.left)},500);
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.right)},2000);
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.bottom)},4000);
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.top)},6000);
+*/
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.bottom)},500);
+ window.setTimeout(function(){self.smashGroup(self.lightGroups.top)},3500);
+
+ }
+
+ this.smashGroup = function(oGroup) {
+ for (var i=oGroup.length; i--;) {
+ oGroup[i].smash();
+ }
+ }
+
+ this.startSequence = function(fSequence,nInterval) {
+ if (self.timer) self.stopSequence();
+ self.timer = window.setInterval(fSequence,(typeof nInterval != 'undefined'?nInterval:self.lightInterval));
+ }
+
+ this.stopSequence = function() {
+ if (self.timer) {
+ window.clearInterval(self.timer);
+ self.timer = null;
+ }
+ }
+
+ var i=0;
+
+/*
+ for (i=0; i<6; i++) {
+ this.createLight('left',parseInt(Math.random()*4),-2,50+i*(self.lightXY*0.7));
+ this.createLight('right',parseInt(Math.random()*4),962,50+i*(self.lightXY*0.7));
+ }
+
+ for (i=0; i<27; i++) {
+ this.createLight('top',parseInt(Math.random()*4),20+i*(self.lightXY*0.7),23);
+ this.createLight('bottom',parseInt(Math.random()*4),20+i*(self.lightXY*0.7),253);
+ }
+*/
+
+ var j=0;
+
+ if (window.innerWidth || window.innerHeight) {
+ var screenX = window.innerWidth; // -(!isIE?24:2);
+ var screenY = window.innerHeight;
+ } else {
+ var screenX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth); // -(!isIE?8:0);
+ var screenY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
+ }
+
+ var jMax = Math.floor((screenX-16)/self.lightXY);
+ var iMax = Math.floor((screenY-16)/self.lightXY);
+
+ for (i=0; i<iMax; i++) {
+ for (j=0; j<jMax; j++) {
+ this.createLight((i+1)%2==0?'bottom':'top',i%3,j*self.lightXY,i*self.lightXY);
+ }
+ }
+
+/*
+ var bsCounter = 0;
+ for (i=0; i<8; i++) {
+ // plant a few random seeds.. er, sounds.
+ self.lights[parseInt(Math.random()*self.lights.length)].bonusSound = bsCounter++;
+ if (bsCounter>2) bsCounter = 0; // hack - loop through sounds
+ }
+*/
+
+ this.appendLights();
+
+ // post-load/init case in the event this object is created late
+ // if (soundManager && soundManager._didInit && !soundManager._disabled) this.initSounds();
+
+ this.startSequence(self.randomLights);
+
+ // setTimeout(this.destroyLights,10000);
+ // setTimeout(this.uberSmash,10000);
+
+} // --- XLSF2007()
+
+var xlsf = null;
+
+function smashInit() {
+ xlsf = new XLSF(document.getElementById('lights'));
+ xlsf.initSounds();
+ document.getElementById('loading').style.display = 'none';
+}
+
+soundManager.url = '../../swf/';
+soundManager.flashVersion = 9;
+soundManager.debugMode = false;
+
+soundManager.onload = function() {
+ setTimeout(smashInit,500);
+}
+
+soundManager.onerror = function() {
+ setTimeout(smashInit,500);
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bg-strip-dark.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bg-strip-dark.png Binary files differnew file mode 100755 index 0000000..80e07d9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bg-strip-dark.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/blank.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/blank.png Binary files differnew file mode 100755 index 0000000..85af9fd --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/blank.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-bottom.png Binary files differnew file mode 100755 index 0000000..7246c01 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-left.png Binary files differnew file mode 100755 index 0000000..1cf077f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-right.png Binary files differnew file mode 100755 index 0000000..8e68ec1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-top.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-top.png Binary files differnew file mode 100755 index 0000000..0156c25 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-32x32-top.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-bottom.png Binary files differnew file mode 100755 index 0000000..79d3b07 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-fragments.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-fragments.png Binary files differnew file mode 100755 index 0000000..f963a89 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-fragments.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-left.png Binary files differnew file mode 100755 index 0000000..6aa0965 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-right.png Binary files differnew file mode 100755 index 0000000..c095739 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-top.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-top.png Binary files differnew file mode 100755 index 0000000..780fe75 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50-top.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50.png Binary files differnew file mode 100755 index 0000000..eb31135 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-50x50.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-bottom.png Binary files differnew file mode 100755 index 0000000..49341a1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-left.png Binary files differnew file mode 100755 index 0000000..cb581e4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-right.png Binary files differnew file mode 100755 index 0000000..fdd54ee --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-top.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-top.png Binary files differnew file mode 100755 index 0000000..09b098b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-64x64-top.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-bottom.png Binary files differnew file mode 100755 index 0000000..4e5cae3 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-left.png Binary files differnew file mode 100755 index 0000000..c8bfa43 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-right.png Binary files differnew file mode 100755 index 0000000..20a614b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-top.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-top.png Binary files differnew file mode 100755 index 0000000..76fd676 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-72x72-top.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-bottom.png Binary files differnew file mode 100755 index 0000000..3506236 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-left.png Binary files differnew file mode 100755 index 0000000..6f727e5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-right.png Binary files differnew file mode 100755 index 0000000..f4456d6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-top.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-top.png Binary files differnew file mode 100755 index 0000000..5c2ba64 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/image/bulbs-96x96-top.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/index.html new file mode 100755 index 0000000..ff9c6fe --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/index.html @@ -0,0 +1,33 @@ +<html>
+<head>
+<title>Smashable Christmas Lights</title> +<meta name="robots" content="noindex" />
+<link rel="stylesheet" media="screen" href="christmaslights.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="yahoo-dom-event-animation-260.js"></script>
+<script type="text/javascript" src="christmaslights.js"></script>
+</head>
+
+<body>
+
+<div>
+
+ <div id="loading">
+ <h1>Christmas Light Smashfest 2008: Prototype</h1>
+ <h2>Rendering...</h2>
+ </div>
+
+ <div id="lights">
+ <!-- lights go here -->
+ </div>
+
+ <div style="position:absolute;bottom:3px;left:3px">
+ <a href="?size=pico">pico</a> | <a href="?size=tiny">tiny</a> | <a href="?size=small">small</a> | <a href="?size=medium">medium</a> | <a href="?size=large">large</a>
+ </div>
+
+</div>
+
+
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass0.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass0.mp3 Binary files differnew file mode 100755 index 0000000..c161c69 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass0.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass1.mp3 Binary files differnew file mode 100755 index 0000000..8d7d6b5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass2.mp3 Binary files differnew file mode 100755 index 0000000..ef5f556 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass3.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass3.mp3 Binary files differnew file mode 100755 index 0000000..be7886e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass3.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass4.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass4.mp3 Binary files differnew file mode 100755 index 0000000..0f328f6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass4.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass5.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass5.mp3 Binary files differnew file mode 100755 index 0000000..b54513e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/sound/glass5.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/yahoo-dom-event-animation-260.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/yahoo-dom-event-animation-260.js new file mode 100755 index 0000000..c38fd9f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/christmas-lights/yahoo-dom-event-animation-260.js @@ -0,0 +1,35 @@ +/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.6.0
+*/
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{};(function(){var A=YAHOO.lang,C=["toString","valueOf"],B={isArray:function(D){if(D){return A.isNumber(D.length)&&A.isFunction(D.splice);}return false;},isBoolean:function(D){return typeof D==="boolean";},isFunction:function(D){return typeof D==="function";},isNull:function(D){return D===null;},isNumber:function(D){return typeof D==="number"&&isFinite(D);},isObject:function(D){return(D&&(typeof D==="object"||A.isFunction(D)))||false;},isString:function(D){return typeof D==="string";},isUndefined:function(D){return typeof D==="undefined";},_IEEnumFix:(YAHOO.env.ua.ie)?function(F,E){for(var D=0;D<C.length;D=D+1){var H=C[D],G=E[H];if(A.isFunction(G)&&G!=Object.prototype[H]){F[H]=G;}}}:function(){},extend:function(H,I,G){if(!I||!H){throw new Error("extend failed, please check that "+"all dependencies are included.");}var E=function(){};E.prototype=I.prototype;H.prototype=new E();H.prototype.constructor=H;H.superclass=I.prototype;if(I.prototype.constructor==Object.prototype.constructor){I.prototype.constructor=I;}if(G){for(var D in G){if(A.hasOwnProperty(G,D)){H.prototype[D]=G[D];}}A._IEEnumFix(H.prototype,G);}},augmentObject:function(H,G){if(!G||!H){throw new Error("Absorb failed, verify dependencies.");}var D=arguments,F,I,E=D[2];if(E&&E!==true){for(F=2;F<D.length;F=F+1){H[D[F]]=G[D[F]];}}else{for(I in G){if(E||!(I in H)){H[I]=G[I];}}A._IEEnumFix(H,G);}},augmentProto:function(G,F){if(!F||!G){throw new Error("Augment failed, verify dependencies.");}var D=[G.prototype,F.prototype];for(var E=2;E<arguments.length;E=E+1){D.push(arguments[E]);}A.augmentObject.apply(this,D);},dump:function(D,I){var F,H,K=[],L="{...}",E="f(){...}",J=", ",G=" => ";if(!A.isObject(D)){return D+"";}else{if(D instanceof Date||("nodeType" in D&&"tagName" in D)){return D;}else{if(A.isFunction(D)){return E;}}}I=(A.isNumber(I))?I:3;if(A.isArray(D)){K.push("[");for(F=0,H=D.length;F<H;F=F+1){if(A.isObject(D[F])){K.push((I>0)?A.dump(D[F],I-1):L);}else{K.push(D[F]);}K.push(J);}if(K.length>1){K.pop();}K.push("]");}else{K.push("{");for(F in D){if(A.hasOwnProperty(D,F)){K.push(F+G);if(A.isObject(D[F])){K.push((I>0)?A.dump(D[F],I-1):L);}else{K.push(D[F]);}K.push(J);}}if(K.length>1){K.pop();}K.push("}");}return K.join("");},substitute:function(S,E,L){var I,H,G,O,P,R,N=[],F,J="dump",M=" ",D="{",Q="}";for(;;){I=S.lastIndexOf(D);if(I<0){break;}H=S.indexOf(Q,I);if(I+1>=H){break;}F=S.substring(I+1,H);O=F;R=null;G=O.indexOf(M);if(G>-1){R=O.substring(G+1);O=O.substring(0,G);}P=E[O];if(L){P=L(O,P,R);}if(A.isObject(P)){if(A.isArray(P)){P=A.dump(P,parseInt(R,10));}else{R=R||"";var K=R.indexOf(J);if(K>-1){R=R.substring(4);}if(P.toString===Object.prototype.toString||K>-1){P=A.dump(P,parseInt(R,10));}else{P=P.toString();}}}else{if(!A.isString(P)&&!A.isNumber(P)){P="~-"+N.length+"-~";N[N.length]=F;}}S=S.substring(0,I)+P+S.substring(H+1);}for(I=N.length-1;I>=0;I=I-1){S=S.replace(new RegExp("~-"+I+"-~"),"{"+N[I]+"}","g");}return S;},trim:function(D){try{return D.replace(/^\s+|\s+$/g,"");}catch(E){return D;}},merge:function(){var G={},E=arguments;for(var F=0,D=E.length;F<D;F=F+1){A.augmentObject(G,E[F],true);}return G;},later:function(K,E,L,G,H){K=K||0;E=E||{};var F=L,J=G,I,D;if(A.isString(L)){F=E[L];}if(!F){throw new TypeError("method undefined");}if(!A.isArray(J)){J=[G];}I=function(){F.apply(E,J);};D=(H)?setInterval(I,K):setTimeout(I,K);return{interval:H,cancel:function(){if(this.interval){clearInterval(D);}else{clearTimeout(D);}}};},isValue:function(D){return(A.isObject(D)||A.isString(D)||A.isNumber(D)||A.isBoolean(D));}};A.hasOwnProperty=(Object.prototype.hasOwnProperty)?function(D,E){return D&&D.hasOwnProperty(E);}:function(D,E){return !A.isUndefined(D[E])&&D.constructor.prototype[E]!==D[E];};B.augmentObject(A,B,true);YAHOO.util.Lang=A;A.augment=A.augmentProto;YAHOO.augment=A.augmentProto;YAHOO.extend=A.extend;})();YAHOO.register("yahoo",YAHOO,{version:"2.6.0",build:"1321"});(function(){var B=YAHOO.util,F=YAHOO.lang,L,J,K={},G={},N=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C=YAHOO.env.ua.opera,M=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,H=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var O=function(Q){if(!E.HYPHEN.test(Q)){return Q;}if(K[Q]){return K[Q];}var R=Q;while(E.HYPHEN.exec(R)){R=R.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}K[Q]=R;return R;};var P=function(R){var Q=G[R];if(!Q){Q=new RegExp("(?:^|\\s+)"+R+"(?:\\s+|$)");G[R]=Q;}return Q;};if(N.defaultView&&N.defaultView.getComputedStyle){L=function(Q,T){var S=null;if(T=="float"){T="cssFloat";}var R=Q.ownerDocument.defaultView.getComputedStyle(Q,"");if(R){S=R[O(T)];}return Q.style[T]||S;};}else{if(N.documentElement.currentStyle&&H){L=function(Q,S){switch(O(S)){case"opacity":var U=100;try{U=Q.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(T){try{U=Q.filters("alpha").opacity;}catch(T){}}return U/100;case"float":S="styleFloat";default:var R=Q.currentStyle?Q.currentStyle[S]:null;return(Q.style[S]||R);}};}else{L=function(Q,R){return Q.style[R];};}}if(H){J=function(Q,R,S){switch(R){case"opacity":if(F.isString(Q.style.filter)){Q.style.filter="alpha(opacity="+S*100+")";if(!Q.currentStyle||!Q.currentStyle.hasLayout){Q.style.zoom=1;}}break;case"float":R="styleFloat";default:Q.style[R]=S;}};}else{J=function(Q,R,S){if(R=="float"){R="cssFloat";}Q.style[R]=S;};}var D=function(Q,R){return Q&&Q.nodeType==1&&(!R||R(Q));};YAHOO.util.Dom={get:function(S){if(S){if(S.nodeType||S.item){return S;}if(typeof S==="string"){return N.getElementById(S);}if("length" in S){var T=[];for(var R=0,Q=S.length;R<Q;++R){T[T.length]=B.Dom.get(S[R]);}return T;}return S;}return null;},getStyle:function(Q,S){S=O(S);var R=function(T){return L(T,S);};return B.Dom.batch(Q,R,B.Dom,true);},setStyle:function(Q,S,T){S=O(S);var R=function(U){J(U,S,T);};B.Dom.batch(Q,R,B.Dom,true);},getXY:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=S.ownerDocument.body){return false;}return I(S);};return B.Dom.batch(Q,R,B.Dom,true);},getX:function(Q){var R=function(S){return B.Dom.getXY(S)[0];};return B.Dom.batch(Q,R,B.Dom,true);},getY:function(Q){var R=function(S){return B.Dom.getXY(S)[1];};return B.Dom.batch(Q,R,B.Dom,true);},setXY:function(Q,T,S){var R=function(W){var V=this.getStyle(W,"position");if(V=="static"){this.setStyle(W,"position","relative");V="relative";}var Y=this.getXY(W);if(Y===false){return false;}var X=[parseInt(this.getStyle(W,"left"),10),parseInt(this.getStyle(W,"top"),10)];if(isNaN(X[0])){X[0]=(V=="relative")?0:W.offsetLeft;}if(isNaN(X[1])){X[1]=(V=="relative")?0:W.offsetTop;}if(T[0]!==null){W.style.left=T[0]-Y[0]+X[0]+"px";}if(T[1]!==null){W.style.top=T[1]-Y[1]+X[1]+"px";}if(!S){var U=this.getXY(W);if((T[0]!==null&&U[0]!=T[0])||(T[1]!==null&&U[1]!=T[1])){this.setXY(W,T,true);}}};B.Dom.batch(Q,R,B.Dom,true);},setX:function(R,Q){B.Dom.setXY(R,[Q,null]);},setY:function(Q,R){B.Dom.setXY(Q,[null,R]);},getRegion:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=S.ownerDocument.body){return false;}var T=B.Region.getRegion(S);return T;};return B.Dom.batch(Q,R,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(U,Y,V,W){U=F.trim(U);Y=Y||"*";V=(V)?B.Dom.get(V):null||N;if(!V){return[];}var R=[],Q=V.getElementsByTagName(Y),X=P(U);for(var S=0,T=Q.length;S<T;++S){if(X.test(Q[S].className)){R[R.length]=Q[S];if(W){W.call(Q[S],Q[S]);}}}return R;},hasClass:function(S,R){var Q=P(R);var T=function(U){return Q.test(U.className);};return B.Dom.batch(S,T,B.Dom,true);},addClass:function(R,Q){var S=function(T){if(this.hasClass(T,Q)){return false;}T.className=F.trim([T.className,Q].join(" "));return true;};return B.Dom.batch(R,S,B.Dom,true);},removeClass:function(S,R){var Q=P(R);var T=function(W){var V=false,X=W.className;if(R&&X&&this.hasClass(W,R)){W.className=X.replace(Q," ");if(this.hasClass(W,R)){this.removeClass(W,R);}W.className=F.trim(W.className);if(W.className===""){var U=(W.hasAttribute)?"class":"className";W.removeAttribute(U);}V=true;}return V;};return B.Dom.batch(S,T,B.Dom,true);},replaceClass:function(T,R,Q){if(!Q||R===Q){return false;}var S=P(R);var U=function(V){if(!this.hasClass(V,R)){this.addClass(V,Q);return true;}V.className=V.className.replace(S," "+Q+" ");if(this.hasClass(V,R)){this.removeClass(V,R);}V.className=F.trim(V.className);return true;};return B.Dom.batch(T,U,B.Dom,true);},generateId:function(Q,S){S=S||"yui-gen";var R=function(T){if(T&&T.id){return T.id;}var U=S+YAHOO.env._id_counter++;if(T){T.id=U;}return U;};return B.Dom.batch(Q,R,B.Dom,true)||R.apply(B.Dom,arguments);},isAncestor:function(R,S){R=B.Dom.get(R);S=B.Dom.get(S);var Q=false;if((R&&S)&&(R.nodeType&&S.nodeType)){if(R.contains&&R!==S){Q=R.contains(S);}else{if(R.compareDocumentPosition){Q=!!(R.compareDocumentPosition(S)&16);}}}else{}return Q;},inDocument:function(Q){return this.isAncestor(N.documentElement,Q);},getElementsBy:function(X,R,S,U){R=R||"*";S=(S)?B.Dom.get(S):null||N;if(!S){return[];}var T=[],W=S.getElementsByTagName(R);for(var V=0,Q=W.length;V<Q;++V){if(X(W[V])){T[T.length]=W[V];if(U){U(W[V]);}}}return T;},batch:function(U,X,W,S){U=(U&&(U.tagName||U.item))?U:B.Dom.get(U);if(!U||!X){return false;}var T=(S)?W:window;if(U.tagName||U.length===undefined){return X.call(T,U,W);}var V=[];for(var R=0,Q=U.length;R<Q;++R){V[V.length]=X.call(T,U[R],W);}return V;},getDocumentHeight:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollHeight:N.documentElement.scrollHeight;var Q=Math.max(R,B.Dom.getViewportHeight());return Q;},getDocumentWidth:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollWidth:N.documentElement.scrollWidth;var Q=Math.max(R,B.Dom.getViewportWidth());return Q;},getViewportHeight:function(){var Q=self.innerHeight;
+var R=N.compatMode;if((R||H)&&!C){Q=(R=="CSS1Compat")?N.documentElement.clientHeight:N.body.clientHeight;}return Q;},getViewportWidth:function(){var Q=self.innerWidth;var R=N.compatMode;if(R||H){Q=(R=="CSS1Compat")?N.documentElement.clientWidth:N.body.clientWidth;}return Q;},getAncestorBy:function(Q,R){while((Q=Q.parentNode)){if(D(Q,R)){return Q;}}return null;},getAncestorByClassName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return B.Dom.hasClass(T,Q);};return B.Dom.getAncestorBy(R,S);},getAncestorByTagName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return T.tagName&&T.tagName.toUpperCase()==Q.toUpperCase();};return B.Dom.getAncestorBy(R,S);},getPreviousSiblingBy:function(Q,R){while(Q){Q=Q.previousSibling;if(D(Q,R)){return Q;}}return null;},getPreviousSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getPreviousSiblingBy(Q);},getNextSiblingBy:function(Q,R){while(Q){Q=Q.nextSibling;if(D(Q,R)){return Q;}}return null;},getNextSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getNextSiblingBy(Q);},getFirstChildBy:function(Q,S){var R=(D(Q.firstChild,S))?Q.firstChild:null;return R||B.Dom.getNextSiblingBy(Q.firstChild,S);},getFirstChild:function(Q,R){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getFirstChildBy(Q);},getLastChildBy:function(Q,S){if(!Q){return null;}var R=(D(Q.lastChild,S))?Q.lastChild:null;return R||B.Dom.getPreviousSiblingBy(Q.lastChild,S);},getLastChild:function(Q){Q=B.Dom.get(Q);return B.Dom.getLastChildBy(Q);},getChildrenBy:function(R,T){var S=B.Dom.getFirstChildBy(R,T);var Q=S?[S]:[];B.Dom.getNextSiblingBy(S,function(U){if(!T||T(U)){Q[Q.length]=U;}return false;});return Q;},getChildren:function(Q){Q=B.Dom.get(Q);if(!Q){}return B.Dom.getChildrenBy(Q);},getDocumentScrollLeft:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollLeft,Q.body.scrollLeft);},getDocumentScrollTop:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollTop,Q.body.scrollTop);},insertBefore:function(R,Q){R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return null;}return Q.parentNode.insertBefore(R,Q);},insertAfter:function(R,Q){R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return null;}if(Q.nextSibling){return Q.parentNode.insertBefore(R,Q.nextSibling);}else{return Q.parentNode.appendChild(R);}},getClientRegion:function(){var S=B.Dom.getDocumentScrollTop(),R=B.Dom.getDocumentScrollLeft(),T=B.Dom.getViewportWidth()+R,Q=B.Dom.getViewportHeight()+S;return new B.Region(S,T,Q,R);}};var I=function(){if(N.documentElement.getBoundingClientRect){return function(S){var T=S.getBoundingClientRect(),R=Math.round;var Q=S.ownerDocument;return[R(T.left+B.Dom.getDocumentScrollLeft(Q)),R(T.top+B.Dom.getDocumentScrollTop(Q))];};}else{return function(S){var T=[S.offsetLeft,S.offsetTop];var R=S.offsetParent;var Q=(M&&B.Dom.getStyle(S,"position")=="absolute"&&S.offsetParent==S.ownerDocument.body);if(R!=S){while(R){T[0]+=R.offsetLeft;T[1]+=R.offsetTop;if(!Q&&M&&B.Dom.getStyle(R,"position")=="absolute"){Q=true;}R=R.offsetParent;}}if(Q){T[0]-=S.ownerDocument.body.offsetLeft;T[1]-=S.ownerDocument.body.offsetTop;}R=S.parentNode;while(R.tagName&&!E.ROOT_TAG.test(R.tagName)){if(R.scrollTop||R.scrollLeft){T[0]-=R.scrollLeft;T[1]-=R.scrollTop;}R=R.parentNode;}return T;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top);var D=Math.max(this.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.6.0",build:"1321"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){this.lastError=null;var K=[],E=this.subscribers.length;if(!E&&this.silent){return true;}var I=[].slice.call(arguments,0),G=true,D,J=false;if(!this.silent){}var C=this.subscribers.slice(),A=YAHOO.util.Event.throwErrors;for(D=0;D<E;++D){var M=C[D];if(!M){J=true;}else{if(!this.silent){}var L=M.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var B=null;if(I.length>0){B=I[0];}try{G=M.fn.call(L,B,M.obj);}catch(F){this.lastError=F;if(A){throw F;}}}else{try{G=M.fn.call(L,this.type,I,M.obj);}catch(H){this.lastError=H;if(A){throw H;}}}if(false===G){if(!this.silent){}break;}}}return(G!==false);},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};var K=YAHOO.env.ua.ie?"focusin":"focus";var L=YAHOO.env.ua.ie?"focusout":"blur";return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,CAPTURE:7,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,throwErrors:false,startInterval:function(){if(!this._interval){var M=this;var N=function(){M._tryPreloadAttach();};this._interval=setInterval(N,this.POLL_INTERVAL);}},onAvailable:function(R,O,S,Q,P){var M=(YAHOO.lang.isString(R))?[R]:R;for(var N=0;N<M.length;N=N+1){F.push({id:M[N],fn:O,obj:S,override:Q,checkReady:P});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(O,M,P,N){this.onAvailable(O,M,P,N,true);},onDOMReady:function(M,O,N){if(this.DOMReady){setTimeout(function(){var P=window;if(N){if(N===true){P=O;}else{P=N;}}M.call(P,"DOMReady",[],O);},0);}else{this.DOMReadyEvent.subscribe(M,O,N);}},_addListener:function(O,M,X,S,N,a){if(!X||!X.call){return false;}if(this._isValidCollection(O)){var Y=true;for(var T=0,V=O.length;T<V;++T){Y=this._addListener(O[T],M,X,S,N,a)&&Y;}return Y;}else{if(YAHOO.lang.isString(O)){var R=this.getEl(O);if(R){O=R;}else{this.onAvailable(O,function(){YAHOO.util.Event._addListener(O,M,X,S,N,a);});return true;}}}if(!O){return false;}if("unload"==M&&S!==this){J[J.length]=[O,M,X,S,N,a];return true;}var b=O;if(N){if(N===true){b=S;}else{b=N;}}var P=function(c){return X.call(b,YAHOO.util.Event.getEvent(c,O),S);};var Z=[O,M,X,P,b,S,N,a];var U=I.length;I[U]=Z;if(this.useLegacyEvent(O,M)){var Q=this.getLegacyIndex(O,M);if(Q==-1||O!=G[Q][0]){Q=G.length;B[O.id+M]=Q;G[Q]=[O,M,O["on"+M]];E[Q]=[];O["on"+M]=function(c){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(c),Q);};}E[Q].push(Z);}else{try{this._simpleAdd(O,M,P,a);}catch(W){this.lastError=W;this._removeListener(O,M,X,a);return false;}}return true;},addListener:function(O,Q,N,P,M){return this._addListener(O,Q,N,P,M,false);},addFocusListener:function(O,N,P,M){return this._addListener(O,K,N,P,M,true);},removeFocusListener:function(N,M){return this._removeListener(N,K,M,true);},addBlurListener:function(O,N,P,M){return this._addListener(O,L,N,P,M,true);},removeBlurListener:function(N,M){return this._removeListener(N,L,M,true);},fireLegacyEvent:function(Q,O){var S=true,M,U,T,V,R;U=E[O].slice();for(var N=0,P=U.length;N<P;++N){T=U[N];if(T&&T[this.WFN]){V=T[this.ADJ_SCOPE];R=T[this.WFN].call(V,Q);S=(S&&R);}}M=G[O];if(M&&M[2]){M[2](Q);}return S;},getLegacyIndex:function(N,O){var M=this.generateId(N)+O;if(typeof B[M]=="undefined"){return -1;}else{return B[M];}},useLegacyEvent:function(M,N){return(this.webkit&&this.webkit<419&&("click"==N||"dblclick"==N));},_removeListener:function(N,M,V,Y){var Q,T,X;if(typeof N=="string"){N=this.getEl(N);}else{if(this._isValidCollection(N)){var W=true;for(Q=N.length-1;Q>-1;Q--){W=(this._removeListener(N[Q],M,V,Y)&&W);}return W;}}if(!V||!V.call){return this.purgeElement(N,false,M);}if("unload"==M){for(Q=J.length-1;Q>-1;Q--){X=J[Q];if(X&&X[0]==N&&X[1]==M&&X[2]==V){J.splice(Q,1);return true;}}return false;}var R=null;var S=arguments[4];if("undefined"===typeof S){S=this._getCacheIndex(N,M,V);}if(S>=0){R=I[S];}if(!N||!R){return false;}if(this.useLegacyEvent(N,M)){var P=this.getLegacyIndex(N,M);var O=E[P];if(O){for(Q=0,T=O.length;Q<T;++Q){X=O[Q];if(X&&X[this.EL]==N&&X[this.TYPE]==M&&X[this.FN]==V){O.splice(Q,1);break;}}}}else{try{this._simpleRemove(N,M,R[this.WFN],Y);}catch(U){this.lastError=U;return false;}}delete I[S][this.WFN];delete I[S][this.FN];
+I.splice(S,1);return true;},removeListener:function(N,O,M){return this._removeListener(N,O,M,false);},getTarget:function(O,N){var M=O.target||O.srcElement;return this.resolveTextNode(M);},resolveTextNode:function(N){try{if(N&&3==N.nodeType){return N.parentNode;}}catch(M){}return N;},getPageX:function(N){var M=N.pageX;if(!M&&0!==M){M=N.clientX||0;if(this.isIE){M+=this._getScrollLeft();}}return M;},getPageY:function(M){var N=M.pageY;if(!N&&0!==N){N=M.clientY||0;if(this.isIE){N+=this._getScrollTop();}}return N;},getXY:function(M){return[this.getPageX(M),this.getPageY(M)];},getRelatedTarget:function(N){var M=N.relatedTarget;if(!M){if(N.type=="mouseout"){M=N.toElement;}else{if(N.type=="mouseover"){M=N.fromElement;}}}return this.resolveTextNode(M);},getTime:function(O){if(!O.time){var N=new Date().getTime();try{O.time=N;}catch(M){this.lastError=M;return N;}}return O.time;},stopEvent:function(M){this.stopPropagation(M);this.preventDefault(M);},stopPropagation:function(M){if(M.stopPropagation){M.stopPropagation();}else{M.cancelBubble=true;}},preventDefault:function(M){if(M.preventDefault){M.preventDefault();}else{M.returnValue=false;}},getEvent:function(O,M){var N=O||window.event;if(!N){var P=this.getEvent.caller;while(P){N=P.arguments[0];if(N&&Event==N.constructor){break;}P=P.caller;}}return N;},getCharCode:function(N){var M=N.keyCode||N.charCode||0;if(YAHOO.env.ua.webkit&&(M in D)){M=D[M];}return M;},_getCacheIndex:function(Q,R,P){for(var O=0,N=I.length;O<N;O=O+1){var M=I[O];if(M&&M[this.FN]==P&&M[this.EL]==Q&&M[this.TYPE]==R){return O;}}return -1;},generateId:function(M){var N=M.id;if(!N){N="yuievtautoid-"+A;++A;M.id=N;}return N;},_isValidCollection:function(N){try{return(N&&typeof N!=="string"&&N.length&&!N.tagName&&!N.alert&&typeof N[0]!=="undefined");}catch(M){return false;}},elCache:{},getEl:function(M){return(typeof M==="string")?document.getElementById(M):M;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(N){if(!H){H=true;var M=YAHOO.util.Event;M._ready();M._tryPreloadAttach();}},_ready:function(N){var M=YAHOO.util.Event;if(!M.DOMReady){M.DOMReady=true;M.DOMReadyEvent.fire();M._simpleRemove(document,"DOMContentLoaded",M._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var S=!H;if(!S){S=(C>0&&F.length>0);}var R=[];var T=function(V,W){var U=V;if(W.override){if(W.override===true){U=W.obj;}else{U=W.override;}}W.fn.call(U,W.obj);};var N,M,Q,P,O=[];for(N=0,M=F.length;N<M;N=N+1){Q=F[N];if(Q){P=this.getEl(Q.id);if(P){if(Q.checkReady){if(H||P.nextSibling||!S){O.push(Q);F[N]=null;}}else{T(P,Q);F[N]=null;}}else{R.push(Q);}}}for(N=0,M=O.length;N<M;N=N+1){Q=O[N];T(this.getEl(Q.id),Q);}C--;if(S){for(N=F.length-1;N>-1;N--){Q=F[N];if(!Q||!Q.id){F.splice(N,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(Q,R,T){var O=(YAHOO.lang.isString(Q))?this.getEl(Q):Q;var S=this.getListeners(O,T),P,M;if(S){for(P=S.length-1;P>-1;P--){var N=S[P];this._removeListener(O,N.type,N.fn,N.capture);}}if(R&&O&&O.childNodes){for(P=0,M=O.childNodes.length;P<M;++P){this.purgeElement(O.childNodes[P],R,T);}}},getListeners:function(O,M){var R=[],N;if(!M){N=[I,J];}else{if(M==="unload"){N=[J];}else{N=[I];}}var T=(YAHOO.lang.isString(O))?this.getEl(O):O;for(var Q=0;Q<N.length;Q=Q+1){var V=N[Q];if(V){for(var S=0,U=V.length;S<U;++S){var P=V[S];if(P&&P[this.EL]===T&&(!M||M===P[this.TYPE])){R.push({type:P[this.TYPE],fn:P[this.FN],obj:P[this.OBJ],adjust:P[this.OVERRIDE],scope:P[this.ADJ_SCOPE],capture:P[this.CAPTURE],index:S});}}}}return(R.length)?R:null;},_unload:function(S){var M=YAHOO.util.Event,P,O,N,R,Q,T=J.slice();for(P=0,R=J.length;P<R;++P){N=T[P];if(N){var U=window;if(N[M.ADJ_SCOPE]){if(N[M.ADJ_SCOPE]===true){U=N[M.UNLOAD_OBJ];}else{U=N[M.ADJ_SCOPE];}}N[M.FN].call(U,M.getEvent(S,N[M.EL]),N[M.UNLOAD_OBJ]);T[P]=null;N=null;U=null;}}J=null;if(I){for(O=I.length-1;O>-1;O--){N=I[O];if(N){M._removeListener(N[M.EL],N[M.TYPE],N[M.FN],N[M.CAPTURE],O);}}N=null;}G=null;M._simpleRemove(window,"unload",M._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var M=document.documentElement,N=document.body;if(M&&(M.scrollTop||M.scrollLeft)){return[M.scrollTop,M.scrollLeft];}else{if(N){return[N.scrollTop,N.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(O,P,N,M){O.addEventListener(P,N,(M));};}else{if(window.attachEvent){return function(O,P,N,M){O.attachEvent("on"+P,N);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(O,P,N,M){O.removeEventListener(P,N,(M));};}else{if(window.detachEvent){return function(N,O,M){N.detachEvent("on"+O,M);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;EU.onFocus=EU.addFocusListener;EU.onBlur=EU.addBlurListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};
+var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINTSCREEN:44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.6.0",build:"1321"});YAHOO.register("yahoo-dom-event", YAHOO, {version: "2.6.0", build: "1321"});
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.6.0
+*/
+(function(){var B=YAHOO.util;var A=function(D,C,E,F){if(!D){}this.init(D,C,E,F);};A.NAME="Anim";A.prototype={toString:function(){var C=this.getEl()||{};var D=C.id||C.tagName;return(this.constructor.NAME+": "+D);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(C,E,D){return this.method(this.currentFrame,E,D-E,this.totalFrames);},setAttribute:function(C,E,D){if(this.patterns.noNegatives.test(C)){E=(E>0)?E:0;}B.Dom.setStyle(this.getEl(),C,E+D);},getAttribute:function(C){var E=this.getEl();var G=B.Dom.getStyle(E,C);if(G!=="auto"&&!this.patterns.offsetUnit.test(G)){return parseFloat(G);}var D=this.patterns.offsetAttribute.exec(C)||[];var H=!!(D[3]);var F=!!(D[2]);if(F||(B.Dom.getStyle(E,"position")=="absolute"&&H)){G=E["offset"+D[0].charAt(0).toUpperCase()+D[0].substr(1)];}else{G=0;}return G;},getDefaultUnit:function(C){if(this.patterns.defaultUnit.test(C)){return"px";}return"";},setRuntimeAttribute:function(D){var I;var E;var F=this.attributes;this.runtimeAttributes[D]={};var H=function(J){return(typeof J!=="undefined");};if(!H(F[D]["to"])&&!H(F[D]["by"])){return false;}I=(H(F[D]["from"]))?F[D]["from"]:this.getAttribute(D);if(H(F[D]["to"])){E=F[D]["to"];}else{if(H(F[D]["by"])){if(I.constructor==Array){E=[];for(var G=0,C=I.length;G<C;++G){E[G]=I[G]+F[D]["by"][G]*1;}}else{E=I+F[D]["by"]*1;}}}this.runtimeAttributes[D].start=I;this.runtimeAttributes[D].end=E;this.runtimeAttributes[D].unit=(H(F[D].unit))?F[D]["unit"]:this.getDefaultUnit(D);return true;},init:function(E,J,I,C){var D=false;var F=null;var H=0;E=B.Dom.get(E);this.attributes=J||{};this.duration=!YAHOO.lang.isUndefined(I)?I:1;this.method=C||B.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=B.AnimMgr.fps;this.setEl=function(M){E=B.Dom.get(M);};this.getEl=function(){return E;};this.isAnimated=function(){return D;};this.getStartTime=function(){return F;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(B.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}B.AnimMgr.registerElement(this);return true;};this.stop=function(M){if(!this.isAnimated()){return false;}if(M){this.currentFrame=this.totalFrames;this._onTween.fire();}B.AnimMgr.stop(this);};var L=function(){this.onStart.fire();this.runtimeAttributes={};for(var M in this.attributes){this.setRuntimeAttribute(M);}D=true;H=0;F=new Date();};var K=function(){var O={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};O.toString=function(){return("duration: "+O.duration+", currentFrame: "+O.currentFrame);};this.onTween.fire(O);var N=this.runtimeAttributes;for(var M in N){this.setAttribute(M,this.doMethod(M,N[M].start,N[M].end),N[M].unit);}H+=1;};var G=function(){var M=(new Date()-F)/1000;var N={duration:M,frames:H,fps:H/M};N.toString=function(){return("duration: "+N.duration+", frames: "+N.frames+", fps: "+N.fps);};D=false;H=0;this.onComplete.fire(N);};this._onStart=new B.CustomEvent("_start",this,true);this.onStart=new B.CustomEvent("start",this);this.onTween=new B.CustomEvent("tween",this);this._onTween=new B.CustomEvent("_tween",this,true);this.onComplete=new B.CustomEvent("complete",this);this._onComplete=new B.CustomEvent("_complete",this,true);this._onStart.subscribe(L);this._onTween.subscribe(K);this._onComplete.subscribe(G);}};B.Anim=A;})();YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){var A=function(F,E,G,H){A.superclass.constructor.call(this,F,E,G,H);};A.NAME="ColorAnim";A.DEFAULT_BGCOLOR="#fff";var C=YAHOO.util;YAHOO.extend(A,C.Anim);var D=A.superclass;var B=A.prototype;B.patterns.color=/color$/i;B.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;B.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;B.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;B.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;B.parseColor=function(E){if(E.length==3){return E;}var F=this.patterns.hex.exec(E);if(F&&F.length==4){return[parseInt(F[1],16),parseInt(F[2],16),parseInt(F[3],16)];}F=this.patterns.rgb.exec(E);if(F&&F.length==4){return[parseInt(F[1],10),parseInt(F[2],10),parseInt(F[3],10)];}F=this.patterns.hex3.exec(E);if(F&&F.length==4){return[parseInt(F[1]+F[1],16),parseInt(F[2]+F[2],16),parseInt(F[3]+F[3],16)];}return null;};B.getAttribute=function(E){var G=this.getEl();
+if(this.patterns.color.test(E)){var I=YAHOO.util.Dom.getStyle(G,E);var H=this;if(this.patterns.transparent.test(I)){var F=YAHOO.util.Dom.getAncestorBy(G,function(J){return !H.patterns.transparent.test(I);});if(F){I=C.Dom.getStyle(F,E);}else{I=A.DEFAULT_BGCOLOR;}}}else{I=D.getAttribute.call(this,E);}return I;};B.doMethod=function(F,J,G){var I;if(this.patterns.color.test(F)){I=[];for(var H=0,E=J.length;H<E;++H){I[H]=D.doMethod.call(this,F,J[H],G[H]);}I="rgb("+Math.floor(I[0])+","+Math.floor(I[1])+","+Math.floor(I[2])+")";}else{I=D.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(F){D.setRuntimeAttribute.call(this,F);if(this.patterns.color.test(F)){var H=this.attributes;var J=this.parseColor(this.runtimeAttributes[F].start);var G=this.parseColor(this.runtimeAttributes[F].end);if(typeof H[F]["to"]==="undefined"&&typeof H[F]["by"]!=="undefined"){G=this.parseColor(H[F].by);for(var I=0,E=J.length;I<E;++I){G[I]=J[I]+G[I];}}this.runtimeAttributes[F].start=J;this.runtimeAttributes[F].end=G;}};C.ColorAnim=A;})();
+/*
+TERMS OF USE - EASING EQUATIONS
+Open source under the BSD License.
+Copyright 2001 Robert Penner All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.5625*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,C){if(B<C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){var A=function(H,G,I,J){if(H){A.superclass.constructor.call(this,H,G,I,J);}};A.NAME="Motion";var E=YAHOO.util;YAHOO.extend(A,E.ColorAnim);var F=A.superclass;var C=A.prototype;C.patterns.points=/^points$/i;C.setAttribute=function(G,I,H){if(this.patterns.points.test(G)){H=H||"px";F.setAttribute.call(this,"left",I[0],H);F.setAttribute.call(this,"top",I[1],H);}else{F.setAttribute.call(this,G,I,H);}};C.getAttribute=function(G){if(this.patterns.points.test(G)){var H=[F.getAttribute.call(this,"left"),F.getAttribute.call(this,"top")];}else{H=F.getAttribute.call(this,G);}return H;};C.doMethod=function(G,K,H){var J=null;if(this.patterns.points.test(G)){var I=this.method(this.currentFrame,0,100,this.totalFrames)/100;J=E.Bezier.getPosition(this.runtimeAttributes[G],I);}else{J=F.doMethod.call(this,G,K,H);}return J;};C.setRuntimeAttribute=function(P){if(this.patterns.points.test(P)){var H=this.getEl();var J=this.attributes;var G;var L=J["points"]["control"]||[];var I;var M,O;if(L.length>0&&!(L[0] instanceof Array)){L=[L];}else{var K=[];for(M=0,O=L.length;M<O;++M){K[M]=L[M];}L=K;}if(E.Dom.getStyle(H,"position")=="static"){E.Dom.setStyle(H,"position","relative");}if(D(J["points"]["from"])){E.Dom.setXY(H,J["points"]["from"]);}else{E.Dom.setXY(H,E.Dom.getXY(H));
+}G=this.getAttribute("points");if(D(J["points"]["to"])){I=B.call(this,J["points"]["to"],G);var N=E.Dom.getXY(this.getEl());for(M=0,O=L.length;M<O;++M){L[M]=B.call(this,L[M],G);}}else{if(D(J["points"]["by"])){I=[G[0]+J["points"]["by"][0],G[1]+J["points"]["by"][1]];for(M=0,O=L.length;M<O;++M){L[M]=[G[0]+L[M][0],G[1]+L[M][1]];}}}this.runtimeAttributes[P]=[G];if(L.length>0){this.runtimeAttributes[P]=this.runtimeAttributes[P].concat(L);}this.runtimeAttributes[P][this.runtimeAttributes[P].length]=I;}else{F.setRuntimeAttribute.call(this,P);}};var B=function(G,I){var H=E.Dom.getXY(this.getEl());G=[G[0]-H[0]+I[0],G[1]-H[1]+I[1]];return G;};var D=function(G){return(typeof G!=="undefined");};E.Motion=A;})();(function(){var D=function(F,E,G,H){if(F){D.superclass.constructor.call(this,F,E,G,H);}};D.NAME="Scroll";var B=YAHOO.util;YAHOO.extend(D,B.ColorAnim);var C=D.superclass;var A=D.prototype;A.doMethod=function(E,H,F){var G=null;if(E=="scroll"){G=[this.method(this.currentFrame,H[0],F[0]-H[0],this.totalFrames),this.method(this.currentFrame,H[1],F[1]-H[1],this.totalFrames)];}else{G=C.doMethod.call(this,E,H,F);}return G;};A.getAttribute=function(E){var G=null;var F=this.getEl();if(E=="scroll"){G=[F.scrollLeft,F.scrollTop];}else{G=C.getAttribute.call(this,E);}return G;};A.setAttribute=function(E,H,G){var F=this.getEl();if(E=="scroll"){F.scrollLeft=H[0];F.scrollTop=H[1];}else{C.setAttribute.call(this,E,H,G);}};B.Scroll=D;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.6.0",build:"1321"});
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/debug.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/debug.css new file mode 100755 index 0000000..728fd4b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/debug.css @@ -0,0 +1,25 @@ +#soundmanager-debug {
+ position:fixed;
+ _position:absolute; /* IE <7 */
+ bottom:1em;
+ right:1em;
+ width:38em;
+ height:30em;
+ overflow:auto;
+ padding:0px;
+ margin:1em;
+ font-family:monaco,"VT-100",terminal,"lucida console",courier,system;
+ opacity:0.9;
+ color:#333;
+ border:1px solid #ccddee;
+ -moz-border-radius:3px;
+ -khtml-border-radius:3px;
+ -webkit-border-radius:3px;
+ background:#f3f9ff;
+}
+
+#soundmanager-debug div {
+ font-size:x-small;
+ padding:0.2em;
+ margin:0px;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/basic.html new file mode 100755 index 0000000..39b768b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/basic.html @@ -0,0 +1,36 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> +<title>SoundManager 2: Flash blocker handling - basic example</title> +<meta name="description" content="Demo of SoundManager 2 handling flashblock / "click to flash" blockers gracefully" /> +<meta name="keywords" content="javascript sound, javascript audio, DHTML sound, flashblock, flash blocker, handling flashblock, click to flash, click2flash" /> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" /> + +<!-- actual flashblock demo stuff, this is for you --> +<link rel="stylesheet" type="text/css" href="flashblock.css" /> +<script type="text/javascript" src="../../script/soundmanager2.js"></script> + +<script type="text/javascript"> +// enable flash block handling +soundManager.useFlashBlock = true; + +// custom demo options, not for your needs +soundManager.debugMode = true; +soundManager.url = '../../swf/'; + +</script> +</head> +<body> + +<div> + + <h1><a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a>: Flashblock / "click to flash" handling: Basic Demo</h1> + + <div id="sm2-container"> + <!-- flash movie will be placed here --> + </div> + + <p>See <a href="flashblock.css">flashblock.css</a> as a template for making your own SM2 + flash block implementations.</p> + +</div>
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/flashblock.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/flashblock.css new file mode 100755 index 0000000..6733a08 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/flashblock.css @@ -0,0 +1,99 @@ +/*
+ SoundManager 2 + useFlashBlock
+ Flash positioning and flashblock / clicktoflash handling
+*/
+
+#sm2-container {
+ /*
+ where the SM2 flash movie goes. by default, relative container.
+ set relative or absolute here, and don't touch it later or bad things will happen (see below comments.)
+ */
+ position:relative;
+ width:1px;
+ height:1px;
+ _overflow:hidden; /* screw IE 6, just make it display nice */
+}
+
+#sm2-container object,
+#sm2-container embed {
+ /*
+ the actual movie bit.
+ SWF needs to be able to be moved off-screen without display: or position: changes. important.
+ changing display: or position: or overflow: here or on parent can cause SFW reload or other weird issues after unblock,
+ eg. SM2 starts but strange errors, no whileplaying() etc.
+ */
+ position:absolute;
+}
+
+#sm2-container object,
+#sm2-container embed,
+#sm2-container.swf_timedout,
+#sm2-container.swf_timedout object,
+#sm2-container.swf_timedout embed {
+ /*
+ when SM2 didn't start normally, time-out case. flash blocked, missing SWF, no flash?
+ 48px square flash placeholder is typically used by blockers.
+ */
+ left:auto;
+ top:auto;
+ width:48px;
+ height:48px;
+}
+
+#sm2-container.swf_unblocked {
+ /* SWF unblocked, or was never blocked to begin with; try to collapse container as much as possible. */
+ width:1px;
+ height:1px;
+}
+
+#sm2-container.swf_unblocked object,
+#sm2-container.swf_unblocked embed {
+ /* hide flash off-screen (relative to container) when it has loaded OK */
+ left:-9999em;
+ top:-9999em;
+}
+
+#sm2-container.swf_error {
+ /* when there is a fatal error (flash loaded, but SM2 failed) */
+ display:none;
+}
+
+#sm2-container.high_performance {
+ /* "high performance" case: keep on-screen at all times */
+ position:absolute;
+ position:fixed;
+ _top:-9999px; /* IE 6 hax, no position:fixed */
+ _left:-9999px;
+ bottom:0px;
+ left:0px;
+ /*
+ special case: show at first with w/h, hide when unblocked.
+ might be bad/annoying.
+ */
+ width:48px;
+ height:48px;
+ z-index:99; /* try to stay on top */
+}
+
+#sm2-container.high_performance.swf_unblocked {
+ z-index:auto;
+}
+
+#sm2-container.high_performance.swf_unblocked,
+#sm2-container.high_performance.swf_unblocked object,
+#sm2-container.high_performance.swf_unblocked embed {
+ /* 8x8px is required minimum to load in fx/win32 in some cases(?), 6x6+ good for fast performance, even better when on-screen via position:fixed */
+ width:8px;
+ height:8px;
+}
+
+#sm2-container.high_performance.swf_unblocked object,
+#sm2-container.high_performance.swf_unblocked embed {
+ /* high-performance case must stay on-screen */
+ left:auto;
+ top:auto;
+}
+
+#sm2-container.high_performance.swf_timedout {
+ z-index:99; /* try to stay on top */
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/index.html new file mode 100755 index 0000000..796308e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/index.html @@ -0,0 +1,125 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Flash Block handling examples</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Demo of SoundManager 2 handling flashblock / "click to flash" blockers gracefully" />
+<meta name="keywords" content="javascript sound, javascript audio, DHTML sound, flashblock, flash blocker, handling flashblock, click to flash, click2flash" />
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
+<!-- design template, you don't need this -->
+<link rel="stylesheet" type="text/css" href="../index.css" />
+<link rel="stylesheet" type="text/css" href="../debug.css" />
+
+<!-- actual flashblock demo stuff, this is for you -->
+<link rel="stylesheet" type="text/css" href="flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+
+<script type="text/javascript">
+// enable flash block handling
+soundManager.useFlashBlock = true; // make sure you check and use flashblock.css too, as that is used to position the SWF with this feature on!
+
+// custom demo options, not for your needs
+soundManager.debugMode = true;
+soundManager.url = '../../swf/';
+
+// flash version URL switch (for this demo page)
+var winLoc = window.location.toString();
+if (winLoc.match(/flash9/i)) {
+ soundManager.flashVersion = 9;
+ if (winLoc.match(/highperformance/i)) {
+ soundManager.useHighPerformance = true;
+ }
+} else if (winLoc.match(/flash8/i)) {
+ soundManager.flashVersion = 8;
+}
+
+soundManager.onready(function(){
+ var ok = soundManager.supported();
+ var loaded = soundManager.getMoviePercent();
+ var msg = null;
+ if (!ok) {
+ // loaded, or no?
+ msg = 'No response (yet), flash movie '+(loaded?'loaded OK (likely security/error case)':'has not loaded (likely flash-blocked.)')+' Waiting indefinitely ...';
+ } else {
+ msg = 'SoundManager load OK';
+ }
+ document.getElementById('sm2-status').innerHTML = msg;
+});
+
+</script>
+</head>
+<body>
+
+<div style="margin:1em;max-width:60em;font-size:110%">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a>: Flashblock / "click to flash" handling demos</h1>
+
+ <h3>Show SWF inline, wait indefinitely for load (click-to-run or whitelist)</h3>
+
+ <p class="note">You can run this demo with <a href="#flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (default), <a href="#flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal mode) or <a href="#flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance mode</a> (higher JS callback frequency).</p>
+
+ <h4>Where (and when) to show the SWF</h4>
+
+ <p>To handle potential flash block cases, put <code><div id="sm2-container"></div></code> in your markup where you'd like the SWF to appear in those cases. If not specified, SM2 will create and append the <code>#sm2-container</code> node to the document when it starts.</p>
+
+ <p>When <code>soundManager.useFlashBlock</code> is true, SM2 will not apply styles (eg. <code>style.position.left</code>) directly to the flash; rather, it will assign CSS classes and you can handle it as you choose. Take a look at <a href="#flashblock-css">the related CSS</a> file you will also need if you turn this feature on.</p>
+
+ <h4>Handling failed start-up cases</h4>
+
+ <p>In the blocked/failed start-up case, <code>#sm2-container</code> will have a class name of <code>swf_timedout</code> applied to it.</p>
+
+ <p>SM2 will start its init process, and will fire <code>onready()</code>, <code>onload()</code> and <code>onerror()</code> handlers accordingly. Keep in mind that while <code>onerror()</code> may fire at first, it may be preceded by a successful <code>onload()</code> if the user first loads the page and then later unblocks the flash movie.</p>
+
+ <p>Note that flash blockers may not run when viewing offline (via <code>file://</code>) content, so try viewing this demo online. For FlashBlock (under Firefox), you can also go to <code>about:config</code> using your address bar and change the value of <code>flashblock.blockLocal</code> to test while offline.</p>
+
+ <h3>Flash Block Example</h3>
+
+ <p>Here, Flash is appended by SM2 to the <code>#sm2-container</code> DIV and after a failed start attempt (if you have a blocker active), will have a <code>swf_timedout</code> class appended.</p>
+
+ <p>The SWF uses <code>position:absolute</code> and negative left/top values so as not to affect the normal page layout, but shifts to <code>left:auto;top:auto</code> (effectively left/top:0) in the blocked case, and becomes visible to the user. On a successful unblock, the movie goes back to left/top:-9999em and is hidden from view.</p>
+
+ <p>SoundManager 2 load status: <b id="sm2-status">Loading...</b></p>
+
+ <!-- here is where the SWF is shown in the blocked / failed start-up case. -->
+
+ <div id="sm2-container">
+ <!-- flash is appended here -->
+ </div>
+
+ <h3 id="flashblock-css">Flash Block-related CSS</h3>
+
+ <p>When <code>soundManager.useFlashBlock</code> is enabled, CSS is applied to <code>#sm2-container</code> depending on the progress of SM2's start-up.</p>
+ <p>This page + demos use the rules below, fully-defined and commented in <a href="flashblock.css">flashblock.css</a>. Use it as a base for your own SM2 + flash block implementations.</p>
+
+<pre class="block"><code>#sm2-container {
+ <span><span>/* Initial state: position:absolute/off-screen, or left/top:0 */</span></span>
+}
+#sm2-container.swf_timedout {
+ <span><span>/* Didn't load before time-out, show to user.
+ Maybe highlight on-screen, red border, etc..? */</span></span>
+}
+#sm2-container.swf_unblocked {
+ <span><span>/* Applied if movie loads successfully
+ (flash started, so move off-screen etc.) */</span></span>
+}
+#sm2-container.swf_error {
+ <span><span>/* "Fatal" error case: SWF loaded,
+ but SM2 was unable to start for some reason.
+ (Flash security or other error case.) */</span></span>
+}
+#sm2-container.high_performance {
+ <span><span>/* Additional modifier for "high performance" mode
+ should apply position:fixed and left/bottom 0 to stay on-screen
+ at all times (better flash performance) */</span></span>
+}
+#sm2-container.flash_debug {
+ <span><span>/* Additional modifier for flash debug output mode
+ should use width/height 100% so you can read debug messages */</span></span>
+}</code></pre>
+
+ <h3>Basic Demo</h3>
+
+ <p>For a more minimal example, see the <a href="basic.html" title="SoundManager 2: Basic Flashblock handling demo">basic flashblock demo</a>.</p>
+
+</div> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.css new file mode 100755 index 0000000..d8a9e69 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.css @@ -0,0 +1,61 @@ +#sm2-container {
+ /* where the SM2 flash movie goes. */
+ position:relative;
+}
+
+#sm2-container,
+#sm2-container embed,
+#sm2-container.swf_timedout {
+ /* 48px square flash placeholder is typically used by blockers */
+ width:48px;
+ height:48px;
+}
+
+#sm2-container.swf_timedout {
+ /* likely a flash block situation. Maybe make it more bold, red, show descriptive nested elements? */
+ border:1px solid red;
+}
+
+#sm2-container object,
+#sm2-container embed {
+ /* hide flash off-screen by default */
+ position:absolute;
+ left:-9999em;
+ top:-9999em;
+}
+
+#sm2-container.swf_timedout object,
+#sm2-container.swf_timedout embed {
+ /* when blocked, make visible inside container */
+ left:auto;
+ top:auto;
+}
+
+#sm2-container object,
+#sm2-container embed {
+ /* 6x6 is small enough to be "invisible" and not blocked by click2flash if allowed, also enough to be really fast/performant on-screen */
+ width:48px;
+ height:48px;
+}
+
+#sm2-container.swf_unblocked,
+#sm2-container.swf_unblocked object,
+#sm2-container.swf_unblocked embed {
+ width:6px;
+ height:6px;
+}
+
+#sm2-container.high_performance {
+ position:absolute;
+ position:fixed;
+ _top:0px; /* IE 6 hax */
+ bottom:0px;
+ left:0px;
+}
+
+#sm2-container.high_performance object,
+#sm2-container.high_performance embed {
+ position:absolute;
+ left:0px;
+ top:0px;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.js new file mode 100755 index 0000000..f96cf46 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/flashblock.js @@ -0,0 +1,90 @@ +/*
+
+ FlashBlock handler for SoundManager 2
+ -------------------------------------------------------------------
+ Attempt to handle and gracefully recover from flashblock conditions
+ Requires SoundManger v2.95a.20090717+
+
+ http://schillmania.com/projects/soundmanager2/
+
+*/
+soundManager._flashBlock = new function() {
+
+ var _s = this;
+ this.name = 'soundManager._flashblock';
+ this.didTimeout = false; // did initial attempt fail?
+ this.timer = null; // for setTimeout call
+
+ this.startTimer = function(nMsec) {
+ // soundManager._wD(_s.name+'_.starttimer()');
+ _s.timer = window.setTimeout(_s.checkFlashStatus,nMsec);
+ };
+
+ this.stopTimer = function() {
+ // soundManager._wD(_s.name+'.stoptimer()');
+ if (_s.timer) {
+ window.clearTimeout(_s.timer);
+ _s.timer = null;
+ }
+ };
+
+ this.checkFlashStatus = function() {
+ // soundManager._wD(_s.name+'.checkflashstatus()');
+ var _sm = soundManager;
+ var oMC = _sm.oMC; // DIV (default: #sm2-container) for .SWF
+ var oStatus = document.getElementById('sm2-status'); // demo-only
+
+ if (!_sm.supported()) {
+ // make the movie more visible, so user can fix
+ oMC.className = 'swf-timedout';
+ _s.didTimeout = true;
+ var msg = 'No flash response, applying .swf-timedout CSS..';
+ _sm._wD(_s.name+': '+msg);
+ if (oStatus) {
+ oStatus.innerHTML = '<span style="color:#996633">'+msg+'</span>';
+ }
+ } else {
+ // SM2 loaded OK
+ // move the movie container to its proper place
+ oMC.className = 'swf-loaded';
+ if (!_s.didTimeout) {
+ // SM2 didn't previously fail, no blocker active
+ var msg = 'SM2 loaded OK (before timeout), fast unblock or no blocker.';
+ _sm._writeDebug(_s.name+'.checkFlashStatus: '+msg,1);
+ if (oStatus) {
+ oStatus.innerHTML = '<span style="color:green">'+msg+'</span>';
+ }
+ } else {
+ var msg = 'SM2 recovered after block (or timeout), loaded OK.';
+ _sm._wD(_s.name+': '+msg);
+ if (oStatus) {
+ oStatus.innerHTML = '<span style="color:#996633">'+msg+'</span>';
+ }
+ }
+ // stop timer, if applicable
+ _s.stopTimer();
+ return false;
+ }
+ };
+
+ soundManager.flashLoadTimeout = 0; // wait forever for flash to load - we'll set our own timeout via oninitmovie()
+
+ soundManager.oninitmovie = function() {
+ // when SWF is written (or ready to start), wait and make SWF visible (time-out case)
+ soundManager._flashBlock.startTimer(750);
+ };
+
+ soundManager.onready(function(oStatus) {
+ // SM2 has now initialized, either no blocking OR blocked movie was allowed/whitelisted
+ var fb = soundManager._flashBlock;
+ if (oStatus.success) {
+ // Yay! recovered OK.
+ fb.checkFlashStatus();
+ } else {
+ // Blocking was passed (or no blocking), but then something *else* went wrong.
+ }
+ // stop timer, if applicable
+ fb.stopTimer();
+ });
+
+}();
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/index.html new file mode 100755 index 0000000..c8acee7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/flashblock/method1/index.html @@ -0,0 +1,79 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Flash blocker handling examples</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Demo of SoundManager 2 handling flashblock / "click to flash" blockers gracefully" />
+<meta name="keywords" content="javascript sound, javascript audio, DHTML sound, flashblock, flash blocker, handling flashblock, click to flash" />
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
+<!-- design template, you don't need this -->
+<link rel="stylesheet" type="text/css" href="../../index.css" />
+<link rel="stylesheet" type="text/css" href="../../debug.css" />
+
+<!-- actual flashblock demo stuff, this is for you -->
+<link rel="stylesheet" type="text/css" href="flashblock.css" />
+<script type="text/javascript" src="../../../script/soundmanager2.js"></script>
+
+<script type="text/javascript">
+// custom demo options, not for your needs
+soundManager.debugMode = true;
+soundManager.url = '../../../swf/';
+
+// flash version URL switch (for this demo page)
+var winLoc = window.location.toString();
+if (winLoc.match(/flash9/i)) {
+ soundManager.flashVersion = 9;
+ if (winLoc.match(/highperformance/i)) {
+ soundManager.useHighPerformance = true;
+ }
+} else if (winLoc.match(/flash8/i)) {
+ soundManager.flashVersion = 8;
+}
+
+soundManager.onready(function(){
+ var ok = soundManager.supported();
+ var loaded = soundManager.getMoviePercent();
+ var msg = null;
+ if (!ok) {
+ // loaded, or no?
+ msg = 'No response (yet), flash movie '+(loaded?'loaded OK (likely security/error case)':'has not loaded (likely flash-blocked.)')+' Waiting indefinitely ...';
+ } else {
+ msg = 'SoundManager load OK';
+ }
+ document.getElementById('sm2-status').innerHTML = msg;
+});
+
+</script>
+</head>
+<body>
+
+<div style="margin:1em;max-width:60em;font-size:110%">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a>: Flashblock / "click to flash" handling demos</h1>
+
+ <h3>Show SWF inline, wait indefinitely for load</h3>
+
+ <p class="note">You can run this demo with <a href="#flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (default), <a href="#flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal mode) or <a href="#flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance mode</a> (higher JS callback frequency).</p>
+
+ <p>Typically SM2 appends a DIV and hides the SWF off-screen. To handle potential flash block cases, a flash container DIV with an ID of "sm2-container" is placed in the HTML. SM2 will find and append the flash movie to this element. In this case, the SWF can be targeted with CSS and is not positioned off-screen as it normally would be.</p>
+ <p>SM2 will start its init process, and will fire <code>onready()</code>, <code>onload()</code> and <code>onerror()</code> handlers accordingly. Keep in mind that while <code>onerror()</code> may fire at first, it may be preceded by a successful <code>onload()</code> if the user first loads the page and then later unblocks the flash movie.</p>
+ <p>Note that flash blockers may not run when viewing offline (via <code>file://</code>) content, so try viewing this demo online. For FlashBlock (under Firefox), you can also adjust <code>flashblock.blockLocal</code> under <code>about:config</code> in the address bar to test while offline.</p>
+
+ <p>CSS applied to <code>#sm2-container</code>, depending on state:</p>
+<pre class="block"><code>#sm2-container.movieContainer {<span><span>/* Initial state: position:absolute/off-screen, or inline/relative */</span></span>}
+#sm2-container.swf_timedout {<span><span>/* Didn't load before time-out, show to user: On-screen, red border, etc..? */</span></span>}
+#sm2-container.swf_unblocked {<span><span>/* Applied if a timeout followed by an unblock (flash started.) Move off-screen. */</span></span>}
+#sm2-container.high_performance {<span><span>/* Additional modifier for "high performance" mode, should apply position:fixed and left/bottom 0 to stay on-screen at all times (better flash performance) */</span></span>}
+#sm2-container.flash_debug {<span><span>/* Additional modifier for flash debug output mode, should use width/height 100% so you can read debug messages */</span></span>}
+#sm2-container.swf_error {<span><span>/* Additional modifier, "something really broke" (fatal: security, missing SWF etc.) */</span></span>}</code></pre>
+
+ <p>SoundManager 2 load status: <b id="sm2-status">Loading...</b></p>
+
+ <p>Take a look at <a href="flashblock.css">flashblock.css</a> for implementation details.</p>
+
+ <div id="sm2-container">
+ <!-- flash is appended here -->
+ </div>
+
+</div> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/index.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.css new file mode 100755 index 0000000..b2493a6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.css @@ -0,0 +1,1715 @@ +body {
+ background:#fff;
+ margin:0px;
+ padding:0px;
+ font:75% "helvetica neue",helvetica,arial,verdana,tahoma,"sans serif";
+}
+
+h1,
+h2.special {
+ letter-spacing:-0.025em;
+}
+
+h1, h2, h3, h4 {
+ font-size:1em;
+ margin:0px;
+ padding:0px;
+ vertical-align:middle;
+}
+
+h4.new,
+h4.recent,
+h4.flash9 {
+ min-height:24px;
+}
+
+h1 {
+ font-size:2em;
+}
+
+h2 {
+ font-family:helvetica,arial,verdana,tahoma,"sans serif";
+ font-size:1.5em;
+}
+
+h3 {
+ font-size:1.17em;
+ border-bottom:1px solid #ccc;
+ padding-bottom:0.25em;
+ margin-top:1.5em;
+}
+
+h4 {
+ margin:1.5em 0px 0.5em 0px;
+ font-size:1.15em;
+}
+
+h5 {
+ font-size:1em;
+ color:#666;
+}
+
+.c2 h5 {
+ border-bottom:1px solid #ccc;
+ padding-bottom:0.25em;
+}
+
+body.home h4 {
+ border-bottom: 1px solid #e9e9e9;
+ padding-bottom: 0.33em;
+ margin-bottom: 0.75em;
+}
+
+em em {
+ /* special highlight */
+ color:#003366;
+ background:#e9f3ff;
+ font-weight:bold;
+ margin-top:-0.3em;
+ padding:0.2em 0.25em;
+}
+
+pre {
+ border-left:2px solid #f3f3f3;
+ padding-left:0.5em;
+}
+
+dl pre {
+ border-color:#e9f3ff;
+ margin-left:-0.5em;
+}
+
+dl.alt pre {
+ border-color:#f3f3f3;
+}
+
+pre,
+code,
+pre code,
+.code,
+dt,
+#soundmanager-debug {
+ font-family:monaco,"Andale Mono","VT-100","Lucida Console","Courier New",monospace,courier,system,sans-serif;
+}
+
+pre,
+code,
+.code,
+dt,
+#soundmanager-debug {
+ font-size:11px;
+ font-weight:normal;
+ line-height:1.5em;
+ color:#006699;
+ background:#f6fcff;
+}
+
+pre {
+ font-size:11px; /* x-small */
+ line-height:1.75em;
+}
+
+pre.specialcommentblock span span {
+ *line-height:1.75em;
+}
+
+pre span span {
+ /* font-size:x-small; */
+}
+
+pre.small {
+ font-size:90%;
+}
+
+p pre,
+p.in pre {
+ font-size:0.97em;
+}
+
+#soundmanager-debug {
+ background:#fff;
+ padding-left:0.75em;
+ border:2px solid #ddeeff;
+ font-size:11px;
+ line-height:1.7em;
+}
+
+body.home #soundmanager-debug {
+ position:fixed;
+ _position:absolute; /* IE <7 */
+ bottom:1em;
+ right:1em;
+ height:12em;
+ width:auto;
+ overflow:auto;
+ padding:0px;
+ margin:1em 6px 6px 1em;
+ opacity:0.95;
+ color:#333;
+ border:1px solid #ccddee;
+ -moz-border-radius:3px;
+ -khtml-border-radius:3px;
+ -webkit-border-radius:3px;
+ background:#f3f9ff;
+ z-index:10;
+ font-size:small;
+ line-height:1.2em;
+}
+
+body.home #soundmanager-debug div {
+ padding-left:0.5em;
+}
+
+#soundmanager-debug div {
+ margin:0px;
+ padding:0.25em 0px;
+ font-size:11px;
+ color:#333;
+}
+
+#soundmanager-debug div.sm2-alt {
+ background-color:#fff;
+ color:#556677;
+}
+
+#live-debug {
+ display:table;
+ *display:block;
+}
+
+#live-debug #soundmanager-debug .sm2-alt {
+ background-color:#f3f9ff;
+ color:#336699;
+}
+
+dd pre,
+dd code {
+ background:transparent;
+/*
+ font-size:1.15em;
+ *font-size:1em;
+*/
+}
+
+pre code {
+ font-size:1em;
+}
+
+pre {
+ white-space:-moz-pre-wrap;
+ white-space:pre-wrap;
+ word-wrap:break-word; /* IE */
+}
+
+pre span,
+code span,
+dt span {
+ color:#339933;
+}
+
+pre span span,
+code span span,
+dt span span {
+ color:#667788;
+}
+
+pre.block,
+pre.block code,
+div.block div.code {
+ position:relative;
+ display:table;
+ *display:block;
+ border:1px solid #ccc;
+ -moz-border-radius:3px;
+ -khtml-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+div.block,
+pre.block {
+ background:#e9f3ff;
+ border-color:#eee;
+ padding:3px;
+}
+
+pre.block code,
+div.block div.code {
+ background:#fff;
+ border:1px solid #ccddee;
+ padding:0.5em;
+ font-size:11px;
+ line-height:1.75em;
+}
+
+dl {
+ background:#f9fcff;
+ padding-bottom:1px;
+}
+
+dd {
+ margin:1em 0px;
+ padding:0px 0.5em;
+ line-height:1.5em;
+}
+
+dt {
+ margin:0px;
+ padding:0px;
+ margin:0.5em 0px 1em 0px;
+ border-bottom:1px solid #ddeeff;
+ padding:0.3em 0.3em 0.4em 0.3em;
+ padding-top:0.5em;
+ text-indent:0.25em;
+ background:#eef6ff;
+ font-size:1.15em;
+}
+
+dt.alt {
+ background:#f3f3f3;
+ border-bottom-color:#e6e6e6;
+}
+
+dl.alt {
+ background:#fcfcfc;
+ padding:0px 0px 1px 0px;
+}
+
+h2 {
+ padding-top:0.5em;
+}
+
+#top {
+ position:relative;
+ padding:1em 1em 0px 1em;
+ background:#222;
+ color:#fff;
+ z-index:1;
+}
+
+#top,
+#top div {
+ *zoom:1;
+}
+
+#top h1 {
+ /* special christmas light case */
+ display:inline;
+}
+
+#top h2 {
+ /* tagline */
+ font-size:1.25em;
+ font-weight:lighter;
+ padding-top:2px;
+ letter-spacing:-1px;
+}
+
+#main {
+ position:relative;
+ padding:0px 0px 2em 0px;
+ padding-top:1px;
+ margin:0px auto;
+ max-width:110em;
+ *padding:0px 1em 2em 1em;
+ zoom:1;
+}
+
+.columnar {
+ position:relative;
+ margin:0px;
+ padding:0px;
+ margin:2em 0.5em 0.5em 0.5em;
+}
+
+.columnar .c1 {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:20em;
+ height:30px;
+ _position:relative; /* IE 6 hackery */
+ _height:auto;
+}
+
+#doc .columnar .c1 {
+ left:auto;
+ right:1em;
+ _right:auto;
+}
+
+.columnar .c1 h2 {
+ position:relative;
+ font-size:1.2em;
+ padding:0.46em 0.5em;
+ vertical-align:middle;
+ background:#333;
+ color:#fff;
+}
+
+.columnar .c1 p {
+ margin:0.5em 0px 1em 0px;
+ padding-left:0.5em;
+ padding-right:0.5em;
+ font-size:0.95em;
+ line-height:1.35em;
+ color:#666;
+}
+
+.columnar .c1 p code {
+ font-size:xx-small;
+ color:#336699;
+}
+
+.columnar .c2 {
+ position:relative;
+ margin-top:2.33em;
+ margin-top:1px;
+ border-top:0.25em solid #333;
+ margin-left:22em;
+ margin-bottom:1.5em;
+}
+
+.triple .columnar .c2 {
+ margin-right:21.25em;
+ min-width:20em;
+}
+
+#doc .triple .columnar .c2 {
+ margin-left:21.5em;
+ margin-right:23em;
+ _margin-right:0px; /* not you, IE 6. */
+}
+
+#doc .triple .columnar .c1 {
+ margin-right:0px;
+ margin-left:21.25em;
+}
+
+.columnar .c2 p:first-child {
+ margin-top:0.2em;
+}
+
+.columnar .c2 h3:first-child {
+ margin-top:0.2em;
+ padding-bottom:0.3em;
+}
+
+.columnar .c2 > .f-block:first-child > h4 {
+ margin-top:0.5em;
+}
+
+.columnar .c2 strong strong {
+ display:block;
+ padding:0.5em;
+ border-bottom:1px solid #999;
+ background:#f0f6ff;
+ color:#336699;
+}
+
+.columnar .c2 p {
+ line-height:1.5em;
+}
+
+.three .columnar {
+ position:relative;
+}
+
+.three .columnar .c1 {
+ position:relative;
+ width:20em;
+}
+
+.three .columnar .c2 {
+ position:relative;
+ margin-right:16em;
+}
+
+.c3 {
+ position:absolute;
+ right:1em;
+ margin-right:16px;
+ top:2em;
+ width:16em;
+ margin-top:-0.5em;
+}
+
+#doc .c3 {
+ right:auto;
+ margin-right:0px;
+ margin-left:16px;
+ left:1.25em;
+}
+
+#nav {
+ position:relative;
+ margin-top:0.75em;
+ margin-left:-0.5em;
+}
+
+ul {
+ line-height:1.5em;
+}
+
+#nav ul {
+ margin:0px;
+ padding:0px;
+ line-height:1em;
+ list-style-type:none;
+}
+
+#nav>ul {
+/*
+ border-top:1px solid #333;
+*/
+}
+
+#nav ul li {
+ position:relative;
+ margin:0px;
+ padding:0px;
+ float:left;
+ display:inline;
+ padding-right:1px;
+}
+
+#nav ul li ul {
+ position:absolute;
+ z-index:1;
+ display:none;
+ min-width:17em;
+ max-width:20em;
+ background:#3399cc;
+ opacity:0.95;
+ _width:17em;
+ *opacity:1;
+ *top:1.5em;
+ *left:0px;
+}
+
+#nav ul li:last-child ul {
+ right:1px;
+}
+
+
+#nav ul li:hover ul,
+#nav ul li ul:hover {
+ display:block;
+}
+
+#nav ul li ul li {
+ float:none;
+ display:block;
+ width:100%;
+}
+
+#nav ul li ul li a {
+ display:block;
+ width:auto;
+ border:none;
+ padding:0.4em;
+ padding-left:1em;
+ color:#fff;
+}
+
+#nav ul li a {
+ display:inline-block;
+ padding:0.3em 0.5em;
+ padding-left:0.75em;
+ padding-right:0.75em;
+ text-decoration:none;
+ font-weight:bold;
+ color:#ccc;
+}
+
+#nav ul li strong a {
+ background:#336699;
+ background:#;
+ background:#fff;
+ color:#333;
+}
+
+#nav ul li strong a:hover,
+#nav ul li a:hover,
+#nav ul>li:hover strong a,
+#nav ul>li:hover>a {
+ background:#3399cc;
+ color:#fff;
+}
+
+#nav ul li ul li a:hover {
+ background:#336699;
+}
+
+#version {
+ position:relative;
+ float:right;
+ display:inline;
+ margin-left:1em;
+ font-size:x-small;
+ margin-bottom:0px;
+ margin-top:0.25em;
+ color:#999;
+}
+
+div.clear {
+ clear:both;
+ font-size:1px;
+ line-height:1px;
+}
+
+.note {
+ margin-top:0.5em;
+ font-size:0.95em;
+ color:#999;
+}
+
+.note a {
+ color:#666;
+ padding:1px;
+ margin:-1px;
+}
+
+.note a:hover {
+ color:#fff;
+ background:#666;
+}
+
+ul.standard {
+ line-height:1.5em;
+ padding-left:1.2em;
+ *padding-left:0px;
+ color:#333;
+ margin-top:0.5em;
+ margin-bottom:0.5em;
+ list-style-type:square;
+}
+
+ul.standard li {
+ margin-bottom:0.5em;
+}
+
+ul.standard ul {
+ margin-top:0.5em;
+ margin-bottom:1em;
+ padding-left:1.2em;
+}
+
+.c3 {
+ background:#fcfcfc;
+}
+
+.c3 ul {
+ list-style-type:none;
+}
+
+.c3 ul,
+.c3 ul li {
+ margin:0px;
+ padding:0px;
+}
+
+.c3 h2 {
+ font-size:1.1em;
+ text-indent:0.4em;
+}
+
+.c3 ul li a {
+ text-decoration:none;
+ color:#000;
+}
+
+.c3 ul li a:hover {
+ color:#000;
+ _color:#000;
+}
+
+.c3 ul li a:focus {
+ color:#000;
+ outline:none;
+}
+
+.c3 ul li.active a {
+ color:#fff;
+}
+
+.c3 ul li.active a:hover {
+ _color:#fff;
+}
+
+.c3 .box {
+ margin-top:6px;
+}
+
+.wedge,
+.c3 h2 {
+ position:relative;
+ background:#333;
+ color:#fff;
+ margin:0px;
+ padding:0px;
+ height:2.101em;
+ line-height:1.65em;
+}
+
+.c3 h2 {
+ height:1.75em;
+ line-height:1.75em;
+}
+
+.wedge {
+ background-color:#3399cc;
+}
+
+.wedge-dark {
+ background:#333;
+}
+
+.wedge .l,
+.wedge .r {
+ border-top:1.75em solid #333;
+}
+
+.c3 h2 .l,
+.c3 h2 .r {
+ border-top:1.66em solid #333;
+}
+
+.wedge .l,
+.c3 h2 .l {
+ background:transparent url(../demo/_image/wedge.png) no-repeat -64px 0px;
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:16px;
+ height:100%;
+ margin-left:-16px;
+ border-top:1.7em solid #333;
+}
+
+.wedge .r,
+.wedge-dark .r,
+.c3 h2 .r {
+ background:transparent url(../demo/_image/wedge.png) no-repeat -48px 0px;
+ position:absolute;
+ right:0px;
+ top:0px;
+ width:16px;
+ height:100%;
+ margin-right:-16px;
+}
+
+.wedge .l,
+.wedge .r {
+ border-color:#3399cc;
+}
+
+.wedge .l {
+ background-position:-64px -64px;
+}
+
+.wedge .r {
+ margin-top:-16px;
+ border-top:none;
+ height:16px;
+ border-bottom:1.7em solid #3399cc;
+ background-position:0px -192px;
+}
+
+.wedge-dark .l,
+.wedge-dark .r {
+ border-color:#333;
+}
+
+.wedge-dark .l {
+ background-position:-64px 0px;
+}
+
+.wedge-dark .r {
+ background-position:0px -128px;
+}
+
+.c3 h2 .r.up {
+ margin-top:-16px;
+ border-top:none;
+ height:16px;
+ border-bottom:1.66em solid #333;
+ background-position:0px -128px;
+}
+
+.c3 h2 .l.flat,
+.wedge .l.flat,
+.c3 h2 .r.flat,
+.wedge .r.flat {
+ background-image:none;
+}
+
+.c3 ul {
+ margin:0px;
+ padding:0px;
+ margin-top:0.125em;
+ margin-bottom:0.25em;
+ list-style-type:none;
+}
+
+.c3 ul li {
+ border:1px solid #f3f3f3;
+ border-top:none;
+ border-bottom:none;
+}
+
+.c3 ul ul li {
+ border:none;
+}
+
+.c3 ul li {
+ margin:0px;
+ padding:0px;
+}
+
+.c3 ul li ul li {
+ font-family:monaco,"Andale Mono","VT-100","Lucida Console","Courier New",monospace,courier,system,sans-serif;
+ font-size:11px;
+ line-height:1.5em;
+ text-indent:0.5em;
+ padding:0.25em 0.25em 0.25em 0.25em;
+ cursor:hand;
+/*
+ font-smooth:never;
+*/
+}
+
+.c3 ul li ul li.alt {
+ background-color:#f8f8f8;
+}
+
+.c3 ul li ul li:hover {
+ background-color:#ccddff;
+ cursor:pointer;
+ cursor:hand;
+}
+
+.c3 ul li ul li.active {
+ background-color:#3399cc;
+ color:#fff;
+}
+
+.c3 h3 {
+ margin:0px;
+ padding:0px;
+ background:#3399cc;
+ border:none;
+ color:#fff;
+ font-size:1.3em;
+ text-indent:0.5em;
+ font-size:1em;
+ height:1.67em;
+ padding:0.25em 0.5em;
+ padding:0px;
+
+}
+
+.c3 h4 {
+ font-size:1em;
+ margin:1em 0.25em 0.25em 0.25em;
+ padding:0px 0.25em;
+ padding:0.2em 0.2em 0.2em 0.5em;
+ vertical-align:middle;
+ margin:0px;
+ color:#333;
+ background:#eef6ff;
+ border-top:1px solid #fff;
+ border-bottom:1px solid #ddeeff;
+}
+
+#get-satisfaction h2 a {
+ color:#fff;
+}
+
+#get-satisfaction a {
+ color:#333;
+}
+
+#get-satisfaction a:hover {
+ color:#fff;
+}
+
+.c3 h2 a {
+ color:#fff;
+}
+
+.c3 h2 a:hover {
+ color:#fff;
+ text-decoration:underline;
+}
+
+.flash9 {
+ background-image:url(../demo/_image/flash9.png);
+ background-repeat:no-repeat;
+ background-position:bottom right;
+ _background-image:none;
+}
+
+li.flash9 {
+ background-position:bottom right;
+}
+
+.flash9.active {
+ background-image:url(../demo/_image/flash9-dark.png);
+ _background-image:none;
+}
+
+.new {
+ background-image:url(../demo/_image/new.png);
+ background-repeat:no-repeat;
+ background-position:bottom right;
+ _background-image:none;
+}
+
+.recent {
+ background-image:url(../demo/_image/new-bw.png);
+ background-repeat:no-repeat;
+ background-position:bottom right;
+ _background-image:none;
+}
+
+.new.active,
+.recent.active {
+ background-image:url(../demo/_image/new-dark.png);
+ _background-image:none;
+}
+
+li.new {
+ background-position:top right;
+}
+
+span.nevermind,
+.removed {
+ text-decoration:line-through;
+ opacity:0.75;
+}
+
+.padded {
+ padding:0.5em;
+}
+
+.c3 p {
+ font-size:0.9em;
+ padding-left:0.5em;
+ padding-right:0.5em;
+}
+
+.c1 pre code {
+ margin-top:0px;
+ font-size:xx-small;
+ color:#336699;
+ margin-left:0px;
+}
+
+.c1 pre {
+ margin-top:0px;
+ padding-top:0px;
+ margin-left:0.5em;
+}
+
+#reset-filter {
+ position:relative;
+ font-family:"Helvetica Neue Light","Helvetica Neue","Helvetica",helvetica,arial,verdana,sans-serif;
+ font-weight:lighter;
+ font-size:2.5em;
+ letter-spacing:-1px;
+}
+
+.c2 .option {
+ font-size:small;
+ float:right;
+ display:inline;
+ margin-left:1em;
+ margin-right:0.5em;
+ margin-top:3px;
+ line-height:1em;
+ white-space:nowrap;
+}
+
+.c2 .option a {
+ padding:0.1em 0.35em 0.1em 0.35em;
+ color:#3399cc;
+}
+
+/*
+.c2 .option a:hover {
+ background-color:#3399cc;
+ color:#fff;
+}
+*/
+
+#filter-box {
+ position:relative;
+ display:none;
+}
+
+#get-satisfaction {
+ position:relative;
+}
+
+#gsfn_content {
+ padding:0.5em 0px 0px 0px;
+}
+
+#gsfn_content ul {
+ margin-bottom:0.5em;
+}
+
+#gsfn_content ul li {
+ border:none;
+}
+
+div#gsfn_list_widget img {
+ border: none;
+}
+
+div#gsfn_list_widget a {
+ text-decoration:none;
+}
+
+div#gsfn_list_widget a.widget_title {
+ display: block;
+ margin-bottom: 10px;
+ font-weight: bold;
+}
+
+div#gsfn_list_widget .powered_by {
+ font-family:verdana,arial;
+ margin:0px 1em 0px 1em;
+ padding:0.25em 0px 0px 0px;
+ border-top: 1px solid #ccc;
+ font-size:xx-small;
+ opacity:0.5;
+}
+
+div#gsfn_list_widget .powered_by:hover {
+ opacity:1;
+}
+
+div#gsfn_list_widget .powered_by a:hover {
+ color:#666;
+}
+
+div#gsfn_list_widget div#gsfn_content {
+ font-size:x-small;
+ font-size:0.9em;
+ padding-left:0.5em;
+ padding-right:0.5em;
+}
+
+div#gsfn_list_widget div#gsfn_content li {
+ text-align:left;
+ position: relative;
+ clear:right;
+ *zoom:1;
+}
+
+div#gsfn_list_widget div#gsfn_content li:hover,
+div#gsfn_list_widget div#gsfn_content li:hover a {
+ background:#3399cc;
+ color:#fff;
+}
+
+div#gsfn_list_widget div#gsfn_content a.gsfn_link {
+ display:block;
+ line-height:1.2em;
+ padding:5px 0px 5px 5px;
+}
+
+div#gsfn_list_widget div#gsfn_content a.gsfn_link:hover {
+ _color:#fff;
+ _background-color:#3399cc;
+}
+
+div#gsfn_list_widget div#gsfn_content span.time {
+ font-size: xx-small;
+ color:#999;
+ padding-left:3px;
+ padding-right:3px;
+ text-align:right;
+ float:right;
+ display:inline;
+ margin-top:1px;
+}
+
+div#gsfn_list_widget div#gsfn_content li:hover span.time {
+ color:#fff;
+}
+
+div#gsfn_list_widget div#gsfn_content p.gsfn_summary {
+ margin-top: 2px;
+ position:relative;
+ z-index:2;
+}
+
+.tight {
+ margin-top:0px;
+}
+
+.compact {
+ margin-bottom:0.25em;
+}
+
+.c2 a,
+a.cta {
+ margin-top:-0.3em;
+ padding:0.2em 0.25em;
+ text-decoration:none;
+ color:#3399cc;
+ -khtml-border-radius:0.25em;
+ -moz-border-radius:0.25em;
+ border-radius:0.25em;
+ zoom:1;
+}
+
+/* redefine for simple mp3 button demo */
+.c2 a.sm2_button {
+ -moz-border-radius:6px;
+ -webkit-border-radius:6px;
+ -o-border-radius:6px;
+ border-radius:6px;
+}
+
+.c2 a.sm2_button.type-2 {
+ -moz-border-radius:9px;
+ -webkit-border-radius:9px;
+ -o-border-radius:9px;
+ border-radius:9px;
+}
+
+
+.c2 a {
+ margin-left:-0.2em;
+ margin-right:-0.2em;
+ color:#3399cc;
+ font-weight:bold;
+ text-decoration:none;
+}
+
+.c2 a.cta {
+ text-decoration:none;
+}
+
+a.cta span {
+ font-size:1.5em;
+ line-height:1em;
+}
+
+a.cta:hover,
+.c2 a:hover {
+ background-color:#3399cc;
+ border-color:#3399cc;
+ color:#fff;
+ text-decoration:none;
+}
+
+.c2 a.sm2_button:hover {
+ /* arg. not specific enough, redefine here. */
+ background-color:#cc3333;
+}
+
+a.cta-more {
+ color:#ddeeff;
+ font-size:0.8em;
+ position:absolute;
+ right:0px;
+ margin:0px;
+ padding:1px;
+ bottom:0.9em;
+ line-height:1em;
+}
+
+a.cta-more:hover {
+ background:#fff;
+ color:#3399cc;
+}
+
+li.html5support span {
+ padding:0px 5px;
+ display:inline-block;
+ text-align:center;
+ font-weight:bold;
+ background:#ccc;
+ color:#fff;
+ -moz-border-radius:5px;
+ -webkit-border-radius:5px;
+ border-radius:5px;
+ margin-left:0.5em;
+ margin-bottom:0.25em;
+}
+
+li.html5support em {
+ font-weight:bold;
+}
+
+li.html5support span.true {
+ background:#669966;
+}
+
+li.html5support span.partial {
+ background:#993333;
+}
+
+li.html5support em.partial {
+ color:#993333;
+}
+
+li.html5support em.true {
+ color:#669966;
+}
+
+#nav ul li ul {
+ /* eh, why not. */
+ -moz-box-shadow:2px 2px 2px rgba(51,153,204,0.2);
+ -khtml-box-shadow:2px 2px 2px rgba(51,153,204,0.2);
+ -webkit-box-shadow:2px 2px 2px rgba(51,153,204,0.2);
+ box-shadow:2px 2px 2px rgba(51,153,204,0.2);
+}
+
+.newer {
+ vertical-align:middle;
+}
+
+.newer a,
+a.feature,
+.c2 .feature-hot {
+ display:block;
+ background:#3399ff;
+ padding:0.3em 0.5em;
+ margin:-0.3em 0px 0px -0.5em;
+ color:#fff;
+ font-weight:bold;
+ border:3px solid #ccc;
+ border:3px solid rgba(255,255,255,0.66);
+ -moz-border-radius:8px;
+ -webkit-border-radius:8px;
+ border-radius:8px;
+ line-height:1em;
+ text-decoration:none;
+ font-size:small;
+ vertical-align:middle;
+}
+
+a.feature {
+ display:inline;
+ margin-left:0px;
+}
+
+.newer a,
+.c2 .feature-hot {
+ background:#ff0000;
+ border-color:#ff6666;
+ color:#fff;
+ line-height:1em;
+}
+
+.newer a:hover,
+.c2 .feature-hot:hover {
+ background:#990000;
+ border-color:#cc0000;
+}
+
+a.feature:focus,
+a.feature:hover {
+ background:#ff0000;
+ border-color:#ff6666;
+ color:#fff;
+}
+
+.newer p {
+ margin:0px;
+ padding:0px;
+}
+
+h4 .scratched-out {
+ text-decoration:line-through;
+ color:#999;
+ /*
+ font-size:xx-small;
+ */
+ font-size:0.9em;
+ margin-top:-0.75em;
+ -webkit-transform:rotate(-15deg);
+ -moz-transform:rotate(-15deg);
+}
+
+.inthewild {
+ margin-top:1em;
+}
+
+.inthewild a,
+.inthewild a img {
+ border:none;
+}
+
+.inthewild a {
+ margin-right:1em;
+}
+
+.inthewild a:last-child {
+ margin-right:0px;
+}
+
+.inthewild a,
+.inthewild a img {
+ vertical-align:middle;
+}
+
+.inthewild a {
+ display:inline-block;
+ display:-moz-inline-box;
+ overflow:hidden;
+ margin:1em 1em 0.5em 1em;
+ padding:0px;
+}
+
+.inthewild a:first-child {
+ margin-left:0.5em;
+}
+
+.inthewild a span {
+ position:absolute;
+ text-indent:-9999em;
+}
+
+#favtape:hover {
+ background:#ff0066;
+ border-color:#ff0066;
+ color:#fff;
+}
+
+#soundcloud {
+ width:83px;
+ height:58px;
+ background:transparent url(../demo/_image/soundcloud-thecloudplayer-logo.png) no-repeat 0px -59px;
+ margin-right:3px;
+}
+
+#soundcloud:hover {
+ background-position:0px 0px;
+}
+
+#lastfm {
+ width:80px;
+ height:28px;
+ background:transparent url(../demo/_image/lastfm.png) no-repeat 0px -28px;
+}
+
+#lastfm:hover {
+ background-position:0px 0px;
+}
+
+#mixcrate {
+ width:80px;
+ height:16px;
+ background:transparent url(../demo/_image/mixcrate.png) no-repeat 0px 0px;
+}
+
+#mixcrate:hover {
+ background-position:0px -16px;
+}
+
+#opera {
+ width:79px;
+ height:32px;
+ background:transparent url(../demo/_image/opera.png) no-repeat 0px 0px;
+}
+
+#opera:hover {
+ background-position:0px -32px;
+}
+
+/* homepage-specific demo shiz */
+
+.sidenote {
+ font-size:x-small;
+ opacity:0.75;
+}
+
+ul.playlist {
+ font-size:xx-small;
+}
+
+ul.playlist li a {
+ font-size:1em;
+}
+
+ul.playlist li a,
+ul.playlist li a:hover {
+ background:transparent;
+ -khtml-border-radius:0px;
+ -moz-border-radius:0px;
+ border-radius:0px;
+ line-height:1em;
+}
+
+ul.playlist li .timing {
+ top:0.6em;
+ font-size:xx-small;
+}
+
+ul.playlist.use-peak li .peak {
+ /* overrides */
+ height:0.61em;
+ margin-top:-5px;
+ width:0.92em;
+}
+
+html.isSafari ul.playlist.use-peak li .peak {
+ margin-top:-4px; /* dumb tweak */
+}
+
+ul.playlist.use-peak li .timing {
+ right:4em;
+}
+
+ul.playlist.use-peak li .peak-box {
+ height:0.66em;
+}
+
+ul.playlist li .peak .l {
+ margin-right:0px;
+}
+
+ul.playlist li .peak .l,
+ul.playlist li .peak .r {
+ width:6px;
+}
+
+ul.playlist li .peak .r {
+ left:9px;
+}
+
+ul.playlist li a.not-supported {
+ /* give user a hint that the format doesn't work */
+ text-decoration:line-through;
+ color:#666;
+ opacity:0.5;
+}
+
+ul.graphic li {
+ line-height:1.5em;
+}
+
+ul.graphic li a,
+ul.graphic li a.sm2_link {
+ min-width:17.75em;
+ width:auto;
+}
+
+ul.graphic li a,
+ul.graphic li a.sm2_link {
+ background-color:#ddd;
+ border-color:#ddd;
+ color:#333;
+ vertical-align:middle;
+}
+
+ul.graphic li a {
+ background:#ddd url(../demo/play-mp3-links/image/icon_play.png) no-repeat 3px 50%;
+ _background-image:url(../demo/play-mp3-links/image/icon_play.gif);
+}
+
+
+ul.graphic li a:hover,
+ul.graphic li a.sm2_paused:hover,
+ul.graphic li a.sm2_link:hover,
+ul.graphic li a.sm2_playing,
+ul.graphic li a.sm2_playing:hover {
+ background-color:#336699;
+ border-color:#336699;
+ color:#fff;
+}
+
+ul.graphic li a.sm2_link {
+ /* Doesn't work on this page. */
+ -webkit-transition-property: none;
+ -webkit-transition: none;
+}
+
+.c2 ul.playlist li a {
+ margin:0px;
+ padding:0px;
+ letter-spacing: -0.02em;
+}
+
+/* Flash positioning and flashblock / clicktoflash handling */
+
+/* special-case for the SM2 homepage only */
+
+body.home #sm2-container {
+ position:absolute;
+ width:48px;
+ height:48px;
+ margin:1px 0px 0px 1px;
+}
+
+body.home #sm2-container.high_performance {
+ bottom:auto;
+ left:auto;
+ top:auto;
+}
+
+body.home #sm2-container.swf_timedout {
+ border:1px solid #ff3333;
+ border-bottom:none;
+ margin:0px;
+ z-index:2;
+}
+
+body.home #sm2-container.swf_unblocked {
+ width:1px;
+ height:1px;
+}
+
+#sm2-support {
+ display:none;
+ font-size:1em;
+ border:1px solid #ff3333;
+ background:#fff6f0;
+ margin-top:48px;
+}
+
+#demo-box {
+ position:relative;
+ float:right;
+ display:inline;
+ background: #fff; /* hide borders behind this box */
+ padding-left:32px;
+ padding-right:16px;
+ margin-top:-1em;
+ width:21.25em;
+ /* hide from IE 6 */
+ _position:absolute;
+ _left:-9999em;
+ _top:-9999em;
+}
+
+#demo-box #without-html5 {
+ display:none;
+}
+
+#demo-box #with-debug,
+#demo-box #without-html5,
+#demo-box #without-html5 a {
+ display:inline;
+ margin-top:-0.75em;
+ font-weight:normal;
+ font-size:x-small;
+ text-decoration:none;
+ font-weight:normal;
+ color:#666;
+}
+
+#demo-box #with-debug {
+ margin-right:1.5em;
+}
+
+#demo-box #without-html5 a:hover,
+#demo-box #with-debug:hover {
+ color:#fff;
+}
+
+#demo-box a.feature-hot {
+ display:inline;
+}
+
+hr {
+ visibility:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.demo-block {
+ position:relative;
+ background:#f9f9f9;
+ border:1px solid #e6e6e6;
+ padding:4px;
+ padding-top:0.5em;
+ margin-top:-0.55em;
+ border-top:none;
+}
+
+#demo-header {
+ color:#333;
+ background:#f9f9f9;
+ border:1px solid #e6e6e6;
+ border-bottom:0px;
+ margin-bottom:0px;
+ padding:0.5em;
+}
+
+#demos h3 {
+ padding-bottom:0px;
+ text-indent:0.5em;
+ font-weight:normal;
+}
+
+#demos h3 a {
+ font-weight:normal;
+}
+
+#revision-list > li {
+ margin-bottom:2em;
+}
+
+/* seasonal decorations */
+
+#lights {
+ position:absolute;
+ border-top:1px solid #006600;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ overflow:hidden;
+ display:none;
+}
+
+.xlsf-light {
+ position:absolute;
+ margin-top:-1px;
+}
+
+body.fast .xlsf-light {
+ opacity:0.9;
+}
+
+.xlsf-light {
+ opacity:0.9;
+}
+
+.xlsf-fragment {
+ position:absolute;
+ background:transparent url(christmas-lights/image/bulbs-50x50-fragments.png) no-repeat 0px 0px;
+ width:50px;
+ height:50px;
+}
+
+.xlsf-fragment-box {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:50px;
+ height:50px;
+ *width:100%;
+ *height:100%;
+ display:none;
+}
+
+.xlsf-cover {
+ position:fixed;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ background:#fff;
+ opacity:1;
+ z-index:999;
+ display:none;
+}
+
+.figure {
+ display:inline;
+ display:inline-block;
+ border:1px solid #ddeeff;
+ padding:0.5em;
+ margin:0.5em 0px 0.5em 0px;
+}
+
+.figure .code {
+}
+
+.figure .code span {
+ padding:0.25em;
+ border:1px solid #f0f9ff;
+ background:#fff;
+}
+
+.figure .code span.mid {
+ color:#666;
+}
+
+#sm2-container.flash_debug {
+ /* flash movie, when soundManager.debugFlash = true */
+ position:relative;
+ width:auto;
+ height:300px;
+ width:100%;
+ background:#f6f6f6;
+ border:1px solid #ccc;
+}
+
+#sm2-container.flash_debug object,
+#sm2-container.flash_debug embed {
+ width:100%;
+ height:100%;
+ left:auto;
+ top:auto;
+}
+
+ul.file-structure ul {
+ padding-left:1.5em;
+}
+
+ul.file-structure li {
+ list-style-type:square;
+ margin-top:0.25em;
+ margin-left:0px;
+}
+
+ul.file-structure li span {
+ color:#999;
+}
+
+#sm2-filesizes {
+ border:1px solid #ddd;
+}
+
+#sm2-filesizes tr:nth-child(2n+1) {
+ background:#f9f9f9;
+}
+
+#sm2-filesizes th {
+ background:#eee;
+ font-weight:bold;
+ text-align:left;
+}
+
+#sm2-filesizes th {
+ padding:4px 6px;
+}
+
+#sm2-filesizes td {
+ padding:0px 6px;
+ border:1px solid #eee;
+}
+
+#sm2-filesizes p {
+ margin-top:0.5em;
+ margin-bottom:0px;
+}
+
+#sm2-filesizes pre {
+ border-left:none;
+ margin-top:0.5em;
+ margin-bottom:0.5em;
+}
+
+#sm2-filesizes .nw {
+ white-space:nowrap;
+}
+
+#sm2-filesizes .booyaa {
+ /* in the words of Paris Hilton, "that's hot." (in the nerdy sense, I suppose.) */
+ background:#fff9f9;
+ color:#990000;
+}
+
+#history li.in > p.compact {
+ font-weight:bold;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.html new file mode 100755 index 0000000..31133af --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>MP3 player demo</title> +<meta name="robots" content="noindex" />
+<meta name="author" content="Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="keywords" content="javascript sound library api" />
+<meta name="description" content="Demo page for soundmanager mp3 player" />
+<script type="text/javascript" src="../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/default.js"></script>
+</head>
+
+<body>
+
+<div>
+
+ <h1>SoundManager 2 Demos</h1>
+
+ <p>
+ <a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2 project page</a>
+ </p>
+
+</div>
+
+</body>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/index.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.js new file mode 100755 index 0000000..97140ee --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/index.js @@ -0,0 +1,368 @@ +/* SoundManager 2 - project home utility JS */
+
+function _id(sID) {
+ return document.getElementById(sID);
+}
+
+getSoundByURL = function(sURL) {
+ return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null);
+}
+
+function init() {
+ var o = document.getElementById('main');
+ var el = o.getElementsByTagName('dt');
+ for (var i=el.length; i--;) {
+ if ((i+1)%2==0) {
+ utils.addClass(el[i],'alt');
+ }
+ }
+ var el = o.getElementsByTagName('dl');
+ for (var i=el.length; i--;) {
+ if ((i+1)%2==0) {
+ utils.addClass(el[i],'alt');
+ }
+ }
+}
+
+function Utils() {
+ var self = this;
+
+ this.hasClass = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?new RegExp('(^|\\s)'+cStr+'(\\s|$)').test(o.className):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (self.hasClass(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (!self.hasClass(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.toggleClass = function(o,cStr) {
+ var m = (self.hasClass(o,cStr)?self.removeClass:self.addClass);
+ m(o,cStr);
+ }
+
+ this.getElementsByClassName = function(className,tagNames,oParent) {
+ var doc = (oParent||document);
+ var matches = [];
+ var i,j;
+ var nodes = [];
+ if (typeof(tagNames)!='undefined' && typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ if (!nodes || !nodes[tagNames[i]]) {
+ nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
+ }
+ }
+ } else if (tagNames) {
+ nodes = doc.getElementsByTagName(tagNames);
+ } else {
+ nodes = doc.all||doc.getElementsByTagName('*');
+ }
+ if (typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ for (j=nodes[tagNames[i]].length; j--;) {
+ if (self.hasClass(nodes[tagNames[i]][j],className)) {
+ matches[matches.length] = nodes[tagNames[i]][j];
+ }
+ }
+ }
+ } else {
+ for (i=0; i<nodes.length; i++) {
+ if (self.hasClass(nodes[i],className)) {
+ matches[matches.length] = nodes[i];
+ }
+ }
+ }
+ return matches;
+ }
+
+ this.findParent = function(o) {
+ if (!o || !o.parentNode) return false;
+ o = o.parentNode;
+ if (o.nodeType == 2) {
+ while (o && o.parentNode && o.parentNode.nodeType == 2) {
+ o = o.parentNode;
+ }
+ }
+ return o;
+ }
+
+ this.getOffY = function(o) {
+ // http://www.xs4all.nl/~ppk/js/findpos.html
+ var curtop = 0;
+ if (o.offsetParent) {
+ while (o.offsetParent) {
+ curtop += o.offsetTop;
+ o = o.offsetParent;
+ }
+ }
+ else if (o.y) curtop += o.y;
+ return curtop;
+ }
+
+ this.isChildOfClass = function(oChild,oClass) {
+ if (!oChild || !oClass) return false;
+ while (oChild.parentNode && !self.hasClass(oChild,oClass)) {
+ oChild = self.findParent(oChild);
+ }
+ return (self.hasClass(oChild,oClass));
+ }
+
+ this.getParentByClassName = function(oChild,sParentClassName) {
+ if (!oChild || !sParentClassName) return false;
+ sParentClassName = sParentClassName.toLowerCase();
+ while (oChild.parentNode && !self.hasClass(oChild.parentNode,sParentClassName)) {
+ oChild = self.findParent(oChild);
+ }
+ return (oChild.parentNode && self.hasClass(oChild.parentNode,sParentClassName)?oChild.parentNode:null);
+ }
+
+}
+
+var utils = new Utils();
+
+var lastSelected = null;
+
+function resetFilter(o) {
+ // reset everything
+ var oParent = null;
+ _id('filter-box').style.display = 'none';
+ utils.removeClass(_id('main'),'filtered');
+ var blocks = utils.getElementsByClassName('f-block',['div','dl'],_id('main'));
+ for (var i=blocks.length; i--;) {
+ blocks[i].style.display = 'block';
+ oParent = utils.getParentByClassName(blocks[i],'columnar',_id('main'));
+ if (oParent) oParent.style.display = 'block';
+ }
+ if (lastSelected) utils.removeClass(lastSelected,'active');
+ if (o) lastSelected = o;
+ return false;
+}
+
+function setFilter(e,sFilterPrefix) {
+ var o = e?e.target||e.srcElement:event.srcElement;
+ utils.addClass(_id('main'),'filtered');
+ var oName = o.nodeName.toLowerCase();
+ if (oName == 'a') {
+ var parent = utils.findParent(o);
+ if (parent && parent.nodeName.toLowerCase() == 'li') {
+ // normalize to LI instead.
+ o = parent;
+ oName = o.nodeName.toLowerCase();
+ }
+ }
+ var sClass = '';
+ var blocks = utils.getElementsByClassName('f-block',['div','dl'],_id('main'));
+ var oParents = utils.getElementsByClassName('columnar','div',_id('main'));
+ var oParent = null;
+ var matchingParents = [];
+ if (oName != 'li' || o.className == 'ignore') {
+ return true;
+ }
+ var isClear = (lastSelected && lastSelected == o && utils.hasClass(lastSelected,'active'));
+ if (oName == 'li' && isClear) {
+ return resetFilter();
+ }
+ if (oName == 'li') {
+ // from shortcuts/filter menu
+ var innerText = (o.getElementsByTagName('a').length?o.getElementsByTagName('a')[0].innerHTML:o.innerHTML); // get inner text (minus link, if one is there)
+ sClass = sFilterPrefix+innerText.substr(0,innerText.indexOf('()')!=-1?innerText.indexOf('()'):999).toLowerCase().replace(/\s+/i,'-');
+ var last = sClass.substr(sClass.length-1);
+ if (last == '-' || last == ' ') {
+ sClass = sClass.substr(0,sClass.length-1); // IE innerHTML trailing whitespace hack (?)
+ }
+ for (var i=blocks.length; i--;) {
+ oParent = utils.getParentByClassName(blocks[i],'columnar',_id('main'));
+ if (utils.hasClass(blocks[i],sClass)) {
+ blocks[i].style.display = 'block';
+ if (oParent) {
+ matchingParents.push(oParent);
+ }
+ } else {
+ blocks[i].style.display = 'none';
+ }
+ }
+ for (i=oParents.length; i--;) {
+ oParents[i].style.display = 'none';
+ }
+ for (i=matchingParents.length; i--;) {
+ matchingParents[i].style.display = 'block';
+ }
+ _id('search-results').innerHTML = '<h3><span class="option"><a href="#" title="Restore full content" onclick="resetFilter();return false" style="text-decoration:none"> clear filter </a></span>Content filter: '+(sFilterPrefix=='f-'?'soundManager.':(sFilterPrefix=='s-'?'[SMSound object].':''))+'<b style="font-weight:bold">'+o.innerHTML+'</b></h3>';
+ _id('search-results').style.display = 'block';
+ _id('filter-box').style.display = 'block';
+ if (isClear) {
+ _id('filter-box').style.paddingBottom = '0px';
+ _id('filter-box').style.display = 'none';
+ } else {
+ _id('filter-box').style.paddingBottom = '0px';
+ if (!navigator.userAgent.match(/msie/i)) {
+ _id('filter-box').style.paddingBottom = Math.max(0,(document.documentElement.scrollTop || window.scrollY)-utils.getOffY(_id('filter-box'))-parseInt(_id('filter-box').offsetHeight)-20)+'px';
+ }
+ _id('filter-box').style.display = 'block';
+ // if ((!document.documentElement.scrollTop && !window.scrollY)) _id('filter-box').style.display = 'none';
+ }
+ if (lastSelected) {
+ if (lastSelected == o) {
+ utils.toggleClass(lastSelected,'active');
+ } else {
+ utils.removeClass(lastSelected,'active');
+ utils.addClass(o,'active');
+ }
+ } else {
+ utils.addClass(o,'active');
+ }
+ lastSelected = o;
+ // cancel bubble, too?
+ return false;
+ }
+}
+
+function getLiveData() {
+ getDynamicData();
+ // reinvigorate.net is a handy (and free!) stats tracking service thingy. you should check it out.
+ var is_live = (document.domain && document.domain.match(/schillmania.com/i) && typeof re_ != 'undefined');
+ loadScript('http://include.reinvigorate.net/re_.js');
+ setTimeout(function(){
+ if (typeof re_ != 'undefined') re_(is_live?'f6795-v062d0xv4u':'u8v2l-jvr8058c6n');
+ },3000);
+}
+
+function getDynamicData() {
+ // Attempt to fetch data from schillmania.com: "Get Satisfaction" topics, version updates etc.
+ loadScript('http://www.schillmania.com/services/soundmanager2/info/?version='+soundManager.versionNumber+'&rnd='+parseInt(Math.random()*1048576));
+}
+
+function loadScript(sURL,onLoad) {
+ var loadScriptHandler = function() {
+ var rs = this.readyState;
+ if (rs == 'loaded' || rs == 'complete') {
+ this.onreadystatechange = null;
+ this.onload = null;
+ window.setTimeout(onLoad,20);
+ }
+ }
+ function scriptOnload() {
+ this.onreadystatechange = null;
+ this.onload = null;
+ window.setTimeout(onLoad,20);
+ }
+ var oS = document.createElement('script');
+ oS.type = 'text/javascript';
+ if (onLoad) {
+ oS.onreadystatechange = loadScriptHandler;
+ oS.onload = scriptOnload;
+ }
+ oS.src = sURL;
+ document.getElementsByTagName('head')[0].appendChild(oS);
+}
+
+function doAltShortcuts() {
+ var o = _id('shortcuts-list');
+ if (!o) {
+ return false;
+ }
+ var oParents = [];
+ var oLIs = o.getElementsByTagName('li');
+ var isIgnore = null;
+ var offset = 0;
+ for (var i=0; i<oLIs.length; i++) {
+ isIgnore = utils.hasClass(oLIs[i],'ignore');
+ if (isIgnore) {
+ offset = 0;
+ }
+ offset++;
+ if ((offset)%2 == 0 && !isIgnore) {
+ utils.addClass(oLIs[i],'alt');
+ }
+ }
+}
+
+function fixLinks() {
+ if (document.location.protocol.match(/http/i)) {
+ return false;
+ }
+ // presumably offline - add index.html to local links, so offline browsing is seamless
+ var l = document.getElementsByTagName('a');
+ var s = null;
+ var tmp = null;
+ for (var i=l.length; i--;) {
+ s = l[i].href.toString();
+ if (!s.match(/http/i) && !utils.hasClass(l[i],'norewrite') && (s.match(/doc/i) || s.match(/demo/i) || s.match(/../))) {
+ // yep, local.
+ tmp = Math.max(s.lastIndexOf('?'),-1);
+ tmp = Math.max(s.lastIndexOf('#'),tmp);
+ tmp = Math.max(s.lastIndexOf('/')+1,tmp);
+ // console.log(s+' '+s.lastIndexOf('?')+', '+s.lastIndexOf('#')+', '+s.lastIndexOf('/')+' = '+tmp);
+ if (tmp == -1) {
+ tmp = s.length;
+ }
+ if (!s.match(/\.html/i)) {
+ l[i].setAttribute('href',s.substr(0,tmp)+'index.html'+s.substr(tmp));
+ }
+ }
+ }
+}
+
+function doChristmasLights() {
+ if ((document.domain.match(/schillmania.com/i) && new Date().getMonth() == 11) || window.location.toString().match(/christmas/i)) {
+ loadScript('http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js',function(){
+ loadScript('demo/christmas-lights/christmaslights-home.js',function(){
+ if (typeof smashInit != 'undefined') {
+ setTimeout(smashInit,20);
+ }
+ });
+ });
+ }
+}
+
+function ie6Sucks() {
+ // no :hover, generally-broken layout etc.
+ if (!navigator.userAgent.match(/msie 6/i)) {
+ return false;
+ }
+ var o = _id('nav').getElementsByTagName('li')[1];
+ var oA = o.getElementsByTagName('a')[0];
+ var oUL = o.getElementsByTagName('ul')[0];
+ oA.onclick = function() {
+ oUL.style.display = 'block';
+ setTimeout(function(){
+ document.onclick = function() {
+ oUL.style.display = 'none';
+ document.onclick = null;
+ }
+ },20);
+ return false;
+ }
+}
+
+function doVersion() {
+ var o = _id('version');
+ if (!o) {
+ return false;
+ }
+ o.innerHTML = soundManager.versionNumber;
+}
+
+function startStuff() {
+ if (navigator.userAgent.match(/safari/i)) {
+ document.getElementsByTagName('html')[0].className = 'isSafari';
+ }
+ doVersion();
+ ie6Sucks();
+ fixLinks();
+ getLiveData();
+ doAltShortcuts();
+}
+
+if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", startStuff, false);
+} else {
+ window.onload = startStuff;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/going_outside.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/going_outside.mp3 Binary files differnew file mode 100755 index 0000000..7555831 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/going_outside.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/office_lobby.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/office_lobby.mp3 Binary files differnew file mode 100755 index 0000000..8432fa7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/office_lobby.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/rain.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/rain.mp3 Binary files differnew file mode 100755 index 0000000..86050cb --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/rain.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/walking.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/walking.mp3 Binary files differnew file mode 100755 index 0000000..45f660e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/audio/walking.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg1.jpg b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg1.jpg Binary files differnew file mode 100755 index 0000000..cb09da9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg1.jpg diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg2.jpg b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg2.jpg Binary files differnew file mode 100755 index 0000000..ef7392f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg2.jpg diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg3.jpg b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg3.jpg Binary files differnew file mode 100755 index 0000000..da1ec4b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/backgrounds/bg3.jpg diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player-light.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player-light.css new file mode 100755 index 0000000..099a6de --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player-light.css @@ -0,0 +1,543 @@ +body {
+ font:normal 75% verdana,tahoma,arial,"sans serif";
+ background:#000;
+ color:#fff;
+}
+
+/*
+
+ GENERAL RANT AWARENESS NOTICE
+ -----------------------------
+ You may see some complaining about Internet Explorer, PNG and opacity-related hacks.
+ Even the new (at time of writing, 12/2006) IE 7 has issues and other quirks. Too bad.
+
+*/
+
+.sm2player {
+ position:absolute;
+ left:1.75em;
+ top:5.5em;
+ z-index:3;
+ padding:1px;
+ height:20px;
+ font:normal x-small/19px arial,verdana,tahoma,"sans serif";
+ *line-height:19px;
+ color:#4f4f4f;
+ zoom:1;
+}
+
+.sm2player.altFont {
+ /* font tweaks for mac which has tighter spacing */
+ letter-spacing:0px;
+}
+
+.sm2player,
+.sm2player .sm2playlist-box {
+ /*width:284px;*/
+}
+
+/*.sm2player .ui,*/
+.sm2player .sm2playlist {
+ opacity:0.9;
+}
+
+.sm2player .ui {
+ _filter:none; /* IE <7 sucks */
+}
+
+.sm2player.noOpacity .ui {
+ /* Safari (1.3.2 at least?) has render bugs with UI display + animated PNG progress bar when applying opacity */
+ opacity:1;
+}
+
+.sm2player .ui:hover {
+ opacity:1;
+ filter:none;
+}
+
+.sm2player a:focus {
+ outline:none;
+}
+
+.sm2player .left,
+.sm2player .mid,
+.sm2player .right {
+ position:relative;
+ float:left;
+ display:inline;
+ height:20px;
+ color:#4f4f4f;
+}
+
+.sm2player .left {
+ width:15px;
+ background:transparent url(../image/skin-3-ui.png) 0px 0px no-repeat;
+ _background-image:url(../image/skin-3-ui.gif); /* IE <7 */
+}
+
+.sm2player .left .trigger,
+.sm2player .left .trigger span {
+ display:block;
+ width:15px;
+ height:20px;
+}
+
+.sm2player .left .trigger.pauseplay span {
+ background:transparent url(../image/sec-left-arr1.png) 5px 6px no-repeat;
+ _background-image:url(../.sm2player .left {
+ width:15px;
+ background:transparent url(../image/skin-0-ui.png) 0px 0px no-repeat;
+ _background-image:url(../image/skin-0-ui.gif); /* IE <7 */
+}
+image/sec-left-arr1.gif);
+}
+
+.sm2player .left .trigger.pauseplay span.playing {
+ /* class applied while playing */
+ background-image:url(../image/sec-left-pause-1.gif);
+ background-position:6px 7px;
+}
+
+.sm2player .left .trigger:hover {
+ background:transparent url(../image/ui-highlight-1.png) 2px 0px no-repeat;
+ _background-image:url(../image/ui-highlight-1.gif);
+ _background-position:2px 0px;
+}
+
+.sm2player .left .trigger.pauseplay:hover span {
+ background:transparent url(../image/sec-left-arr0.png) 5px 6px no-repeat;
+ _background-image:url(../image/sec-left-arr2.gif);
+}
+
+.sm2player .left .trigger.pauseplay:hover span.playing {
+ background-image:url(../image/sec-left-pause.gif);
+ background-position:6px 7px;
+}
+
+.sm2player .mid {
+ position:relative;
+ width:223px;
+ _width:224px;
+ background:transparent url(../image/skin-3-ui.png) -14px 0px no-repeat;
+ _background-image:url(../image/skin-3-ui.gif);
+}
+
+.sm2player .mid .info {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:20px;
+ overflow:hidden;
+ text-indent:2px;
+ z-index:2;
+ cursor:default;
+}
+
+.sm2player .mid .progress {
+ position:relative;
+ display:block;
+ width:1px;
+ height:12px;
+ margin:4px 0px 0px 0px;
+ background:transparent url(../image/sec-mid-loaded-light.png) 0px 0px repeat-x;
+ _background-image:url(../image/sec-mid-loaded-light.gif);
+ background-color:#eee;
+}
+
+.sm2player .mid .progress.loading {
+ position:relative;
+ display:block;
+ width:1px;
+ border-right:1px solid #eee;
+}
+
+.sm2player .mid .slider {
+ position:absolute;
+ display:block;
+ width:12px;
+ height:12px;
+ left:0px;
+ top:0px;
+ margin-top:4px;
+ background:transparent url(../image/slider-light.png) 0px 0px no-repeat;
+ _background-image:url(../image/slider-light.gif);
+ z-index:1; /* swap between 1 and 2 to position on top */
+ z-index:2;
+ opacity:0.95;
+ /* filter:alpha(opacity=95); IE7 still messes up alpha transparency with PNGs when applying filters. Boo urns. */
+}
+
+.sm2player .mid.hover .slider,
+.sm2player .mid:hover .slider {
+/*
+ z-index:2;
+ opacity:0.95;
+ filter:filter:alpha(opacity=95);
+*/
+}
+
+.sm2player .mid .slider.active {
+/*
+ -moz-opacity:0.85;
+ filter:alpha(opacity=85);
+*/
+}
+
+.sm2player .mid .text,
+.sm2player .mid .default,
+.sm2player .mid .seek,
+.sm2player .mid .divider {
+ display:none;
+}
+
+.sm2player .mid .caption {
+ *position:absolute; /* required for scroll positioning to work under IE */
+ display:inline;
+ white-space:nowrap;
+ visibility:hidden; /* hidden by default */
+}
+
+.sm2player .mid .seek {
+ position:absolute;
+ left:0px;
+ top:0px;
+ text-indent:2px;
+}
+
+.sm2player .right {
+/*
+ width:18px;
+ width:45px;
+*/
+ background:transparent url(../image/skin-3-ui.png) 100% 0px no-repeat;
+ _background-image:url(../image/skin-3-ui.gif);
+ margin-left:1px;
+ _margin-left:0px; /* IE <7 sucks. */
+}
+
+.sm2player .right .divider {
+ /* one-pixel visual divider between bar / cap (yep, this is a UI nit-pick.) */
+ float:left;
+ display:inline;
+ width:1px;
+ height:20px;
+ overflow:hidden;
+ background:transparent url(../image/skin-3-ui.png) -1006px 0px no-repeat;
+ _background-image:url(../image/skin-3-ui.gif);
+ margin-left:-1px;
+ _display:none; /* IE <7 sucks. */
+}
+
+.sm2player .right .time {
+ float:left;
+ display:inline;
+ width:3em;
+ text-align:center;
+ line-height:19px;
+ margin:0px 1px 0px 3px;
+}
+
+.sm2player .right .trigger {
+ float:left;
+ display:inline;
+ width:14px;
+ height:20px;
+}
+
+.sm2player .right .trigger span {
+ display:block;
+ height:20px;
+}
+
+.sm2player .right .trigger.prev {
+ margin-left:1px;
+}
+
+.sm2player .right .trigger.s0 {
+ width:16px;
+}
+
+.sm2player .right .trigger.s1 {
+ width:18px;
+}
+
+.sm2player .right .trigger.s2 {
+ width:20px;
+}
+
+.sm2player .right .trigger.s3 {
+ width:12px;
+}
+
+.sm2player .right .trigger.s4 {
+ width:13px;
+}
+
+.sm2player .right .trigger {
+ background:transparent;
+}
+
+.sm2player .right .trigger.prev {
+}
+
+.sm2player .right .trigger.dropdown {
+ width:14px;
+ margin-right:2px;
+}
+
+.sm2player .right .trigger span {
+ background:transparent url(../image/sec-right-arr1.png) 3px 7px no-repeat;
+ /*
+ _background-image:url(../image/sec-right-arr1.gif);
+ _background-position:0px 0px;
+ */
+}
+
+.sm2player .right .trigger.prev span {
+ background:transparent url(../image/btn-prev-1.png) 4px 6px no-repeat;
+ /* _background-image:url(../image/btn-prev-1.gif); */
+}
+
+.sm2player .right .trigger.next span {
+ background:transparent url(../image/btn-next-1.png) 3px 6px no-repeat;
+ /* _background-image:url(../image/btn-next-1.gif); */
+}
+
+.sm2player .right .trigger.loop span {
+ background:transparent url(../image/loop-light.png) 3px 5px no-repeat;
+ opacity:0.5;
+ filter:alpha(opacity=50);
+}
+
+.sm2player .right .trigger.loop.active span {
+ opacity:1;
+ filter:none;
+}
+
+.sm2player .right .trigger.shuffle span {
+ background:transparent url(../image/shuffle-1-light.png) 2px 5px no-repeat;
+ opacity:0.5;
+ filter:alpha(opacity=50);
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/shuffle-1-light.png');
+ _margin:5px 0px 0px 2px;
+}
+
+.sm2player .right .trigger.shuffle:hover span {
+ background-image:url(../image/shuffle.png);
+}
+
+.sm2player .right .trigger.shuffle.active span {
+ opacity:1;
+ filter:none;
+}
+
+.sm2player .right .trigger.mute span {
+ background:transparent url(../image/speaker-light.png) 3px 5px no-repeat;
+}
+
+.sm2player .right .trigger.mute:hover span {
+ background-image:url(../image/speaker.png);
+ opacity:0.75;
+}
+
+.sm2player .right .trigger.mute.active span {
+ opacity:0.5;
+}
+
+.sm2player .right .trigger.volume span {
+ background:transparent url(../image/volume-light.png) 0px 4px no-repeat;
+}
+
+.sm2player .right .trigger:hover {
+ background:transparent url(../image/ui-highlight-1.png) -2px 0px no-repeat;
+ _background-image:url(../image/ui-highlight-1.gif);
+ /*_background-position:2px 2px;*/
+}
+
+.sm2player .right .trigger.dropdown:hover>span {
+ background-image:url(../image/sec-right-arr0.png);
+}
+
+.sm2player .right .trigger.prev:hover>span {
+ background-image:url(../image/btn-prev.png);
+}
+
+.sm2player .right .trigger.next:hover>span {
+ background-image:url(../image/btn-next.png);
+}
+
+.sm2player .right .trigger.loop:hover>span {
+ background-image:url(../image/loop.png);
+}
+
+.sm2player .right .trigger.shuffle:hover>span {
+ background-image:url(../image/shuffle-1.png);
+}
+
+.sm2player .right .trigger.mute:hover>span {
+ background-image:url(../image/speaker.png);
+}
+
+.sm2player .right .trigger.volume:hover>span {
+ background-image:url(../image/volume.png);
+}
+
+.sm2player .right .dropdown:hover {
+ background-position:right 0px;
+}
+
+.sm2playlist-box {
+ position:absolute;
+ /*width:256px;*/
+ /*overflow:hidden;*/
+ /*max-height:33.1em;*/
+ left:1px;
+ top:26px;
+ overflow:auto;
+ margin-top:-4px;
+}
+
+.sm2playlist {
+ position:relative;
+ /* zoom:1; stupid IE. */
+ margin-top:-999em; /* hidden by default */
+}
+
+.sm2playlist .hd,
+.sm2playlist .c {
+ position:relative;
+ height:3px;
+}
+
+.sm2playlist .hd {
+ background:transparent url(../image/skin-3-ui.png) no-repeat 0px 0px;
+ _background-image:url(../image/skin-3.ui.gif);
+ margin-right:3px;
+}
+
+.sm2playlist .hd .c {
+ position:absolute;
+ right:0px;
+ top:0px;
+ background:transparent url(../image/skin-3-ui.png) no-repeat 100% 0px;
+ _background-image:url(../image/skin-3-ui.gif);
+ margin-right:-3px;
+ width:3px;
+}
+
+.sm2playlist .bd {
+ background:transparent url(../image/shade-left.png) repeat-y 0px 0px;
+ _background-image:none;
+ margin-right:2px;
+}
+
+.sm2playlist ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+ padding-right:4px; /* space for background */
+ margin-right:-2px;
+ background:transparent url(../image/shade-right.png) repeat-y 100% 0px;
+ _background-image:none;
+ zoom:1; /* Even IE 7 needs this (!?) */
+}
+
+.sm2playlist ul li {
+ line-height:1.5em;
+}
+
+.sm2playlist ul li a {
+ display:block;
+ background:transparent;
+ margin-left:2px;
+ margin-right:-2px;
+ color:#666;
+ text-indent:0.25em;
+ text-decoration:none;
+ width:100%; /* stupid IE 7. */
+}
+
+.sm2playlist ul li a span {
+ display:block;
+ background:#eee;
+ padding:0.1em 0.5em;
+ border-top:1px solid #fff;
+ border-bottom:1px solid #ccc;
+}
+
+.sm2playlist ul li.alt a span {
+ background:#e0e0e0;
+}
+
+.sm2playlist ul li:first-child a span {
+ border-top:none;
+}
+
+.sm2playlist ul li:last-child a span {
+ border-bottom:none;
+}
+
+.sm2playlist ul li a:hover span {
+ background-color:#999;
+ color:#fff;
+}
+
+.sm2playlist ul li a:hover span {
+ border-color:transparent;
+ _border-color:#ccc;
+}
+
+.sm2playlist ul li.highlight a {
+ color:#fff;
+}
+
+.sm2playlist ul li.highlight a span {
+ background:#fff url(../image/notreallyajaxandyouknowit-light.gif) no-repeat right 50%;
+ color:#333;
+ border-color:#fff;
+}
+
+.sm2playlist ul li.highlight a:hover {
+ background-color:#999;
+ color:#9999ff;
+}
+
+.sm2playlist ul li a:focus {
+ outline:none;
+}
+
+.sm2playlist .ft {
+ background:transparent url(../image/skin-3-ui.png) no-repeat 0px 100%;
+ _background-image:url(../image/skin-3-ui.gif);
+ margin-right:3px;
+ height:2px;
+}
+
+.sm2playlist .ft .c {
+ position:absolute;
+ right:0px;
+ bottom:0px;
+ background:transparent url(../image/skin-3-ui.png) no-repeat 100% 100%;
+ _background-image:url(../image/skin-3-ui.gif);
+ width:3px;
+ height:2px;
+}
+
+#soundmanager-debug {
+ position:absolute;
+ position:fixed;
+ right:20px;
+ bottom:20px;
+ display:none;
+ font-size:xx-small;
+ height:20em;
+ overflow:auto;
+ /* background:transparent url(../image/whiteout.png); */
+ padding:1em;
+ background:#000;
+ color:#fff;
+ filter:alpha(opacity=90);
+ opacity:0.9;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player.css new file mode 100755 index 0000000..5c5907e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/css/player.css @@ -0,0 +1,525 @@ +body {
+ font:normal 75% verdana,tahoma,arial,"sans serif";
+ background:#000;
+ color:#ccc;
+}
+
+/*
+
+ GENERAL RANT AWARENESS NOTICE
+ -----------------------------
+ You may see some complaining about Internet Explorer, PNG and opacity-related hacks.
+ Even the new (at time of writing, 12/2006) IE 7 has issues and other quirks. Too bad.
+
+*/
+
+.sm2player {
+ position:absolute;
+ left:1.75em;
+ top:5.5em;
+ z-index:3;
+ padding:1px;
+ height:20px;
+ font:normal x-small/19px arial,verdana,tahoma,"sans serif";
+ *line-height:18px;
+ color:#000;
+ zoom:1;
+}
+
+.sm2player.altFont {
+ /* font tweaks for mac which has tighter spacing */
+ letter-spacing:0px;
+}
+
+.sm2player,
+.sm2player .sm2playlist-box {
+/*
+ width:302px;
+ width:360px;
+*/
+}
+
+.sm2player .ui,
+.sm2player .sm2playlist {
+xfilter:alpha(opacity=90); /* Even IE 7 (still) sucks! */
+ opacity:0.9;
+}
+
+.sm2player .ui {
+ _filter:none; /* IE <7 sucks */
+}
+
+.sm2player.noOpacity .ui {
+ /* Safari (1.3.2 at least?) has render bugs with UI display + animated PNG progress bar when applying opacity */
+ opacity:1;
+}
+
+.sm2player .ui:hover {
+ opacity:1;
+ filter:alpha(opacity=100);
+}
+
+.sm2player a:focus {
+ outline:none;
+}
+
+.sm2player .left,
+.sm2player .mid,
+.sm2player .right {
+ position:relative;
+ float:left;
+ display:inline;
+ height:20px;
+ color:#fff;
+}
+
+.sm2player .left {
+ width:15px;
+ background:transparent url(../image/skin-0-ui.png) 0px 0px no-repeat;
+ _background-image:url(../image/skin-0-ui.gif); /* IE <7 */
+}
+
+.sm2player .left .trigger,
+.sm2player .left .trigger span {
+ display:block;
+ width:15px;
+ height:20px;
+}
+
+.sm2player .left .trigger.pauseplay span {
+ background:transparent url(../image/sec-left-arr0.png) 5px 6px no-repeat;
+ _background-image:url(../image/sec-left-arr0.gif);
+ _background-position:0px 0px;
+}
+
+.sm2player .left .trigger.pauseplay span.playing {
+ /* class applied while playing */
+ background-image:url(../image/sec-left-pause.gif);
+ background-position:6px 7px;
+}
+
+.sm2player .left .trigger:hover {
+ background:transparent url(../image/ui-highlight-2.png) 2px 0px no-repeat;
+ _background-image:url(../image/ui-highlight-2.gif);
+ /*_background-position:2px 2px;*/
+}
+
+.sm2player .mid {
+ position:relative;
+ width:223px;
+ _width:224px;
+ background:transparent url(../image/skin-0-ui.png) -14px 0px no-repeat;
+ _background-image:url(../image/skin-0-ui.gif);
+}
+
+.sm2player .mid .info {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:20px;
+ overflow:hidden;
+ text-indent:2px;
+ z-index:2;
+ cursor:default;
+}
+
+.sm2player .mid .progress {
+ position:relative;
+ display:block;
+ width:1px;
+ height:12px;
+ margin:4px 0px 0px 0px;
+ background:transparent url(../image/sec-mid-loaded.png) 0px 0px repeat-x;
+ _background-image:url(../image/sec-mid-loaded.gif);
+ background-color:#333;
+}
+
+.sm2player .mid .progress.loading {
+ position:relative;
+ display:block;
+ width:1px;
+ border-right:1px solid #333;
+}
+
+.sm2player .mid .slider {
+ position:absolute;
+ display:block;
+ width:12px;
+ height:12px;
+ left:0px;
+ top:0px;
+ margin-top:4px;
+ background:transparent url(../image/slider-1.png) 0px 0px no-repeat;
+ _background-image:url(../image/slider.gif);
+ z-index:1; /* swap between 1 and 2 to position on top */
+ z-index:2;
+ opacity:0.90;
+ /* filter:alpha(opacity=90); IE7 can't apply opacity to PNGs without messing up alpha transparency. Boo urns. */
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/slider-1.png');
+}
+
+.sm2player .mid:hover .slider {
+ opacity:0.95;
+ filter:alpha(opacity=95);
+}
+
+.sm2player .mid>.slider.active {
+ -moz-opacity:0.85;
+ filter:alpha(opacity=85);
+}
+
+.sm2player .mid .text,
+.sm2player .mid .default,
+.sm2player .mid .seek,
+.sm2player .mid .divider {
+ display:none;
+}
+
+.sm2player .mid .caption {
+ *position:absolute; /* required for scroll positioning to work under IE */
+ display:inline;
+ white-space:nowrap;
+ visibility:hidden; /* hidden by default */
+}
+
+.sm2player .mid .seek {
+ position:absolute;
+ left:0px;
+ top:0px;
+ text-indent:2px;
+}
+
+.sm2player .right {
+ background:transparent url(../image/skin-0-ui.png) 100% 0px no-repeat;
+ _background-image:url(../image/skin-0-ui.gif);
+ margin-left:1px;
+ _margin-left:0px; /* IE <7 sucks. */
+}
+
+.sm2player .right .divider {
+ /* one-pixel visual divider between bar / cap (yep, this is a UI nit-pick.) */
+ float:left;
+ display:inline;
+ width:1px;
+ height:20px;
+ overflow:hidden;
+ background:transparent url(../image/skin-0-ui.png) -1006px 0px no-repeat;
+ _background-image:url(../image/skin-0-ui.gif);
+ margin-left:-1px;
+ _display:none; /* IE <7 sucks. */
+}
+
+.sm2player .right .time {
+ float:left;
+ display:inline;
+ width:3em;
+ text-align:center;
+ margin:0px 1px 0px 3px;
+}
+
+.sm2player .right .trigger {
+ float:left;
+ display:inline;
+ width:14px;
+ height:20px;
+}
+
+.sm2player .right .trigger span {
+ display:block;
+ height:20px;
+}
+
+.sm2player .right .trigger.prev {
+ margin-left:1px;
+}
+
+.sm2player .right .trigger.s0 {
+ width:16px;
+}
+
+.sm2player .right .trigger.s1 {
+ width:18px;
+}
+
+.sm2player .right .trigger.s2 {
+ width:20px;
+}
+
+.sm2player .right .trigger.s3 {
+ width:12px;
+}
+
+.sm2player .right .trigger.s4 {
+ width:13px;
+}
+
+.sm2player .right .trigger {
+ background:transparent;
+}
+
+.sm2player .right .trigger.prev {
+}
+
+.sm2player .right .trigger.dropdown {
+ width:14px;
+ margin-right:2px;
+}
+
+.sm2player .right .trigger.dropdown span {
+ xwidth:14px;
+}
+
+.sm2player .right .trigger span {
+ background:transparent url(../image/sec-right-arr0.png) 3px 7px no-repeat;
+ _background-image:url(../image/sec-right-arr0.gif);
+ _background-position:0px 0px;
+ _background-image:none;
+}
+
+.sm2player .right .trigger.dropdown span {
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/sec-right-arr0.png');
+ _margin:7px 0px 0px 3px;
+ _height:13px;
+}
+
+.sm2player .right .trigger.prev span {
+ background:transparent url(../image/btn-prev.png) 4px 6px no-repeat;
+ _background-image:url(../image/btn-prev.gif);
+}
+
+.sm2player .right .trigger.next span {
+ background:transparent url(../image/btn-next.png) 3px 6px no-repeat;
+ _background-image:url(../image/btn-next.gif);
+}
+
+.sm2player .right .trigger.loop span {
+ background:transparent url(../image/loop.png) 3px 5px no-repeat;
+ opacity:0.5;
+ filter:alpha(opacity=50);
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/loop.png');
+ _margin:5px 0px 0px 3px;
+ _height:15px;
+}
+
+.sm2player .right .trigger.loop:hover>span {
+ opacity:0.75;
+ filter:alpha(opacity=75);
+}
+
+.sm2player .right .trigger.loop.active>span {
+ /*background-image:url(../image/loop-light.png);*/
+ opacity:1;
+ filter:none;
+}
+
+.sm2player .right .trigger.shuffle span {
+ background:transparent url(../image/shuffle-1.png) 2px 5px no-repeat;
+ opacity:0.5;
+ filter:alpha(opacity=50);
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/shuffle-1.png');
+ _margin:5px 0px 0px 2px;
+ _height:15px;
+}
+
+.sm2player .right .trigger.shuffle:hover>span {
+ opacity:0.75;
+ filter:alpha(opacity=75);
+}
+
+.sm2player .right .trigger.shuffle.active>span {
+ opacity:1;
+ filter:none;
+}
+
+.sm2player .right .trigger.mute span {
+ background:transparent url(../image/speaker.png) 3px 5px no-repeat;
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/speaker.png');
+ _margin:5px 0px 0px 3px;
+ _height:15px;
+}
+
+.sm2player .right .trigger.mute:hover>span {
+ opacity:0.75;
+ filter:alpha(opacity=75);
+}
+
+.sm2player .right .trigger.mute.active>span {
+ opacity:0.5;
+ filter:alpha(opacity=50);
+}
+
+.sm2player .right .trigger.volume span {
+ background:transparent url(../image/volume.png) 0px 4px no-repeat;
+ _background-image:none;
+ _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop src='image/volume.png');
+ _margin:4px 0px 0px 0px;
+ _height:16px;
+}
+
+.sm2player .right .trigger:hover {
+ background:transparent url(../image/ui-highlight-2.png) -2px 0px no-repeat;
+ _background-image:url(../image/ui-highlight-2.gif);
+ /*_background-position:2px 2px;*/
+}
+
+.sm2playlist-box {
+ position:absolute;
+ /*width:256px;*/
+ /*overflow:hidden;*/
+ /*max-height:33.1em;*/
+ left:1px;
+ top:22px;
+ overflow:auto;
+ margin-top:-4px;
+}
+
+.sm2playlist {
+ position:relative;
+ /* zoom:1; stupid IE. */
+ margin-top:-999em; /* hidden by default */
+}
+
+.sm2playlist .hd,
+.sm2playlist .c {
+ position:relative;
+ height:3px;
+}
+
+.sm2playlist .hd {
+ background:transparent url(../image/skin-0-ui.png) no-repeat 0px 0px;
+ _background-image:url(../image/skin-0.ui.gif);
+ margin-right:2px;
+}
+
+.sm2playlist .hd .c {
+ /* not used? */
+}
+
+.sm2playlist .bd {
+ background:transparent url(../image/shade-left.png) repeat-y 0px 0px;
+ _background-image:none;
+ margin-right:2px;
+}
+
+.sm2playlist ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+ padding-right:4px; /* space for background */
+ margin-right:-2px;
+ background:transparent url(../image/shade-right.png) repeat-y 100% 0px;
+ _background-image:none;
+ zoom:1; /* Even IE 7 needs this (!?) */
+}
+
+.sm2playlist ul li {
+ line-height:1.5em;
+}
+
+.sm2playlist ul li a {
+ display:block;
+ background:transparent;
+ margin-left:2px;
+ margin-right:-2px;
+ color:#999;
+ text-indent:0.25em;
+ text-decoration:none;
+ width:100%; /* stupid IE 7. */
+}
+
+.sm2playlist ul li a span {
+ display:block;
+ background:#222;
+ padding:0.1em 0.5em;
+ border-top:1px solid #333;
+ border-bottom:1px solid #000;
+ /* genie animation test */
+/*
+ white-space:nowrap;
+ overflow:hidden;
+*/
+}
+
+.sm2playlist ul li.alt a span {
+ background:#303030;
+ color:#c3c3c3;
+}
+
+.sm2playlist ul li:first-child a span {
+ border-top:none;
+}
+
+.sm2playlist ul li:last-child a span {
+ /*border-bottom:none;*/
+}
+
+.sm2playlist ul li a:hover span {
+ background-color:#444;
+ color:#fff;
+}
+
+.sm2playlist ul li a:hover span {
+ border-color:transparent;
+ _border-color:#333;
+}
+
+.sm2playlist ul li.highlight a {
+ background-color:#660000;
+}
+
+.sm2playlist ul li.highlight a span {
+ background:#161616 url(../image/notreallyajaxandyouknowit-dark.gif) no-repeat right 50%;
+ border-color:#000;
+ color:#ff9999;
+}
+
+.sm2playlist ul li.highlight a:hover {
+ background-color:#880000;
+ color:#fff;
+}
+
+.sm2playlist ul li a:focus {
+ outline:none;
+}
+
+.sm2playlist .ft {
+ background:transparent url(../image/skin-0-ui.png) no-repeat 0px 100%;
+ _background-image:url(../image/skin-0-ui.gif);
+ margin-right:2px;
+ height:2px;
+}
+
+.sm2playlist .ft .c {
+ position:absolute;
+ right:0px;
+ bottom:0px;
+ background:transparent url(../image/skin-0-ui.png) no-repeat 100% 100%;
+ _background-image:url(../image/skin-0-ui.gif);
+ margin-left:3px; /* leave room for left cap */
+ margin-right:-1px;
+ /* not needed */
+ display:none;
+
+}
+
+#soundmanager-debug {
+ position:absolute;
+ position:fixed;
+ right:20px;
+ bottom:20px;
+ display:none;
+ font-size:xx-small;
+ height:20em;
+ overflow:auto;
+ /* background:transparent url(../image/whiteout.png); */
+ background:#000;
+ padding:1em;
+ color:#fff;
+ filter:alpha(opacity=90);
+ opacity:0.9;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.gif Binary files differnew file mode 100755 index 0000000..e43cafe --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.png Binary files differnew file mode 100755 index 0000000..9db8019 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.gif Binary files differnew file mode 100755 index 0000000..98ff850 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.png Binary files differnew file mode 100755 index 0000000..e253f28 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-next.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.gif Binary files differnew file mode 100755 index 0000000..9cff3d0 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.png Binary files differnew file mode 100755 index 0000000..842c917 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.gif Binary files differnew file mode 100755 index 0000000..d2c1257 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.png Binary files differnew file mode 100755 index 0000000..252f854 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/btn-prev.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop-light.png Binary files differnew file mode 100755 index 0000000..70d41b7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop.png Binary files differnew file mode 100755 index 0000000..82d61be --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/loop.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-dark.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-dark.gif Binary files differnew file mode 100755 index 0000000..42fd2b7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-dark.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-light.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-light.gif Binary files differnew file mode 100755 index 0000000..9cf0467 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/notreallyajaxandyouknowit-light.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.gif Binary files differnew file mode 100755 index 0000000..7de9b71 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.png Binary files differnew file mode 100755 index 0000000..9057d52 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr0.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.gif Binary files differnew file mode 100755 index 0000000..d4e3026 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.png Binary files differnew file mode 100755 index 0000000..fc2f6e1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr2.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr2.gif Binary files differnew file mode 100755 index 0000000..50c496c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-arr2.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause-1.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause-1.gif Binary files differnew file mode 100755 index 0000000..df8f5d3 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause-1.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause.gif Binary files differnew file mode 100755 index 0000000..41c517f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-left-pause.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-dark.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-dark.png Binary files differnew file mode 100755 index 0000000..dac90dc --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-dark.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.gif Binary files differnew file mode 100755 index 0000000..cf0c9c0 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.png Binary files differnew file mode 100755 index 0000000..f9c3d57 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.gif Binary files differnew file mode 100755 index 0000000..e630272 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.png Binary files differnew file mode 100755 index 0000000..cc0d8ca --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-mid-loaded.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.gif Binary files differnew file mode 100755 index 0000000..5d7f471 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.png Binary files differnew file mode 100755 index 0000000..d3a6eb8 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr0.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr1.png Binary files differnew file mode 100755 index 0000000..d53d90c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/sec-right-arr1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-left.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-left.png Binary files differnew file mode 100755 index 0000000..28cdb31 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-left.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-right.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-right.png Binary files differnew file mode 100755 index 0000000..a11c057 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shade-right.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0-light.png Binary files differnew file mode 100755 index 0000000..770d471 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0.png Binary files differnew file mode 100755 index 0000000..13b3e56 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-0.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1-light.png Binary files differnew file mode 100755 index 0000000..0fc7174 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1.png Binary files differnew file mode 100755 index 0000000..bca4642 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/shuffle-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.gif Binary files differnew file mode 100755 index 0000000..e209f57 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.png Binary files differnew file mode 100755 index 0000000..6bd2821 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui__.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui__.gif Binary files differnew file mode 100755 index 0000000..dc742e0 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-0-ui__.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-1-ui.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-1-ui.png Binary files differnew file mode 100755 index 0000000..22d3830 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-1-ui.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-2-ui.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-2-ui.png Binary files differnew file mode 100755 index 0000000..d1eee4e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-2-ui.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.gif Binary files differnew file mode 100755 index 0000000..c715a9c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.png Binary files differnew file mode 100755 index 0000000..161e19d --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-3-ui.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-4-ui.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-4-ui.png Binary files differnew file mode 100755 index 0000000..087b43e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/skin-4-ui.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-1.png Binary files differnew file mode 100755 index 0000000..be28d4a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.gif Binary files differnew file mode 100755 index 0000000..63a20ac --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.png Binary files differnew file mode 100755 index 0000000..4984ea2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.gif Binary files differnew file mode 100755 index 0000000..2c86492 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.png Binary files differnew file mode 100755 index 0000000..dc4b1a4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/slider.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker-light.png Binary files differnew file mode 100755 index 0000000..de681e4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker.png Binary files differnew file mode 100755 index 0000000..c61a5bd --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/speaker.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.gif Binary files differnew file mode 100755 index 0000000..2709854 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.png Binary files differnew file mode 100755 index 0000000..a211562 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-0.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.gif Binary files differnew file mode 100755 index 0000000..d6828cf --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.png Binary files differnew file mode 100755 index 0000000..fc007f9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-1.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.gif Binary files differnew file mode 100755 index 0000000..6f91eb9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.png Binary files differnew file mode 100755 index 0000000..68fc7ff --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/ui-highlight-2.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume-light.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume-light.png Binary files differnew file mode 100755 index 0000000..426e3d5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume-light.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume.png Binary files differnew file mode 100755 index 0000000..27967eb --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/volume.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/whiteout.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/whiteout.png Binary files differnew file mode 100755 index 0000000..679f8e8 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/image/whiteout.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/index.html new file mode 100755 index 0000000..b1ccdc4 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/index.html @@ -0,0 +1,241 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>jsAMP MP3 Player v0.99a.20071010 - Technology Preview Demo</title> +<meta name="robots" content="noindex" />
+<meta name="author" content="Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="keywords" content="javascript sound library api" />
+<meta name="description" content="Demo page for soundmanager mp3 player" />
+<link rel="stylesheet" type="text/css" href="css/player.css" title="dark" media="screen" />
+<link rel="alternate stylesheet" type="text/css" href="css/player-light.css" title="light" media="screen" />
+<style type="text/css">
+
+#demo-info {
+ position:relative;
+ padding:1em;
+ background:#000;
+ opacity:0.75;
+ filter:alpha(opacity=75);
+ color:#fff;
+ max-width:51em;
+}
+
+#demo-info h1 {
+ margin:0px 0px 2em 0px;
+ font-size:1.5em;
+ color:#99ccff;
+}
+
+#demo-info p {
+ line-height:1.5em;
+}
+
+#demo-info a {
+ color:#99ccff;
+}
+
+#demo-info a:hover {
+ color:#fff;
+}
+
+#close {
+ position:absolute;
+ right:0px;
+ top:0px;
+ display:block;
+ width:1em;
+ line-height:1em;
+ padding:0.1em;
+ margin:0.5em;
+ height:1em;
+ text-decoration:none;
+ color:#fff;
+ border:1px solid #666;
+ text-align:center;
+ overflow:hidden;
+}
+
+#close:hover {
+ background:#333;
+}
+
+#demo-info.closed * {
+ display:none;
+}
+
+#demo-info.closed .minimal {
+ display:block;
+ margin:0px;
+ padding:0px;
+}
+
+#demo-info.closed .minimal * {
+ display:inline;
+}
+
+</style>
+<script type="text/javascript">
+function setActiveStyleSheet(title) {
+ var i, a, main;
+ for (i=0; (a = document.getElementsByTagName("link")[i]); i++) {
+ if (a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
+ a.disabled = true;
+ if(a.getAttribute("title") == title) a.disabled = false;
+ }
+ }
+}
+</script>
+<script type="text/javascript" src="../../script/soundmanager2-nodebug-jsmin.js"></script>
+<script type="text/javascript" src="script/jsamp-preview.js"></script>
+
+</head>
+
+<body>
+
+<div>
+
+ <!-- skin / control stuff -->
+ <div id="demo-info">
+
+ <h1>jsAMP: Example SoundManager 2 Application</h1>
+<pre style="font-size:1.25em">
+ ---------------------------------------------------------
+
+ * GENERAL DISCLAIMER: jsAMP is UNSUPPORTED DEMO CODE. *
+
+ jsAMP is provided "as-is" and as an example application
+ using the API functionality provided by SoundManager 2.
+ (It's also a dev. sanity QA check / API test suite.)
+
+ I don't recommend throwing it on your band/label's site
+ expecting it to "just work" - you have been warned. ;)
+
+ You are welcome to use this in your own projects, but
+ be aware jsAMP may be buggy, use at your own risk etc.
+
+ If you are looking for a JS/DHTML/Flash MP3 player,
+ check the related projects section of the SM2 project
+ page for other resources.
+
+ ---------------------------------------------------------
+</pre>
+ <p>jsAMP is a JavaScript MP3 player which uses the <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 project home">SoundManager 2 API</a> to provide JS-driven audio. It's an example of the kind of stuff you could build using SoundManager. All player logic is handled via Javascript, but SoundManager 2 (JS + Flash) provide the actual sound layer. It's also convenient in that no Flash knowledge is needed, it's all handled by SM2.</p>
+ <p>jsAMP picks up all <a> elements linking to MP3 files in the page, and creates a playlist (view source for details.) It gets ID3 information when loading local/same-domain files or as permissions allow, as well.</p>
+ <p>To see the playlist, click the "down arrow" <img src="image/sec-right-arr0.png" alt="Playlist toggle" title="Playlist toggle" /> at right on the UI.</p>
+ <p>Click and drag the title bar to move the player around. When a track is loaded, click to seek or drag and drop the slider to a given position. (Safari seems to have a few minor UI issues in this version, FYI.) IE 6 also receives a somewhat-degraded, GIF-based experience.</p>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2 Project Home</a></p>
+
+ <p class="minimal">Skin: <a href="#" onclick="setActiveStyleSheet('light');return false">light</a> | <a href="#" onclick="setActiveStyleSheet('dark');return false">dark</a> || <a href="#" onclick="bg.getRandom();return false">this background sucks</a></p>
+
+ <a id="close" href="#" title="close" onclick="document.getElementById('demo-info').className='closed';return false">-</a>
+
+ </div>
+
+
+ <div id="player-template" class="sm2player">
+
+ <!-- player UI (bar) -->
+
+ <div class="ui">
+
+ <div class="left">
+ <a href="#" title="Pause/Play" onclick="soundPlayer.togglePause();return false" class="trigger pauseplay"><span></span></a>
+ </div>
+
+ <div class="mid">
+
+ <div class="progress"></div>
+ <div class="info"><span class="caption text">%{artist} - %{title} [%{album}], (%{year}) (%{time})</span></div>
+ <div class="default">jsAMP Technology Preview v0.99a.20071010 (Seriously alpha - use at own risk! :))</div>
+ <div class="seek">Seek to %{time1} of %{time2} (%{percent}%)</div>
+ <div class="divider"> --- </div>
+ <a href="#" title="" class="slider"></a>
+ </div>
+
+ <div class="right">
+ <div class="divider"></div>
+ <div class="time" title="Time">0:00</div>
+ <a href="#" title="Previous" class="trigger prev" onclick="soundPlayer.oPlaylist.playPreviousItem();return false"><span></span></a>
+ <a href="#" title="Next" class="trigger next" onclick="soundPlayer.oPlaylist.playNextItem();return false"><span></span></a>
+ <a href="#" title="Shuffle" class="trigger s1 shuffle" onclick="soundPlayer.toggleShuffle();return false"><span></span></a>
+ <a href="#" title="Repeat" class="trigger s2 loop" onclick="soundPlayer.toggleRepeat();return false"><span></span></a>
+ <a href="#" title="Mute" class="trigger s3 mute" onclick="soundPlayer.toggleMute();return false"><span></span></a>
+ <a href="#" title="Volume" onmousedown="soundPlayer.volumeDown(event);return false" onclick="return false" class="trigger s4 volume"><span></span></a>
+ <a href="#" title="Playlist" class="trigger dropdown" onclick="soundPlayer.togglePlaylist();return false"><span></span></a>
+ </div>
+
+ </div>
+
+ <div class="sm2playlist-box">
+
+ <!-- playlist / controls -->
+ <div id="playlist-template" class="sm2playlist">
+
+ <div class="hd"><div class="c"></div></div>
+ <div class="bd">
+ <ul>
+ <!-- playlist items created, inserted here
+ <li><a href="/path/to/some.mp3"><span>Artist - Song Name, etc.</span></a></li>
+ -->
+ </ul>
+ </div>
+ <div class="ft"><div class="c"></div></div>
+ </div>
+
+ <!-- close container -->
+ </div>
+
+ </div>
+
+ <div style="position:absolute;left:0px;top:-9999px;width:30em">
+
+ <p>This is a normal list of HTML links to MP3 files, which jsAMP picks up and turns into a playlist.</p>
+
+ <ul>
+
+ <li><a href="audio/going_outside.mp3">Going Outside</a></li>
+ <li><a href="audio/office_lobby.mp3">Office Lobby Entrance</a></li>
+ <li><a href="../_mp3/mak.mp3">Angry cow sound?</a></li>
+ <li><a href="audio/walking.mp3">Walking</a></li>
+
+ <!-- files from the web (note that ID3 information will *not* load from remote domains without permission, Flash restriction) -->
+
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Rain 3.mp3">Rain 3</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Frogs @ Yahoo!.mp3">Frogs @ Yahoo!</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Walking past sprinklers, mailbox.mp3">Walking past sprinklers, mailbox</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Cup of Coffee.mp3">Cup of Coffee</a></li>
+ <li><a href="http://www.freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl (featureblend.com)</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></li>
+ <li><a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></li>
+
+ </ul>
+
+ </div>
+
+</div>
+
+<script type="text/javascript">
+var bg = {
+ images: ['bg1','bg2','bg3'],
+ i: 0,
+ getRandom: function(n) {
+ this.i = (typeof n != 'undefined'?n:(++this.i>=this.images.length?0:this.i));
+ document.body.style.background = "#000 url(backgrounds/"+this.images[this.i]+".jpg) no-repeat 0px 0px";
+ }
+}
+
+bg.getRandom(parseInt(Math.random()*bg.images.length));
+</script>
+
+<script type="text/javascript">
+if (window.location.toString().match(/flash9/)) soundManager.flashVersion = 9;
+soundManager.url = '../../swf/';
+</script>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/php notes.txt b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/php notes.txt new file mode 100755 index 0000000..25f8e88 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/php notes.txt @@ -0,0 +1,25 @@ +<?php
+
+// print out MP3s in a given directory
+// format:
+// <li><a href="/my/music/20060411 - Code 3825.mp3">Code 3825</a></li>
+
+function listMP3s($path) {
+ $dir = $_SERVER['DOCUMENT_ROOT'].$path;
+ $dirlength = strlen($dir);
+ $dh = opendir($dir);
+ while (false !== ($filename = readdir($dh))) {
+ // print "filename: $filename<br />";
+ if (stristr($filename,'.mp3')) $files[] = $path."/".basename($filename);
+ if ($filename != "." && $filename != ".." && is_dir($dir."/".$filename)) listMP3s($path."/".$filename); // recurse through subdirectories
+ // print ("is dir: ".(($filename != "." && $filename != ".." && is_dir($dir."/".$filename))?"Yes":"No")."<br />");
+ }
+ rsort($files);
+ for ($i=0; $i<sizeof($files); $i++) {
+ print " <li><a href=\"".dirname($files[$i])."/".rawurlencode(basename($files[$i]))."\">".basename($files[$i])."</a></li>\n";
+ }
+}
+
+listMP3s('/my/music');
+
+?>
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/script/jsamp-preview.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/script/jsamp-preview.js new file mode 100755 index 0000000..8b1b872 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/jsAMP-preview/script/jsamp-preview.js @@ -0,0 +1,1605 @@ +/*
+
+ jsAMP - V0.9a.20080331 - "Technology Preview" - DEMO ONLY
+ ---------------------------------------------------------
+ An MP3 player implementation using the SoundManager 2 API
+
+ (And a sanity QA / test suite for the core API calls. :D)
+ http://www.schillmania.com/projects/soundmanager2/
+
+ ---------------------------------------------------------
+
+ * GENERAL DISCLAIMER: jsAMP is UNSUPPORTED DEMO CODE. *
+
+ jsAMP is provided "as-is" and as an example application
+ using the API functionality provided by SoundManager 2.
+ (It's also a dev. sanity QA check / API test suite.)
+
+ I don't recommend throwing it on your band/label's site
+ expecting it to "just work" - you have been warned. ;)
+
+ You are welcome to use this in your own projects, but
+ be aware jsAMP may be buggy, use at your own risk etc.
+
+ If you are looking for a JS/DHTML/Flash MP3 player,
+ check the related projects section of the SM2 project
+ page for other resources.
+
+ ---------------------------------------------------------
+
+*/
+
+function SMUtils() {
+ var self = this;
+ this.isSafari = navigator.userAgent.match(/safari/);
+ this.isMac = navigator.platform.match(/mac/);
+ this.isIE = (navigator.appVersion.match(/MSIE/) && !navigator.userAgent.match(/Opera/));
+ this.isNewIE = (this.isIE && !this.isMac && (!navigator.userAgent.match(/MSIE (5|6)/)));
+ this.isOldIE = (this.isIE && !this.isNewIE);
+
+ this.$ = function(sID) {
+ return document.getElementById(sID);
+ }
+
+ this.isChildOf = function(oChild,oParent) {
+ while (oChild.parentNode && oChild != oParent) {
+ oChild = oChild.parentNode;
+ }
+ return (oChild == oParent);
+ }
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.classContains = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?o.className.indexOf(cStr)+1:false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o) return false; // safety net
+ if (self.classContains(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o) return false; // safety net
+ if (!self.classContains(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getElementsByClassName = function(className,tagNames,oParent) {
+ var doc = (oParent||document);
+ var matches = [];
+ var i,j;
+ var nodes = [];
+ if (typeof(tagNames)!='undefined' && typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ if (!nodes || !nodes[tagNames[i]]) {
+ nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
+ }
+ }
+ } else if (tagNames) {
+ nodes = doc.getElementsByTagName(tagNames);
+ } else {
+ nodes = doc.all||doc.getElementsByTagName('*');
+ }
+ if (typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ for (j=nodes[tagNames[i]].length; j--;) {
+ if (self.classContains(nodes[tagNames[i]][j],className)) {
+ matches[matches.length] = nodes[tagNames[i]][j];
+ }
+ }
+ }
+ } else {
+ for (i=0; i<nodes.length; i++) {
+ if (self.classContains(nodes[i],className)) {
+ matches[matches.length] = nodes[i];
+ }
+ }
+ }
+ return matches;
+ }
+
+ this.getOffX = function(o) {
+ // http://www.xs4all.nl/~ppk/js/findpos.html
+ var curleft = 0;
+ if (o.offsetParent) {
+ while (o.offsetParent) {
+ curleft += o.offsetLeft;
+ o = o.offsetParent;
+ }
+ }
+ else if (o.x) curleft += o.x;
+ return curleft;
+ }
+
+ this.getOffY = function(o) {
+ // http://www.xs4all.nl/~ppk/js/findpos.html
+ var curtop = 0;
+ if (!o) return false;
+ if (o.offsetParent) {
+ while (o.offsetParent) {
+ curtop += o.offsetTop;
+ o = o.offsetParent;
+ }
+ }
+ else if (o.y) curtop += o.y;
+ return curtop;
+ }
+
+ this.setOpacity = this.isIE?function(o,nOpacity) {
+ o.style.filter = 'alpha(opacity='+nOpacity+')';
+ }:function(o,nOpacity) {
+ o.style.opacity = nOpacity/100;
+ }
+
+ this.copy = function(oArray) {
+ // there *must* be a cleaner way to do this..
+ var o2 = [];
+ for (var i=0,j=oArray.length; i<j; i++) {
+ o2[i] = oArray[i];
+ }
+ return o2;
+ }
+
+};
+
+var smUtils = new SMUtils();
+
+function SMPlayer(oSoundPlayer) {
+ var self = this;
+ this.oParent = oSoundPlayer;
+ var u = smUtils; // alias
+ var getEBCN = u.getElementsByClassName;
+ this.oMain = document.getElementById('player-template');
+ this.o = this.oMain.getElementsByTagName('div')[0];
+ this.oLeft = getEBCN('left','div',this.o)[0];
+ this.oBar = getEBCN('mid','div',this.o)[0];
+ this.oSlider = getEBCN('slider','a',this.o)[0];
+ this.oTitle = getEBCN('caption','span',this.oBar)[0];
+ this.oSeek = getEBCN('seek','div',this.oBar)[0];
+ this.oDivider = getEBCN('divider','div',this.oBar)[0];
+ this.sFormat = (this.oTitle.innerHTML||'%artist - %title');
+ this.sFormatSeek = (this.oSeek.innerHTML||'%{time1}/%{time2} (%{percent}%)');
+ this.oProgress = getEBCN('progress','div',this.oBar)[0];
+ this.oRight = getEBCN('right','div',this.o)[0];
+ this.oTime = getEBCN('time','div',this.o)[0];
+ this.oShuffle = getEBCN('shuffle','a',this.o)[0];
+ this.oRepeat = getEBCN('loop','a',this.o)[0];
+ this.oMute = getEBCN('mute','a',this.o)[0];
+ this.oVolume = getEBCN('volume','a',this.o)[0];
+ this.lastTime = 0;
+ this.scale = 100;
+ this.percentLoaded = 0;
+ this.gotTimeEstimate = 0;
+ this.offX = 0;
+ this.x = 0;
+ this.xMin = 0;
+ this.barWidth = self.oBar.offsetWidth;
+ this.xMax = self.barWidth-self.oSlider.offsetWidth;
+ this.xMaxLoaded = 0;
+ // this.value = 0;
+ this.timer = null;
+ this._className = this.oBar.className;
+ this.tween = [];
+ this.frame = 0;
+ this.playState = 0;
+ this.busy = false; // when being dragged/animated/moved by user
+ this.maxOpacity = 100; // barber pole opacity (when animating in)
+ this.didDrag = false;
+ this.coords = {
+ 'x': 0,
+ 'y': 0,
+ 'offX':0,
+ 'offY':0,
+ 'titleWidth': 0
+ }
+ this.muted = false;
+ this.volume = soundManager.defaultOptions.volume;
+
+ var useAltFont = u.isMac; // specific letter-spacing CSS tweak (OSX has better-kerned/tighter spacing)
+
+ // set default caption
+ this.oTitle.innerHTML = getEBCN('default','div',this.oBar)[0].innerHTML;
+ this.oTitle.style.visibility = 'visible';
+
+ this.over = function() {
+ this.className = self._className+' hover';
+ event.cancelBubble=true;
+ return false;
+ }
+
+ this.out = function() {
+ this.className = self._className;
+ event.cancelBubble=true;
+ return false;
+ }
+
+ this.down = function(e) {
+ if (!self.oParent.currentSound) return false;
+ self.didDrag = false;
+ var e = e?e:event;
+ self.offX = e.clientX-(u.getOffX(self.oSlider)-u.getOffX(self.oBar));
+ self.busy = true;
+ u.addClass(self.oSlider,'active');
+ self.refreshSeek();
+ self.setSeekVisibility(1);
+ u.addEventHandler(document,'mousemove',self.move);
+ u.addEventHandler(document,'mouseup',self.up);
+ e.stopPropgation?e.stopPropagation():e.cancelBubble=true;
+ return false;
+ }
+
+ this.barDown = function(e) {
+ var e=e?e:event;
+ self.didDrag = false;
+ self.coords.x = e.clientX;
+ self.coords.y = e.clientY;
+ self.coords.offX = e.clientX-u.getOffX(self.oMain);
+ self.coords.offY = e.clientY-u.getOffY(self.oMain);
+ u.addEventHandler(document,'mousemove',self.barMove);
+ u.addEventHandler(document,'mouseup',self.barUp);
+ return false;
+ }
+
+ this.barMove = function(e) {
+ var e=e?e:event;
+ if (!self.didDrag) {
+ if (Math.abs(e.clientX-self.coords.x)<3 && Math.abs(e.clientY-self.coords.y)<3) {
+ // drag threshold
+ return false;
+ } else {
+ self.didDrag = true;
+ }
+ }
+ self.oMain.style.left = (e.clientX-self.coords.offX)+'px';
+ self.oMain.style.top = (e.clientY-self.coords.offY)+'px';
+ e.stopPropgation?e.stopPropagation():e.cancelBubble=true;
+ return false;
+ }
+
+ this.barUp = function(e) {
+ u.removeEventHandler(document,'mousemove',self.barMove);
+ u.removeEventHandler(document,'mouseup',self.barUp);
+ }
+
+ this.barClick = function(e) {
+ if (!self.oParent.currentSound) return false;
+ if (self.didDrag) return false;
+ var tgt = (e?e.target:event.srcElement);
+ var e=e?e:event;
+ if (tgt.tagName.toLowerCase()=='a') return false; // ignore clicks on links (eg. dragging slider)
+ var xNew = Math.min(e.clientX-u.getOffX(self.oBar),self.xMaxLoaded);
+ self.slide(self.x,xNew);
+ }
+
+ // volume x/y offsets
+ this.volumeX = 0;
+ this.volumeWidth = 0;
+
+ this.volumeDown = function(e) {
+ // set initial volume based on offset?
+ self.volumeX = u.getOffX(self.oVolume);
+ self.volumeWidth = parseInt(self.oVolume.offsetWidth);
+ soundManager._writeDebug('offsets: '+self.volumeX+', '+self.volumeWidth);
+ document.onmousemove = self.volumeMove;
+ document.onmouseup = self.volumeUp;
+ self.volumeMove(e);
+ return false;
+ }
+
+ this.volumeMove = function(e) {
+ // set volume based on position
+ var e = e?e:event;
+ var vol = ((e.clientX-self.volumeX)/(self.volumeWidth));
+ vol = Math.min(1,Math.max(0,vol));
+ self.setVolume(vol*100);
+ return false;
+ }
+
+ this.volumeUp = function(e) {
+ var e = e?e:event;
+ document.onmousemove = null;
+ document.onmouseup = null;
+ return false;
+ }
+
+ this.setVolume = function(nVol) {
+ if (!self.oParent.currentSound || self.volume == nVol) return false;
+ soundManager.defaultOptions.volume = nVol;
+ soundManager._writeDebug('soundManager.setVolume('+nVol+')');
+ self.volume = nVol;
+ if (!self.muted) soundManager.setVolume(self.oParent.currentSound,nVol);
+ u.setOpacity(self.oVolume,nVol);
+ }
+
+ this.move = function(e) {
+ var e=e?e:event;
+ var x = e.clientX-self.offX;
+ if (x>self.xMaxLoaded) {
+ x = self.xMaxLoaded;
+ } else if (x<self.xMin) {
+ x = self.xMin;
+ }
+ if (x != self.x) {
+ self.moveTo(x);
+ if (self.oParent.options.allowScrub) self.doScrub();
+ self.refreshSeek();
+ }
+ e.stopPropgation?e.stopPropagation():e.cancelBubble=true;
+ return false;
+ }
+
+ this.up = function(e) {
+ u.removeEventHandler(document,'mousemove',self.move);
+ u.removeEventHandler(document,'mouseup',self.up);
+ u.removeClass(self.oSlider,'active');
+ self.busy = false;
+ if (!self.oParent.options.allowScrub || self.oParent.paused) self.oParent.onUserSetSlideValue(self.x); // notify parent of update
+ self.setSeekVisibility();
+ return false;
+ }
+
+ this.slide = function(x0,x1) {
+ self.tween = animator.createTween(x0,x1);
+ self.busy = true;
+ self.slideLastExec = new Date();
+ animator.addMethod(self.animate,self.animateComplete);
+ animator.start();
+ }
+
+ this.refreshSeek = function() {
+ var sData = self.sFormatSeek;
+ var oSound = soundManager.getSoundById(self.oParent.currentSound);
+// soundManager._writeDebug('oSound.duration: '+oSound.duration);
+// soundManager._writeDebug(self.x+','+self.xMaxLoaded+','+oSound.duration+','+oSound.durationEstimate);
+ var sliderMSec = self.x/self.xMaxLoaded*oSound.duration;
+ var attrs = {
+ 'time1': self.getTime(sliderMSec,true),
+ 'time2': (!oSound.loaded?'~':'')+self.getTime(oSound.durationEstimate,true),
+ 'percent': Math.floor(sliderMSec/oSound.durationEstimate*100)
+ }
+ // soundManager._writeDebug(attrs.time1+' / '+attrs.time2+' / '+attrs.percent);
+ for (var attr in attrs) {
+ data = attrs[attr];
+ if (self.isEmpty(data)) data = '!null!';
+ sData = sData.replace('\%\{'+attr+'\}',data);
+ }
+ // remove any empty/null fields
+ var aData = sData.split(' ');
+ for (var i=aData.length; i--;) {
+ if (aData[i].indexOf('!null!')+1) aData[i] = null;
+ }
+ self.oSeek.innerHTML = aData.join(' ');
+ }
+
+ this.setSeekVisibility = function(bVisible) {
+ self.oTitle.style.visibility = bVisible?'hidden':'visible';
+ self.oSeek.style.display = bVisible?'block':'none';
+ }
+
+ this.animateComplete = function() {
+ self.busy = false;
+ // set sound position, if needed
+ if (self.oParent) self.oParent.onUserSetSlideValue(self.x);
+ }
+
+ this.moveTo = function(x) {
+ self.x = x;
+ self.oSlider.style.marginLeft = (Math.floor(x)+1)+'px'; // 1 offset
+ }
+
+ this.moveToEnd = function() {
+ self.moveTo(self.xMax);
+ }
+
+ this.slideLastExec = new Date();
+
+ this.animate = function() {
+ self.moveTo(self.tween[self.frame]);
+ self.frame = Math.max(++self.frame,animator.determineFrame(self.slideLastExec,40));
+ // if (self.frame++>=self.tween.length-1) {
+ if (self.frame>=self.tween.length-1) {
+ self.active = false;
+ self.frame = 0;
+ if (self._oncomplete) self._oncomplete();
+ return false;
+ }
+ return true;
+ }
+
+ this.doScrub = function(t) {
+ if (self.oParent.paused) return false;
+ if (self.oParent.options.scrubThrottle) {
+ if (!self.timer) self.timer = setTimeout(self.scrub,t||20);
+ } else {
+ self.scrub();
+ }
+ }
+
+ this.scrub = function() {
+ self.timer = null;
+ self.oParent.onUserSetSlideValue(self.x)
+ }
+
+ this.randomize = function() {
+ self.slide(self.x,parseInt(Math.random()*self.xMax));
+ }
+
+ this.getTimeEstimate = function(oSound) {
+ // try to estimate song length within first 128 KB (or total bytes), updating n times
+ var byteCeiling = Math.min(1048576||oSound.bytes);
+ var samples = (byteCeiling==oSound.bytes?2:4);
+ var milestone = Math.floor(oSound.bytesLoaded/byteCeiling*samples);
+ if (oSound.bytesLoaded>byteCeiling && self.gotTimeEstimate>0) return false;
+ if (self.gotTimeEstimate == milestone) return false;
+ self.gotTimeEstimate = milestone;
+ self.setMetaData(oSound);
+ }
+
+ this.getTime = function(nMSec,bAsString) {
+ // convert milliseconds to mm:ss, return as object literal or string
+ var nSec = Math.floor(nMSec/1000);
+ var min = Math.floor(nSec/60);
+ var sec = nSec-(min*60);
+ if (min == 0 && sec == 0) return null; // return 0:00 as null
+ return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});
+ }
+
+ this.updateTime = function(nMSec) {
+ // update "current playing" time
+ self.lastTime = nMSec;
+ self.oTime.innerHTML = (self.getTime(nMSec,true)||'0:00');
+ }
+
+ this.setTitle= function(sTitle) {
+ // used in the absence of ID3 info
+ self.oTitle.innerHTML = unescape(sTitle);
+ self.titleString = unescape(sTitle);
+ self.refreshScroll();
+ }
+
+ this.isEmpty = function(o) {
+ return (typeof o == 'undefined' || o == null || o == 'null' || (typeof o == 'string' && o.toLowerCase() == 'n/a' || o.toLowerCase == 'undefined'));
+ }
+
+ self.setMetaData = function(oSound) {
+ // get id3 data and populate according to formatting string (%artist - %title [%album] etc.)
+ var friendlyAttrs = {
+ // ID3V1 inherits from ID3V2 if populated
+ 'title': 'songname', // songname/TIT2
+ 'artist': 'artist', // artist/TPE1
+ 'album': 'album', // album/TALB
+ 'track': 'track', // track/TRCK
+ 'year': 'year', // year/TYER
+ 'genre': 'genre', // genre/TCON
+ 'comment': 'comment', // comment/COMM
+ 'url': 'WXXX'
+ }
+ var sTime = self.getTime(oSound.durationEstimate,true);
+ sTime = (sTime && !oSound.loaded?'~':'')+sTime;
+ var metaAttrs = {
+ // custom attributes taken directly from sound data
+ 'time': sTime // get time as mm:ss
+ }
+ // get normalised data, build string, replace
+ var sData = self.sFormat; // eg. %{artist} - %{title}
+ var data = null;
+ var useID3 = (!self.isEmpty(oSound.id3.songname) && !self.isEmpty(oSound.id3.artist)); // artist & title must be present to consider using ID3
+ for (var attr in friendlyAttrs) {
+ data = oSound.id3[friendlyAttrs[attr]];
+ if (self.isEmpty(data)) data = '!null!';
+ sData = sData.replace('\%\{'+attr+'\}',data);
+ }
+ for (var attr in metaAttrs) {
+ data = metaAttrs[attr];
+ if (self.isEmpty(data)) data = '!null!';
+ sData = sData.replace('\%\{'+attr+'\}',data);
+ }
+ // remove any empty/null fields
+ var aData = sData.split(' ');
+ for (var i=aData.length; i--;) {
+ if (aData[i].indexOf('!null!')+1) aData[i] = null;
+ }
+ var sMetaData = (useID3?unescape(aData.join(' ')):unescape(self.oParent.oPlaylist.getCurrentItem().userTitle)+(!self.isEmpty(metaAttrs.time)?' ('+metaAttrs.time+')':'')).replace(/\s+/g,' ');
+ self.oTitle.innerHTML = sMetaData;
+ self.titleString = sMetaData;
+ self.oParent.oPlaylist.getCurrentItem().setTooltip(sMetaData);
+ self.refreshScroll();
+ }
+
+ this.setLoadingProgress = function(nPercentage) {
+// soundManager._writeDebug('setLoadingProgress(): '+nPercentage);
+ self.percentLoaded = nPercentage;
+ self.xMaxLoaded = self.percentLoaded*self.xMax;
+ self.oProgress.style.width = parseInt(nPercentage*self.barWidth)+'px';
+ }
+
+ this.setLoading = function(bLoading) {
+ if (self.isLoading == bLoading) return false;
+ self.isLoading = bLoading;
+ var f = bLoading?u.addClass:u.removeClass;
+ f(self.oProgress,'loading');
+ self.setLoadingAnimation(bLoading);
+ }
+
+ this.setLoadingAnimation = function(bLoading) {
+ soundManager._writeDebug('setLoadingAnimation(): '+bLoading);
+ if (bLoading) {
+ self.loadingTween = self.loadingTweens[0];
+ animator.addMethod(self.loadingAnimate);
+ animator.addMethod(self.loadingAnimateSlide,self.loadingAnimateSlideComplete);
+ animator.start();
+ } else {
+ self.loadingTween = self.loadingTweens[1];
+ if (self.loadingAnimateFrame>0) {
+ // reverse animation while active
+ // self.loadingTween.reverse();
+ self.loadingAnimateFrame = (self.loadingTween.length-self.loadingAnimateFrame);
+ } else {
+ self.loadingTween = self.loadingTweens[1];
+ animator.addMethod(self.loadingAnimateSlide,self.loadingAnimateSlideComplete);
+ }
+ }
+ }
+
+ this.loadingAnimate = function() {
+ var d = new Date();
+ if (d-self.loadingLastExec<50) return true; // throttle fps
+ self.loadingLastExec = d;
+ self.loadingX--;
+ self.oProgress.style.backgroundPosition = self.loadingX+'px '+self.loadingY+'px';
+ return self.isLoading;
+ }
+
+ this.loadingLastExec = new Date();
+ this.loadingTweens = [animator.createTween(0,self.maxOpacity),animator.createTween(self.maxOpacity,0)];
+ this.loadingDirection = 0;
+ this.loadingTween = this.loadingTweens[this.loadingDirection];
+ this.loadingAnimateFrame = 0;
+
+ this.loadingAnimateSlide = function() {
+ var d = new Date();
+ if (d-self.loadingLastExec<50) return true; // throttle to 20fps
+ u.setOpacity(self.oProgress,self.loadingTween[self.loadingAnimateFrame++]);
+ if (!self.isLoading) self.loadingAnimate(); // show update if not actively loading
+ self.loadingLastExec = d; // updates time, prevents loadingAnimate()
+ return (++self.loadingAnimateFrame<self.loadingTweens[0].length);
+ }
+
+ this.loadingAnimateSlideComplete = function() {
+ soundManager._writeDebug('loadingAnimateSlideComplete()');
+ self.loadingAnimateFrame = 0;
+ // self.loadingDirection = !self.loadingDirection;
+ self.loadingX = 0;
+ }
+
+ this.isLoading = false;
+ this.loadingTimer = null;
+ this.loadingX = 0;
+ this.loadingY = 0;
+
+ this.setPlayState = function(bPlayState) {
+ soundManager._writeDebug('SMPlayer.setPlayState('+bPlayState+')');
+ self.playState = bPlayState;
+ self.oLeft.getElementsByTagName('span')[0].className = (self.playState?'playing':'');
+ }
+
+ this.togglePause = function() {
+ soundManager._writeDebug('togglePause()');
+ if (self.oParent.currentSound) {
+ soundManager.togglePause(self.oParent.currentSound);
+ } else {
+ self.oParent.oPlaylist.playNextItem();
+ }
+ var isPaused = soundManager.getSoundById(self.oParent.currentSound).paused;
+ self.oParent.paused = isPaused;
+ self.setPlayState(!isPaused);
+ }
+
+ this.toggleShuffle = function() {
+ soundManager._writeDebug('SMPlayer.toggleShuffle()');
+ self.oParent.oPlaylist.toggleShuffle();
+ self.setShuffle(self.oParent.oPlaylist.doShuffle);
+ }
+
+ this.toggleRepeat = function() {
+ soundManager._writeDebug('SMPlayer.toggleRepeat()');
+ self.oParent.oPlaylist.toggleRepeat();
+ self.setRepeat(self.oParent.oPlaylist.doRepeat);
+ }
+
+ this.toggleMute = function() {
+ soundManager._writeDebug('SMPlayer.toggleMute()');
+ self.muted = !self.muted;
+ // var nVol = self.muted?0:self.volume;
+ // if (self.oParent.currentSound) soundManager.setVolume(self.oParent.currentSound,nVol);
+ // soundManager.defaultOptions.volume = nVol; // update global volume
+ if (self.muted) {
+ soundManager.mute();
+ } else {
+ soundManager.unmute();
+ }
+ self.setMute(self.muted);
+ }
+
+ this.togglePlaylist = function() {
+ // show UI changes here in main player?
+ soundManager._writeDebug('SMPlayer.togglePlaylist()');
+ }
+
+ this.setShuffle = function(bShuffle) {
+ var f = (bShuffle?u.addClass:u.removeClass);
+ f(self.oShuffle,'active');
+ }
+
+ this.setRepeat = function(bRepeat) {
+ var f = (bRepeat?u.addClass:u.removeClass);
+ f(self.oRepeat,'active');
+ }
+
+ this.setMute = function(bMute) {
+ var f = (bMute?u.addClass:u.removeClass);
+ f(self.oMute,'active');
+ }
+
+ this.scrollOffset = 0;
+ this.scrollOffsetMax = self.oBar.offsetWidth;
+ this.scrollInterval = 100;
+ this.scrollAmount = 2; // pixels
+ this.scrollLastExec = new Date();
+ this.scrollTimer = null;
+ this.isScrolling = null;
+
+ this.scrollTo = function(nOffset) {
+ self.oTitle.style.marginLeft = (nOffset*-1)+'px';
+ // soundManager._writeDebug('scrollTo(): '+nOffset);
+ self.refreshDocumentTitle();
+ }
+
+ var tmp = document.createElement('p');
+ tmp.innerHTML = ' ';
+ var nbsp = tmp.innerHTML;
+
+ this.refreshDocumentTitle = function(nOffset) {
+ var offset = (typeof nOffset != 'undefined'?nOffset:null);
+ var str = (self.titleString).substr(nOffset != null?nOffset:Math.max(self.scrollOffset-self.scrollAmount,0));
+ str = str.replace(/ /i,' ');
+ if (self.oParent.options.usePageTitle) {
+ try {
+ document.title = str; // str.replace(/ /i,' ');
+ } catch(e) {
+ // oh well
+ }
+ }
+ }
+
+ this.doScroll = function() {
+ var d = new Date();
+ if (d-self.scrollLastExec<self.scrollInterval) return true; // throttle
+ self.scrollLastExec = d;
+ self.scrollOffset += self.scrollAmount;
+ if (self.scrollOffset>self.coords.titleWidth) {
+ // soundManager._writeDebug('wrapping around');
+ self.scrollOffset = (smUtils.isIE?5:1);
+ }
+ self.scrollTo(self.scrollOffset);
+ return self.isScrolling;
+ }
+
+ this.resetScroll = function() {
+ soundManager._writeDebug('resetScroll()');
+ self.scrollOffset = 0;
+ self.scrollTo(self.scrollOffset);
+ self.refreshDocumentTitle(0);
+ }
+
+ this.setScroll = function(bScroll) {
+ soundManager._writeDebug('setScroll('+bScroll+')');
+ if (bScroll && !self.isScrolling) {
+ soundManager._writeDebug('starting scroll');
+ self.isScrolling = true;
+ animator.addMethod(self.doScroll,self.resetScroll);
+ animator.start();
+ }
+ if (!bScroll && self.isScrolling) {
+ soundManager._writeDebug('stopping scroll');
+ self.isScrolling = false;
+ }
+ }
+
+ this.titleString = ''; // for document title
+
+ this.refreshScroll = function() {
+ // self.scrollOffsetMax = 25; // self.oTitle.innerHTML.length;
+ // soundManager._writeDebug('refreshScroll(): '+self.scrollOffsetMax);
+ self.coords.titleWidth = self.oTitle.offsetWidth;
+ var doScroll = (self.coords.titleWidth>self.scrollOffsetMax);
+ if (doScroll) {
+ var sHTML = self.oTitle.innerHTML;
+ var dHTML = self.oDivider.innerHTML; // heh
+ self.oTitle.innerHTML = sHTML+dHTML;
+ self.coords.titleWidth = self.oTitle.offsetWidth;
+ self.setScroll(doScroll);
+ self.titleString = sHTML;
+ self.oTitle.innerHTML = sHTML+dHTML+sHTML;
+ } else {
+ self.setScroll(doScroll);
+ self.titleString = self.oTitle.innerHTML;
+ }
+ // if (doScroll) self.oTitle.innerHTML = (self.oTitle.innerHTML+' *** '+self.oTitle.innerHTML); // fake the "repeat"
+ }
+
+ this.reset = function() {
+ soundManager._writeDebug('SMPlayer.reset()');
+ if (self.x != 0) self.moveTo(0);
+ self.setLoadingProgress(0);
+ self.gotTimeEstimate = 0;
+ self.updateTime(0);
+ self.resetScroll();
+ }
+
+ this.destructor = function() {
+ self.oBar.onmouseover = null;
+ self.oBar.onmouseout = null;
+ self.o.onmousedown = null;
+ self.o = null;
+ self.oV = null;
+ self.oB.onclick = null;
+ self.oB = null;
+ }
+
+ if (u.isIE) {
+ // IE is lame, no :hover
+ this.oBar.onmouseover = this.over;
+ this.oBar.onmouseout = this.out;
+ }
+
+ if (u.isSafari) u.addClass(this.oMain,'noOpacity'); // stupid transparency tweak
+ if (useAltFont) u.addClass(this.oMain,'altFont');
+
+ // this.setScroll(true); // test
+
+ this.oSlider.onmousedown = this.down;
+ this.oBar.onmousedown = this.barDown;
+ this.oBar.onclick = this.barClick;
+// self.update();
+
+ // start scrolling, if needed
+ self.refreshScroll();
+
+}
+
+function Animator() {
+ var self = this;
+ this.timer = null;
+ this.active = null;
+ this.methods = [];
+ this.tweenStep = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2];
+ this.frameCount = this.tweenStep.length;
+ // this.lastExec = new Date();
+
+ this.start = function() {
+ if (self.active==true) return false;
+ self.active = true;
+ self.timer = window.setInterval(self.animate,20);
+ }
+
+ this.stop = function() {
+ if (self.timer) {
+ window.clearInterval(self.timer);
+ self.timer = null;
+ self.active = false;
+ }
+ }
+
+ this.reset = function() {
+ self.methods = [];
+ }
+
+ this.addMethod = function(oMethod,oncomplete) {
+ for (var i=self.methods.length; i--;) {
+ if (self.methods[i] == oMethod) {
+ if (oncomplete) {
+ self.methods[i]._oncomplete = oncomplete;
+ }
+ return false;
+ }
+ }
+ self.methods[self.methods.length] = oMethod;
+ self.methods[self.methods.length-1]._oncomplete = oncomplete||null;
+ }
+
+ this.createTween = function(start,end) {
+ var start = parseInt(start);
+ var end = parseInt(end);
+ var tweenStepData = self.tweenStep;
+ var tween = [start];
+ var tmp = start;
+ var diff = end-start;
+ var j = tweenStepData.length;
+ var isAscending = end>start;
+ for (var i=0; i<j; i++) {
+ tmp += diff*tweenStepData[i]*0.01;
+ tween[i] = parseInt(tmp);
+ // floor/ceiling checks (rounding errors?)
+ if (isAscending) {
+ if (tween[i]>end) tween[i] = end;
+ } else {
+ if (tween[i]<end) tween[i] = end;
+ }
+ }
+ if (tween[i] != end) tween[i] = end;
+ return tween;
+ }
+
+ this.determineFrame = function(tStart,nInterval) {
+ var d = new Date();
+ // var tElapsed = (new Date()-tStart);
+ // determine current frame, including lag
+ return Math.min(self.frameCount,Math.floor(self.frameCount*((new Date()-tStart)/(nInterval*self.frameCount))));
+ }
+
+ this.animate = function(e) {
+ if (!self.active) return false;
+ /*
+ var now = new Date();
+ if (now-self.lastExec<50) return false; // no more than 20 fps
+ self.lastExec = now;
+ */
+ var active = false;
+ for (var i=self.methods.length; i--;) {
+ if (self.methods[i]) {
+ if (self.methods[i]()) {
+ active = true;
+ } else {
+ if (self.methods[i]._oncomplete) {
+ self.methods[i]._oncomplete();
+ self.methods[i]._oncomplete = null;
+ }
+ self.methods[i] = null;
+ }
+ }
+ }
+ if (!active) {
+ self.stop();
+ self.reset();
+ }
+ }
+
+}
+
+var animator = new Animator();
+
+function SPPlaylist(oSoundPlayer,oPlaylist) {
+ var self = this;
+ var oParent = oSoundPlayer;
+ this.o = null;
+ this.links = [];
+ this.items = [];
+ this.playlistItems = []; // pointer
+ this.playlistItemsUnsorted = [];
+ this.playlistItemsShuffled = [];
+ this.index = -1;
+ this.lastIndex = null;
+ this.o = oPlaylist; // containing element
+ this.history = [];
+ this.isVisible = false;
+ this.doShuffle = false;
+ this.doRepeat = false;
+ this._ignoreCurrentSound = false;
+
+ var seamlessDelay = 0; // offset for justBeforeFinish
+
+ this.findURL = function(sURL) {
+ for (var i=self.items.length; i--;) {
+ if (self.items[i].url == sURL) return true;
+ }
+ return false;
+ }
+
+ this.addItem = function(oOptions) {
+ // oOptions = {url:string,name:string}
+ var sURL = oOptions.url||null;
+ var sName = oOptions.name||null;
+ if (!sURL || self.findURL(sURL)) return false;
+ self.items[self.items.length] = {
+ url: sURL,
+ name: (sName||sURL.substr(sURL.lastIndexOf('/')+1))
+ }
+ soundManager._writeDebug('SPPlaylist().addItem('+self.items[self.items.length-1].url+')');
+ }
+
+ this.getItem = function(sURL) {
+ for (var i=self.items.length; i--;) {
+ if (self.items[i].url == sURL) return self.items[i];
+ }
+ return null;
+ }
+
+ this.getCurrentItem = function() {
+ return self.playlistItems[self.index];
+ }
+
+ this.getRandomItem = function() {
+ return parseInt(Math.random()*self.items.length);
+ }
+
+ this.calcNextItem = function() {
+ var nextItem = self.index+1;
+ if (nextItem >= self.items.length) nextItem = -1;
+ return nextItem;
+ }
+
+ this.getNextItem = function() {
+ self.index++;
+ if (self.index>=self.items.length) {
+ self.index = -1; // reset
+ return false;
+ }
+ return true;
+ }
+
+ this.calcPreviousItem = function() {
+ var prevItem = self.index-1;
+ if (prevItem <0) prevItem = self.items.length-1;
+ return prevItem;
+ }
+
+ this.getPreviousItem = function() {
+ // self.index--;
+ if (--self.index<0) {
+ self.index = self.items.length-1;
+ return false;
+ }
+ return true;
+ }
+
+ this.playNextItem = function() {
+ // call getNextItem, decide what to do based on repeat/random state etc.
+ soundManager._writeDebug('SPPlaylist.playNextItem()');
+
+ if (self.getNextItem() || self.doRepeat) {
+ if (self.doRepeat && self.index == -1) {
+ // did loop
+ soundManager._writeDebug('did loop - restarting playlist');
+ self.index = 0;
+ }
+ self.play(self.index);
+ self.setHighlight(self.index);
+ } else {
+ soundManager._writeDebug('SPPlaylist.playNextItem(): finished?');
+ // finished
+ self.index = self.items.length-1;
+ if (!oParent.playState) {
+ self.play(self.index); // only start playing if currently stopped
+ }
+ // self.setHighlight(self.index);
+ }
+ }
+
+ this.playPreviousItem = function() {
+ // call getPreviousItem, decide what to do
+ soundManager._writeDebug('SPPlaylist.playPreviousItem()');
+ if (self.getPreviousItem() || self.doRepeat) {
+ // self.play(self.playlistItems[self.index].index);
+ self.play(self.index);
+ self.setHighlight(self.index);
+ } else {
+ // soundManager._writeDebug('SPPlaylist.playPreviousItem(): finished?');
+ self.index = 0;
+ // if (!oParent.playState) self.play(self.playlistItems[self.index].index); // only start playing if currently stopped
+ if (!oParent.playState) self.play(self.index); // only start playing if currently stopped
+ self.setHighlight(self.index);
+ }
+ }
+
+ this.setHighlight = function(i) {
+ if (self.playlistItems[i]) self.playlistItems[i].setHighlight();
+ // self.index = i;
+ if (self.lastIndex != null && self.lastIndex != i) self.removeHighlight(self.lastIndex);
+ self.lastIndex = i;
+ }
+
+ this.removeHighlight = function(i) {
+ if (self.playlistItems[i]) self.playlistItems[i].removeHighlight();
+ }
+
+ this.selectItem = function(i) {
+ self.index = i;
+ self.setHighlight(i);
+ }
+
+ this.onItemBeforeFinish = function() {
+ // NOTE: This could be inconsistent across systems and is not guaranteed (it's JS-based timing.)
+ if (oParent.oSMPlayer.busy) return false; // ignore if user is scrubbing
+ // setTimeout(self.onItemJustBeforeFinish,4800);
+ soundManager._writeDebug('SPPlaylist.onItemBeforeFinish()');
+ // start preloading next track
+ var nextItem = self.calcNextItem();
+ self.load(self.playlistItems[nextItem].index);
+ }
+
+ this.onItemJustBeforeFinish = function() {
+ // compensate for JS/Flash lag to attempt seamless audio. (woah.)
+ soundManager._writeDebug('SPPlaylist.onItemJustBeforeFinish()');
+ // soundManager.getSoundById(oParent.currentSound)._ignoreOnFinish = true; // prevent this sound's onfinish() from triggering next load, etc.
+ soundManager.getSoundById(this.sID)._ignoreOnFinish = true; // prevent this sound's onfinish() from triggering next load, etc.
+ if (this.sID == oParent.currentSound) { // just in case this method fires too late (next song already playing..)
+ self._ignoreCurrentSound = true; // prevent current track from stopping
+ self.playNextItem();
+ }
+ }
+
+ this.onItemBeforeFinishComplete = function() {
+ // TODO: Make getting SID reference cleaner (scope to playlist item)
+ soundManager._writeDebug('onItemBeforeFinishComplete()');
+ // soundManager.stop(oParent.lastSound);
+ // soundManager.unload(oParent.lastSound);
+ }
+
+ this.onItemFinish = function() {
+ soundManager._writeDebug('SPPlaylist.onItemFinish()');
+ if (this._ignoreOnFinish) {
+ // special case for seamless playback - don't trigger next track, already done
+ soundManager._writeDebug('sound '+this.sID+' ended with ._ignoreOnFinish=true');
+ this._ignoreOnFinish = false; // reset for next use
+ return false;
+ }
+ oParent.setPlayState(false); // stop
+ if (!self.getNextItem()) {
+ self.onfinish();
+ } else {
+ // self.play(self.playlistItems[self.index].index); // not needed?
+ self.play(self.index); // not needed?
+ self.setHighlight(self.index);
+ }
+ }
+
+ this.onfinish = function() {
+ // end of playlist
+ soundManager._writeDebug('SPPlaylist.onfinish()');
+ oParent.onfinish();
+ // hacks: reset scroll and index
+ oParent.x = 0; // haaack
+ oParent.lastSound = oParent.currentSound;
+ oParent.currentSound = null;
+ self.removeHighlight(self.index); // reset highlight
+ self.index = -1; // haaack
+// self.reset();
+
+ // if repeat mode, start playing next song
+ if (self.doRepeat) self.playNextItem();
+
+ }
+
+ this.show = function() {
+ self.setDisplay(true);
+ }
+
+ this.hide = function() {
+ self.setDisplay();
+ }
+
+ this.toggleShuffle = function() {
+ soundManager._writeDebug('SPPlaylist.toggleShuffle()');
+ self.doShuffle = !self.doShuffle;
+ soundManager._writeDebug('shuffle: '+self.doShuffle);
+ if (self.doShuffle) {
+ // undo current highlight
+ self.removeHighlight(self.index);
+ self.shufflePlaylist();
+ self.playlistItems = self.playlistItemsShuffled;
+ self.index = 0; // self.playlistItems[0].index;
+ self.setHighlight(0);
+ self.play(0);
+ } else {
+ self.index = self.playlistItems[self.index].origIndex; // restore to last unsorted position
+ self.lastIndex = self.playlistItems[self.lastIndex].origIndex; // map new lastIndex
+ self.playlistItems = self.playlistItemsUnsorted;
+ }
+ }
+
+ this.toggleRepeat = function() {
+ soundManager._writeDebug('SPPlaylist.toggleRepeat()');
+ self.doRepeat = !self.doRepeat;
+ soundManager._writeDebug('repeat: '+self.doRepeat);
+ }
+
+ this.shufflePlaylist = function() {
+ soundManager._writeDebug('SPPlaylist.shufflePlaylist()');
+ var p = self.playlistItemsShuffled, j = null, tmp = null, newIndex = null;
+ for (var i=p.length; i--;) {
+ j = parseInt(Math.random()*p.length);
+ tmp = p[j];
+ p[j] = p[i];
+ p[i] = tmp;
+ }
+ }
+
+ this.displayTweens = null;
+ this.opacityTweens = [animator.createTween(90,0),animator.createTween(0,90)];
+ this.displayTween = null;
+ this.opacityTween = null;
+ this.widthTweens = null;
+ this.widthTween = null;
+
+ this.frame = 0;
+
+ this.setOpacity = function(nOpacity) {
+ // soundManager._writeDebug('spPlaylist.setOpacity('+nOpacity+')');
+ // u.setOpacity(self.o,nOpacity);
+ }
+
+ this.createTweens = function() {
+ // calculate tweens
+ var base = (smUtils.isOldIE?16:0); // IE<7 needs vertical offset for playlist.
+ self.displayTweens = [animator.createTween(base,self.o.offsetHeight),animator.createTween(self.o.offsetHeight,base)];
+ self.widthTweens = [animator.createTween(self.o.offsetWidth,1),animator.createTween(1,self.o.offsetWidth)];
+ }
+
+ this.setCoords = function(nHeight,nOpacity,nWidth) {
+ self.o.style.marginTop = -nHeight+'px';
+ if (!smUtils.isIE) smUtils.setOpacity(self.o,nOpacity);
+ // self.o.style.width = nWidth+'px';
+ // self.o.style.marginLeft = (parseInt((self.widthTweens[0][0]-nWidth)/2)+1)+'px';
+ }
+
+ this.animate = function() {
+ self.frame = Math.max(++self.frame,animator.determineFrame(self.displayLastExec,35));
+ // self.frame++;
+ self.setCoords(self.displayTween[self.frame],self.opacityTween[self.frame],self.widthTween[self.frame]);
+ // self.playlistItems[self.frame].doAnimate(1);
+ if (self.frame>=self.displayTween.length-1) {
+ // self.active = false;
+ self.frame = 0;
+ return false;
+ }
+ return true;
+ }
+
+ this.displayLastExec = new Date();
+
+ this.setDisplay = function(bDisplay) {
+ soundManager._writeDebug('setDisplay()');
+ self.displayTween = self.displayTweens[self.isVisible?1:0];
+ self.opacityTween = self.opacityTweens[self.isVisible?1:0];
+ self.widthTween = self.widthTweens[self.isVisible?1:0];
+ if (self.frame>0) self.frame = self.displayTweens[0].length-self.frame;
+ self.displayLastExec = new Date();
+ animator.addMethod(self.animate,self.animateComplete);
+ animator.start();
+ }
+
+ this.animateComplete = function() {
+ // soundManager._writeDebug('spPlaylist.animateComplete()');
+ // if (self.isVisible) self.o.style.display = 'none';
+ }
+
+ this.toggleDisplay = function() {
+ self.isVisible = !self.isVisible;
+ if (!self.isVisible) self.o.style.display = 'block';
+ self.setDisplay(self.isVisible);
+ }
+
+ this.createPlaylist = function() {
+ for (var i=0,j=self.items.length; i<j; i++) {
+ self.playlistItems[i] = new SPPLaylistItem(self.links[i],self,i);
+ }
+ // assign copies
+ self.playlistItemsUnsorted = smUtils.copy(self.playlistItems);
+ self.playlistItemsShuffled = smUtils.copy(self.playlistItems);
+ }
+
+ this.searchForSoundLinks = function(oContainer) {
+ soundManager._writeDebug('SPPlaylist.searchForSoundLinks()');
+ var o = oContainer||document.body;
+ if (!o) return false;
+ self.links = [];
+ var items = o.getElementsByTagName('a');
+ for (var i=0,j=items.length; i<j; i++) {
+ try {
+ // if [object], then ignore??
+ if (items[i].href.toString().indexOf('.mp3')+1) {
+ self.links[self.links.length] = items[i];
+ self.addItem({url:items[i].href.toString()});
+ }
+ } catch(e) {
+ // error may be thrown by funny characters in URL such as % for some reason under IE 7 (eg. "100% pure love" seemed to fail - odd.)
+ soundManager._writeDebug('<b>SPPlaylist.searchForSoundLinks(): Error at link index '+i+'</b> - may be caused by funny characters in URL');
+ // return false;
+ }
+ }
+ }
+
+ this.load = function(i) {
+ soundManager._writeDebug('SPPlaylist.load('+i+')');
+ // start preloading a sound
+ var sID = 'spsound'+i;
+ var s = soundManager.getSoundById(sID,true);
+ if (s) {
+ // reload (preload) existing sound
+ soundManager._writeDebug('reloading existing sound');
+ var thisOptions = {
+ 'autoPlay': false,
+ 'url': s.url, // reload original URL (assuming currently "unloaded" state)
+ 'stream': true
+ }
+ s.load(thisOptions);
+ } else {
+ soundManager._writeDebug('preloading new sound');
+ soundManager.createSound({
+ 'id': sID,
+ 'url': self.items[i].url,
+ // 'onload': self.onload,
+ 'onload': oParent.onload,
+ 'stream': true,
+ 'autoLoad': true,
+ 'autoPlay': false,
+ 'onid3': oParent.onid3,
+ 'onplay': oParent.onplay,
+ 'whileloading': oParent.whileloading,
+ 'whileplaying': oParent.whileplaying,
+ 'onbeforefinish': self.onItemBeforeFinish,
+ 'onbeforefinishcomplete': self.onItemBeforeFinishComplete,
+ 'onbeforefinishtime': 5000,
+ 'onjustbeforefinish': self.onItemJustBeforeFinish,
+ 'onjustbeforefinishtime':seamlessDelay , // 0 = do not call
+ 'onfinish': self.onItemFinish,
+ 'multiShot': false
+ });
+ // s = soundManager.getSoundById(sID);
+ // soundManager._writeDebug('<b>preloaded sound load state: '+s.loaded+'</b>');
+ // soundManager.getSoundById(sID).disableEvents(); // prevent UI calls etc., just preload
+ // self.setMetaData(soundManager.getSoundById(sID));
+ }
+ }
+
+ this.play = function(i) {
+ // scoped to playlistItem instance
+ if (!self.items[i]) return false;
+ soundManager._writeDebug('SPPlaylist.play()');
+ // var sID = 'spsound'+self.index;
+ // if (i==-1) i=0; // safeguard
+ if (self.doShuffle) i = self.playlistItems[i].index; // if shuffle enabled, map to proper sound
+ var sID = 'spsound'+i;
+ var exists = false;
+ if (oParent.currentSound) {
+ if (!self._ignoreCurrentSound) {
+ soundManager._writeDebug('stopping current sound');
+ soundManager.stop(oParent.currentSound);
+ soundManager.unload(oParent.currentSound);
+ } else {
+ soundManager._writeDebug('allowing current sound to finish');
+ self._ignoreCurrentSound = false;
+ }
+ }
+ if (!soundManager.getSoundById(sID,true)) {
+ soundManager._writeDebug('creating sound '+sID);
+ soundManager.createSound({
+ 'id': sID,
+ 'url': self.items[i].url,
+ // 'onload': self.onload,
+ 'onload': oParent.onload,
+ 'stream': true,
+ 'autoPlay': false,
+ 'onid3': oParent.onid3,
+ 'onplay': oParent.onplay,
+ 'whileloading': oParent.whileloading,
+ 'whileplaying': oParent.whileplaying,
+ 'onbeforefinish': self.onItemBeforeFinish,
+ 'onbeforefinishcomplete': self.onItemBeforeFinishComplete,
+ 'onbeforefinishtime': 5000,
+ 'onjustbeforefinish': self.onItemJustBeforeFinish,
+ 'onjustbeforefinishtime':seamlessDelay,
+ 'onfinish': self.onItemFinish,
+ 'multiShot': false
+ });
+ } else {
+ // sound already exists - preload or replay use cases
+ exists = true;
+ soundManager._writeDebug('sound id '+sID+' already exists (preload/reuse case)');
+ }
+
+ soundManager._writeDebug('Refreshing sound details');
+ oParent.refreshDetails(sID);
+ oParent.lastSound = oParent.currentSound;
+ oParent.currentSound = sID;
+ oParent.reset(); // ensure slider starts at 0
+ oParent.setLoading(true);
+ soundManager.play(sID);
+ oParent.setPlayState(true);
+
+ // apply URL hash
+ if (oParent.options.allowBookmarking) window.location.hash = 'track='+encodeURI(self.items[i].url.substr(self.items[i].url.lastIndexOf('/')+1));
+
+ if (exists) {
+ var s = soundManager.getSoundById(sID);
+ oParent.setMetaData(s);
+ if (s.loaded) {
+ // already loaded before playing started - calculate time estimates, re-call onload() now
+ oParent.onload.apply(s);
+ }
+ }
+
+ }
+
+ this.init = function() {
+ self.o = document.getElementById('playlist-template');
+ // set width to parent
+ self.o.style.width = (parseInt(oParent.oSMPlayer.oMain.offsetWidth)-2)+'px';
+ // smUtils.getElementsByClassName('sm2playlist-box','div',self.o)[0].style.width = '100px';
+ }
+
+ this.loadFromHash = function() {
+ // given a hash, match an MP3 URL and play it.
+ if (!oParent.options.allowBookmarking) return false;
+ var hash = oParent.options.hashPrefix;
+ var hashOffset = hash.length+1;
+ var i = (window.location.hash.indexOf(hash));
+ if (i==-1) return false;
+ var url = decodeURI(window.location.hash.substr(hashOffset));
+ soundManager._writeDebug('loadFromHasn(): searching for '+url);
+ var index = self.findItemByURL(encodeURI(url));
+ if (index == -1) {
+ soundManager._writeDebug('trying alternate search..');
+ index = self.findItemByURL(escape(url));
+ }
+ if (index != -1) {
+ soundManager._writeDebug('loadFromHash(): found index '+index+' ('+url+')');
+ self.selectItem(index);
+ self.play(index);
+ smUtils.addEventHandler(window,'beforeunload',self.removeHash);
+ } else {
+ soundManager._writeDebug('loadFromHash(): no match found');
+ }
+ }
+
+ this.removeHash = function() {
+ // experimental - probably won't work in any good browsers (eg. Firefox)
+ try {
+ window.location.hash = ''; // prevent reload from maintaining current state
+ } catch(e) {
+ // oh well
+ }
+ }
+
+ this.findItemByURL = function(sURL) {
+ for (var i=self.items.length; i--;) {
+ if (self.items[i].url.indexOf(sURL)!=-1) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ this.init();
+
+}
+
+function SPPLaylistItem(oLink,oPlaylist,nIndex) {
+ var self = this;
+ var oParent = oPlaylist;
+ this.index = nIndex;
+ this.origIndex = nIndex;
+ this.userTitle = oLink.innerHTML;
+ var sURL = oParent.items[this.index].url;
+ this.o = document.createElement('li');
+ if (nIndex%2==0) this.o.className = 'alt'; // striping
+ this.o.innerHTML = '<a href="'+sURL+'"><span></span></a>';
+ this.o.getElementsByTagName('span')[0].innerHTML = this.userTitle;
+
+ this.setHighlight = function() {
+ smUtils.addClass(self.o,'highlight');
+ }
+
+ this.removeHighlight = function() {
+ smUtils.removeClass(self.o,'highlight');
+ }
+
+ this.setTooltip = function(sHTML) {
+ self.o.title = sHTML;
+ }
+
+ this.onclick = function() {
+ if (oParent.doShuffle) soundPlayer.toggleShuffle(); // disable shuffle, if on (should be oParent.oParent too, ideally)
+ oParent.selectItem(self.index);
+ oParent.play(self.index);
+ return false;
+ }
+
+ this.init = function() {
+ // append self.o somewhere
+ // oParent.o.appendChild(self.o);
+ document.getElementById('playlist-template').getElementsByTagName('ul')[0].appendChild(self.o);
+ self.o.onclick = self.onclick;
+ }
+
+ this.init();
+
+}
+
+
+function SoundPlayer() {
+ var self = this;
+ this.urls = []; // will get from somewhere..
+ this.currentSound = null; // current sound ID (offset/count)
+ this.lastSound = null;
+ this.oPlaylist = null;
+ this.oSMPlayer = null;
+ this.playState = 0;
+ this.paused = false;
+ this.options = {
+ allowScrub: true, // let sound play when possible while user is dragging the slider (seeking)
+ scrubThrottle: false, // prevent scrub update call on every mouse move while dragging - "true" may be nicer on CPU, but track will update less
+ allowBookmarking: false, // change URL to reflect currently-playing MP3
+ usePageTitle: true, // change document.title (window title) to reflect track data
+ hashPrefix: 'track=' // eg. #track=foo%20bar.mp3
+ }
+ var u = smUtils; // alias
+
+ this.reset = function() {
+ // this.sliderPosition = 0;
+ self.oSMPlayer.reset();
+ }
+
+ this.whileloading = function() {
+ if (this.sID != self.currentSound) return false;
+ // "this" scoped to soundManager SMSound object instance
+ // this.sID, this.bytesLoaded, this.bytesTotal
+ // soundManager._writeDebug('whileLoading: '+parseInt(this.bytesLoaded/this.bytesTotal*100)+' %');
+ self.oSMPlayer.setLoadingProgress(Math.max(0,this.bytesLoaded/this.bytesTotal));
+ self.oSMPlayer.getTimeEstimate(this);
+ }
+
+ this.onload = function() {
+ if (this.sID != self.currentSound) return false;
+ // force slider calculation (position) update?
+ // soundManager._writeDebug('<b>time, estimate: '+this.duration+', '+this.durationEstimate+'</b>');
+ soundManager._writeDebug('soundPlayer.onload()');
+ self.oSMPlayer.setLoadingProgress(1); // ensure complete
+ self.setMetaData(this);
+ self.oSMPlayer.setLoading(false);
+
+ }
+
+ this.onid3 = function() {
+ if (this.sID != self.currentSound) return false;
+ soundManager._writeDebug('SoundPlayer.onid3()');
+ // update with received ID3 data
+ self.setMetaData(this);
+ }
+
+ this.onfinish = function() {
+ // sound reached end - reset controls, stop?
+ // document.getElementById('controls').getElementsByTagName('dd')[0].innerHTML = 'Finished playing.';
+ soundManager._writeDebug('SoundPlayer.onfinish()');
+ self.oSMPlayer.moveToEnd();
+ self.setPlayState(false);
+ }
+
+ this.onplay = function() {
+ // started playing?
+ soundManager._writeDebug('.onplay!');
+ }
+
+ this.whileplaying = function() {
+ if (this.sID != self.currentSound) return false;
+ // this.sID, this.position, this.duration
+ // with short MP3s when loading for >1st time, this.duration can be null??
+ var duration = (!this.loaded?this.durationEstimate:this.duration); // use estimated duration until completely loaded
+ if (this.position>duration) return false; // can happen when resuming from an unloaded state?
+ var newPos = Math.floor(this.position/duration*self.oSMPlayer.xMax);
+ if (newPos != self.oSMPlayer.x) { // newPos > self.oSMPlayer.x
+ if (!self.oSMPlayer.busy) {
+ self.oSMPlayer.moveTo(newPos);
+ self.oSMPlayer.update();
+ }
+ }
+ if (Math.abs(this.position-self.oSMPlayer.lastTime)>1000) self.oSMPlayer.updateTime(this.position);
+ }
+
+ this.onUserSetSlideValue = function(nX) {
+ // called from slider control
+ var x = parseInt(nX);
+ // soundManager._writeDebug('onUserSetSlideValue('+x+')');
+ // play sound at this position
+ var s = soundManager.sounds[self.currentSound];
+ if (!s) return false;
+ var nMsecOffset = Math.floor(x/self.oSMPlayer.xMax*s.durationEstimate);
+ soundManager.setPosition(self.currentSound,nMsecOffset);
+ }
+
+ this.setTitle = function(sTitle) {
+ var title = (typeof sTitle == 'undefined'?'Untitled':sTitle);
+ self.oSMPlayer.setTitle(title);
+ self.oSMPlayer.refreshScroll();
+ }
+
+ this.setMetaData = function(oSound) {
+ // pass sound to oSMPlayer
+ self.oSMPlayer.setMetaData(oSound);
+ }
+
+ this.setLoading = function(bLoading) {
+ self.oSMPlayer.setLoading(bLoading);
+ }
+
+ this.setPlayState = function(bPlaying) {
+ self.playState = bPlaying;
+ self.oSMPlayer.setPlayState(bPlaying);
+ }
+
+ this.refreshDetails = function(sID) {
+ var id = (sID||self.currentSound);
+ if (!id) return false;
+ var s = soundManager.getSoundById(id);
+ if (!s) return false;
+ soundManager._writeDebug('refreshDetails(): got sound: '+s);
+ // in absence of ID3, use user-provided data (URL or link text?)
+ self.setTitle(self.oPlaylist.getCurrentItem().userTitle);
+ }
+
+ this.volumeDown = function(e) {
+ self.oSMPlayer.volumeDown(e);
+ }
+
+ this.togglePause = function() {
+ self.oSMPlayer.togglePause();
+ }
+
+ this.toggleShuffle = function() {
+ self.oSMPlayer.toggleShuffle();
+ }
+
+ this.toggleRepeat = function() {
+ self.oSMPlayer.toggleRepeat();
+ }
+
+ this.toggleMute = function() {
+ // soundManager._writeDebug('soundPlayer.toggleMute()');
+ self.oSMPlayer.toggleMute();
+ }
+
+ this.togglePlaylist = function() {
+ soundManager._writeDebug('soundPlayer.togglePlaylist()');
+ self.oPlaylist.toggleDisplay();
+ self.oSMPlayer.togglePlaylist();
+ }
+
+ this.init = function() {
+ self.oSMPlayer = new SMPlayer(self);
+ }
+
+}
+
+var soundPlayer = new SoundPlayer();
+
+function initStuff() {
+ soundPlayer.init(); // load mp3, etc.
+ setTimeout(initOtherStuff,20);
+}
+
+function initOtherStuff() {
+ soundPlayer.oPlaylist = new SPPlaylist(soundPlayer,null);
+ soundPlayer.oPlaylist.searchForSoundLinks();
+ soundPlayer.oPlaylist.createPlaylist();
+ soundPlayer.oPlaylist.createTweens(); // make tweens for playlist
+ soundPlayer.oPlaylist.loadFromHash();
+}
+
+soundManager.debugMode = (window.location.toString().match(/debug=1/)?true:false); // set debug mode
+soundManager.defaultOptions.multiShot = false;
+
+soundManager.onload = function() {
+ // called after window.onload() + SoundManager is loaded
+ soundManager._writeDebug('<b><a href="http://www.schillmania.com/projects/soundmanager2/">www.schillmania.com/projects/soundmanager2/</a></b>');
+ soundManager._writeDebug('<b>-- jsAMP v0.99a.20080331 --</b>',1);
+ initStuff();
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/basic.html new file mode 100755 index 0000000..9a4b151 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/basic.html @@ -0,0 +1,48 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Basic MP3 Play Button (Simple Demo)</title>
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+</style>
+<link rel="stylesheet" type="text/css" href="css/mp3-player-button.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/mp3-player-button.js"></script>
+</head>
+
+<body>
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play MP3s inline with javascript using SoundManager 2">SoundManager 2</a> / Basic MP3 Play Button: Template</h1>
+
+ <p>View the source code of this page for detail. Don't forget to set <b>soundManager.debugMode = false;</b> to disable debug output.</p>
+
+ <p>Walking <a href="../jsAMP-preview/audio/walking.mp3" class="sm2_button">Walking</a></p>
+
+ <p>Armstrong Beat <a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3" class="sm2_button">Armstrong Beat</a></p>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 project page">SoundManager 2 project home</a></p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/css/mp3-player-button.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/css/mp3-player-button.css new file mode 100755 index 0000000..e5e1ce6 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/css/mp3-player-button.css @@ -0,0 +1,114 @@ +/* + + SoundManager 2: Basic MP3 player CSS + ------------------------------------ + + Clicks on links to MP3s are intercepted via JS, calls are + made to SoundManager to load/play sounds. CSS classes are + appended to the link, which are used to highlight the + current play state and so on. + + Class names are applied in addition to "sm2_button" base. + + Default: + + sm2_button + + Additional states: + + sm2_playing + sm2_paused + + eg. + + <!-- default --> + <a href="some.mp3" class="sm2_button">some.mp3</a> + + <!-- playing --> + <a href="some.mp3" class="sm2_button sm2_playing">some.mp3</a> + + + Note you don't require ul.graphic / ul.flat etc. for your use + if only using one style on a page. You can just use .sm2_button{} + and so on, but isolate the CSS you want. + + Side note: Would do multiple class definitions eg. + + a.sm2_default.sm2_playing{} + + .. except IE 6 has a parsing bug which may break behaviour, + applying sm2_playing {} even when the class is set to sm2_default. + + + If you want to make your own UI from scratch, here is the base: + + Default + hover state, "click to play": + + a.sm2_button {} + a.sm2_button:hover {} + + Playing + hover state, "click to pause": + + a.sm2_playing {} + a.sm2_playing:hover {} + + Paused + hover state, "click to resume": + + a.sm2_paused {} + a.sm2_paused:hover {} + +*/ + +a.sm2_button { + position:relative; + display:inline-block; /* If you worry about old browser bugs, Firefox 2 might not like this and may need -moz-inline-box instead. :D */ + width:18px; + height:18px; + text-indent:-9999px; /* don't show link text */ + overflow:hidden; /* don't draw inner link text */ + vertical-align:middle; + /* and, a bit of round-ness for the cool browsers. */ + -moz-border-radius:6px; + -webkit-border-radius:6px; + -o-border-radius:6px; + border-radius:6px; + margin-top:-1px; /* vertical align tweak */ + /* safari 3.1+ fun (/W3 working draft extension, TBD.) */ + -webkit-transition-property: hover; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out 0s; /* firefox 4 (couldn't sort out -moz-transform vs. MozTransform, so, "all" for now) */ + -o-transition-property: background-color; /* opera 10.5 */ + -o-transition-duration: 0.15s; +} + +a.sm2_button:focus { + outline:none; /* maybe evil, but don't show the slight border outline on focus. */ +} + +a.sm2_button, +a.sm2_button.sm2_paused:hover { + background-color:#3399cc; + background-image:url(../image/arrow-right-white.png); + /* where possible, use data: and skip the HTTP request. Fancy-pants. Would use short-hand background: for above, but IE 8 doesn't override background-image. */ + background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAYAAABmBXS+AAAAbklEQVQY02NgQAL//v1jZMAF/v//vwuIs9HEUBUBTbj4HwIeA3EGVsVAxtn/qOAVUGM8uknIiv4hsV8A5ZKxKfoLVvnvHwifAzLtMKwDSQLBVSBti27dJajkcSD2RJODO3wtkOOMz/tMSJJYAxMA5dmsL0IfubQAAAAASUVORK5CYII=); + *background-image:url(../image/arrow-right-white.gif); /* IE 6+7 don't do DATA: URIs */ + background-repeat:no-repeat; + background-position:5px 50%; +} + +a.sm2_button:hover, +a.sm2_button.sm2_playing, +a.sm2_button.sm2_playing:hover { + background-color:#cc3333; +} + +a.sm2_button.sm2_playing, +a.sm2_button.sm2_playing:hover { + -moz-transform:rotate(90deg); + -webkit-transform:rotate(90deg); +} + +a.sm2_button.sm2_paused, +a.sm2_button.sm2_paused:hover { + background-color:#666; +}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.gif Binary files differnew file mode 100755 index 0000000..3b4900e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.png Binary files differnew file mode 100755 index 0000000..fc55124 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-black.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.gif Binary files differnew file mode 100755 index 0000000..9e760e1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.png Binary files differnew file mode 100755 index 0000000..4189094 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/image/arrow-right-white.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/index.html new file mode 100755 index 0000000..6cc1ff5 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/index.html @@ -0,0 +1,188 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Basic MP3 Play Button</title> +<meta name="robots" content="noindex" />
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:2.5em arial,tahoma,verdana;
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+ margin-top:0.5em;
+}
+
+h2, h3 {
+ color:#333;
+}
+
+h2 {
+ font-size:2em;
+}
+
+h3 {
+ font-size:1.5em;
+}
+
+h1 a,
+h1 a:hover {
+ color:#000;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+ul li {
+ margin-bottom:0.5em;
+}
+
+ul.notes {
+ margin-left:0px;
+ padding-left:1.5em;
+}
+
+.note {
+ margin-top:0px;
+ font-style:italic;
+ color:#666;
+}
+
+pre {
+ font-weight:bold;
+ font-size:1.2em;
+ _font-size:1em;
+}
+
+pre code {
+ color:#228822;
+}
+
+#left {
+ max-width:56em;
+}
+
+</style>
+<link rel="stylesheet" type="text/css" href="css/mp3-player-button.css" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/mp3-player-button.js"></script>
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play MP3s inline with javascript using SoundManager 2">SoundManager 2</a> / Inline MP3 Player Button</h1>
+
+ <h2 style="display:inline">Basic MP3 Play Button Examples</h2> (also see <a title="MP3 Play Button, Basic Example demo" href="basic.html">basic demo</a>.)
+
+ <hr />
+
+ <div id="sm2-container">
+ <!-- flash movie ends up here -->
+ </div>
+
+ <h3>Inline text, with "play" button</h3>
+
+ <p>Example code (link with a <b>sm2_button</b> CSS class):</p>
+<pre><p> Spare change <code><a href="/path/to/coins.mp3" title="Play &quot;coins&quot;" class="sm2_button">coins.mp3</a></code> </p></pre>
+ <p>Renders as:</p>
+<div>
+ <p>Spare change <a href="../../demo/_mp3/coins.mp3" class="sm2_button" title="Play "coins"">coins.mp3</a></p>
+ <p class="note">Note that the text inside the link is hidden and replaced with an image, but should be descriptive - or at least should say something generic, like "play".</p>
+</div>
+ <h3>Basic MP3 play button, no text</h3>
+
+ <p>Code:</p>
+
+ <pre><code><a href="../jsAMP-preview/audio/office_lobby.mp3" title="Play &quot;Office Lobby&quot;" class="sm2_button">Office Lobby</a></code></pre>
+
+ <p>Renders as:</p>
+ <p>
+ <a href="../jsAMP-preview/audio/office_lobby.mp3" title="Play "Office Lobby"" class="sm2_button">Office Lobby</a>
+ </p>
+ <h2>How It Works</h2>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 Javascript Sound API">SoundManager 2</a> intercepts clicks to MP3 links and plays them inline. The script assigns additional CSS classes to the links to indicate their state (playing/paused, etc.)</p>
+
+ <h3>Static Examples</h3>
+
+ <p>CSS classes are dynamically applied as follows:</p>
+
+ <ul>
+ <li><a href="#" class="sm2_button" title=""Click to play" state">Default: class="sm2_button"</a> Default: class="sm2_button"</li>
+ <li><a href="#" class="sm2_button sm2_playing" title=""Click to pause" state">Playing: class="sm2_button sm2_playing"</a> Playing: class="sm2_button sm2_playing"</li>
+ <li><a href="#" class="sm2_button sm2_paused" title=""Click to resume" state">Paused: class="sm2_button sm2_paused"</a> Paused: class="sm2_button sm2_paused"</li>
+ </ul>
+
+ <h3>Basic CSS</h3>
+
+ <p>If you want to make your own UI from scratch, here is the base:</p>
+
+<pre>
+ Default + hover state, "click to play":
+<code>
+ a.sm2_button {}
+ a.sm2_button:hover {}
+</code>
+ Playing + hover state, "click to pause":
+<code>
+ a.sm2_button.sm2_playing {}
+ a.sm2_button.sm2_playing:hover {}
+</code>
+ Paused + hover state, "click to resume":
+<code>
+ a.sm2_button.sm2_paused {}
+ a.sm2_button.sm2_paused:hover {}
+</code></pre>
+
+ <h3>Other Options</h3>
+
+ <p>By default, one sound will be played at a time; you can easily change a "config" object value to turn on playlist-like behaviour (i.e., play the next MP3 when the current one finishes.)</p>
+
+<pre>
+<code>
+// (within mp3-player-button.js)
+this.config = {
+ playNext: false // stop after one sound, or play through list until end
+}
+</code></pre>
+
+ <h3>I'd like to use this.</h3>
+ <p>See this <a href="basic.html" title="basic template: inline mp3 player">basic demo</a> for reference.</p>
+
+ <p>
+ <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
+ </p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/script/mp3-player-button.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/script/mp3-player-button.js new file mode 100755 index 0000000..96e0346 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mp3-player-button/script/mp3-player-button.js @@ -0,0 +1,247 @@ +/*
+
+ SoundManager 2 Demo: Play MP3 links via button
+ ----------------------------------------------
+
+ http://schillmania.com/projects/soundmanager2/
+
+ A simple demo making MP3s playable "inline"
+ and easily styled/customizable via CSS.
+
+ A variation of the "play mp3 links" demo.
+
+ Requires SoundManager 2 Javascript API.
+
+*/
+
+function BasicMP3Player() {
+ var self = this;
+ var pl = this;
+ var sm = soundManager; // soundManager instance
+ this.excludeClass = 'button-exclude'; // CSS class for ignoring MP3 links
+ this.links = [];
+ this.sounds = [];
+ this.soundsByURL = [];
+ this.indexByURL = [];
+ this.lastSound = null;
+ this.soundCount = 0;
+ var isIE = (navigator.userAgent.match(/msie/i));
+
+ this.config = {
+ playNext: false, // stop after one sound, or play through list until end
+ autoPlay: false // start playing the first sound right away
+ }
+
+ this.css = {
+ // CSS class names appended to link during various states
+ sDefault: 'sm2_button', // default state
+ sLoading: 'sm2_loading',
+ sPlaying: 'sm2_playing',
+ sPaused: 'sm2_paused'
+ }
+
+ this.includeClass = this.css.sDefault;
+
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.classContains = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?o.className.match(new RegExp('(\\s|^)'+cStr+'(\\s|$)')):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr || self.classContains(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr || !self.classContains(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getSoundByURL = function(sURL) {
+ return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null);
+ }
+
+ this.isChildOfNode = function(o,sNodeName) {
+ if (!o || !o.parentNode) {
+ return false;
+ }
+ sNodeName = sNodeName.toLowerCase();
+ do {
+ o = o.parentNode;
+ } while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName);
+ return (o.nodeName.toLowerCase() == sNodeName?o:null);
+ }
+
+ this.events = {
+
+ // handlers for sound events as they're started/stopped/played
+
+ play: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ stop: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = '';
+ },
+
+ pause: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPaused;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ resume: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ finish: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = '';
+ if (pl.config.playNext) {
+ var nextLink = (pl.indexByURL[this._data.oLink.href]+1);
+ if (nextLink<pl.links.length) {
+ pl.handleClick({'target':pl.links[nextLink]});
+ }
+ }
+ }
+
+ }
+
+ this.stopEvent = function(e) {
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.getTheDamnLink = (isIE)?function(e) {
+ // I really didn't want to have to do this.
+ return (e && e.target?e.target:window.event.srcElement);
+ }:function(e) {
+ return e.target;
+ }
+
+ this.handleClick = function(e) {
+ // a sound link was clicked
+ if (typeof e.button != 'undefined' && e.button>1) {
+ // ignore right-click
+ return true;
+ }
+ var o = self.getTheDamnLink(e);
+ if (o.nodeName.toLowerCase() != 'a') {
+ o = self.isChildOfNode(o,'a');
+ if (!o) return true;
+ }
+ var sURL = o.getAttribute('href');
+ if (!o.href || !soundManager.canPlayLink(o) || self.classContains(o,self.excludeClass)) {
+ return true; // pass-thru for non-MP3/non-links
+ }
+ if (!self.classContains(o,self.includeClass)) {
+ return true;
+ }
+ sm._writeDebug('handleClick()');
+ var soundURL = (o.href);
+ var thisSound = self.getSoundByURL(soundURL);
+ if (thisSound) {
+ // already exists
+ if (thisSound == self.lastSound) {
+ // and was playing (or paused)
+ thisSound.togglePause();
+ } else {
+ // different sound
+ thisSound.togglePause(); // start playing current
+ sm._writeDebug('sound different than last sound: '+self.lastSound.sID);
+ if (self.lastSound) self.stopSound(self.lastSound);
+ }
+ } else {
+ // create sound
+ thisSound = sm.createSound({
+ id:'basicMP3Sound'+(self.soundCount++),
+ url:soundURL,
+ onplay:self.events.play,
+ onstop:self.events.stop,
+ onpause:self.events.pause,
+ onresume:self.events.resume,
+ onfinish:self.events.finish
+ });
+ // tack on some custom data
+ thisSound._data = {
+ oLink: o, // DOM node for reference within SM2 object event handlers
+ className: self.css.sPlaying
+ };
+ self.soundsByURL[soundURL] = thisSound;
+ self.sounds.push(thisSound);
+ if (self.lastSound) {
+ // stop last sound
+ self.stopSound(self.lastSound);
+ }
+ thisSound.play();
+ }
+
+ self.lastSound = thisSound; // reference for next call
+
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.stopSound = function(oSound) {
+ soundManager.stop(oSound.sID);
+ soundManager.unload(oSound.sID);
+ }
+
+ this.init = function() {
+ sm._writeDebug('basicMP3Player.init()');
+ var oLinks = document.getElementsByTagName('a');
+ // grab all links, look for .mp3
+ var foundItems = 0;
+ for (var i=0, j=oLinks.length; i<j; i++) {
+ if (self.classContains(oLinks[i],self.css.sDefault) && !self.classContains(oLinks[i],self.excludeClass)) {
+ // self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration - good if you're lazy and want ALL MP3/playable links to do this
+ self.links[foundItems] = (oLinks[i]);
+ self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
+ foundItems++;
+ }
+ }
+ if (foundItems>0) {
+ self.addEventHandler(document,'click',self.handleClick);
+ if (self.config.autoPlay) {
+ self.handleClick({target:self.links[0],preventDefault:function(){}});
+ }
+ }
+ sm._writeDebug('basicMP3Player.init(): Found '+foundItems+' relevant items.');
+ }
+
+ this.init();
+
+}
+
+var basicMP3Player = null;
+
+soundManager.useFlashBlock = true;
+soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
+
+soundManager.onready(function() {
+ if (soundManager.supported()) {
+ // soundManager.createSound() etc. may now be called
+ basicMP3Player = new BasicMP3Player();
+ }
+});
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/acoustic-drumkit.xml b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/acoustic-drumkit.xml new file mode 100755 index 0000000..3d6606a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/acoustic-drumkit.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Acoustic drumkit example sounds
+ Source credit: http://www.akaipro.com/arc_kotw.html
+-->
+
+<!-- SoundManager Flash configuration -->
+<!-- Sound IDs are referenced from JS -->
+
+<items baseHref="audio/"> <!-- baseHref is optional, but note the trailing slash if used. -->
+
+ <sound id="s0" href="AMB_BD_1.mp3" />
+ <sound id="s1" href="AMB_FTM2.mp3" />
+ <sound id="s2" href="AMB_HHCL.mp3" />
+ <sound id="s3" href="AMB_HHOP.mp3" />
+ <sound id="s4" href="AMB_HHPD.mp3" />
+ <sound id="s5" href="AMB_HTM.mp3" />
+ <sound id="s6" href="AMB_LTM2.mp3" />
+ <sound id="s7" href="AMB_MTM.mp3" />
+ <sound id="s8" href="AMB_RIM1.mp3" />
+ <sound id="s9" href="AMB_SN13.mp3" />
+ <sound id="s10" href="AMB_SN_5.mp3" />
+ <sound id="s11" href="CHINA_1.mp3" />
+ <sound id="s12" href="CRASH_1.mp3" />
+ <sound id="s13" href="CRASH_5.mp3" />
+ <sound id="s14" href="CRASH_6.mp3" />
+ <sound id="s15" href="RIDE_1.mp3" />
+<!--
+ <sound id="s16" href="RIDE_3.mp3" />
+ <sound id="s17" href="SPLASH_1.mp3" />
+-->
+</items>
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_BD_1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_BD_1.mp3 Binary files differnew file mode 100755 index 0000000..ac40028 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_BD_1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_FTM2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_FTM2.mp3 Binary files differnew file mode 100755 index 0000000..a181e07 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_FTM2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHCL.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHCL.mp3 Binary files differnew file mode 100755 index 0000000..5833134 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHCL.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHOP.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHOP.mp3 Binary files differnew file mode 100755 index 0000000..679376c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHOP.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHPD.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHPD.mp3 Binary files differnew file mode 100755 index 0000000..79bf78c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HHPD.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HTM.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HTM.mp3 Binary files differnew file mode 100755 index 0000000..990d8f1 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_HTM.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_LTM2.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_LTM2.mp3 Binary files differnew file mode 100755 index 0000000..d9c371c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_LTM2.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_MTM.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_MTM.mp3 Binary files differnew file mode 100755 index 0000000..cadd93e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_MTM.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_RIM1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_RIM1.mp3 Binary files differnew file mode 100755 index 0000000..354c35a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_RIM1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN13.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN13.mp3 Binary files differnew file mode 100755 index 0000000..319348c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN13.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN_5.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN_5.mp3 Binary files differnew file mode 100755 index 0000000..baf7a87 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/AMB_SN_5.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CHINA_1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CHINA_1.mp3 Binary files differnew file mode 100755 index 0000000..18a5142 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CHINA_1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_1.mp3 Binary files differnew file mode 100755 index 0000000..db77301 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_5.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_5.mp3 Binary files differnew file mode 100755 index 0000000..4d999f2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_5.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_6.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_6.mp3 Binary files differnew file mode 100755 index 0000000..d20ec27 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/CRASH_6.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_1.mp3 Binary files differnew file mode 100755 index 0000000..1e5601c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_3.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_3.mp3 Binary files differnew file mode 100755 index 0000000..701e150 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/RIDE_3.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/SPLASH_1.mp3 b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/SPLASH_1.mp3 Binary files differnew file mode 100755 index 0000000..77cb0de --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/audio/SPLASH_1.mp3 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/css/mpc.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/css/mpc.css new file mode 100755 index 0000000..dd10668 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/css/mpc.css @@ -0,0 +1,164 @@ +/* Demo/example CSS - not needed for general use */
+
+body {
+ background:#000;
+ font:normal 75% "helvetica neue",helvetica,verdana,arial,tahoma,"times new roman","sans serif";
+ color:#fff;
+ margin:0px;
+ padding:0px;
+}
+
+#background {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:100%;
+ height:100%;
+ background:transparent url(http://farm1.static.flickr.com/45/191496680_97cdc5351b_b.jpg) no-repeat 50% 50%;
+}
+
+#site {
+ position:relative;
+ z-index:2;
+ background:rgba(0,0,0,0.5);
+ padding:1em;
+}
+
+#site h1 {
+ margin-top:0px;
+}
+
+#site p {
+ margin:0.5em 0px 0.5em 0px;
+}
+
+#site p:last-child {
+ margin:0px;
+}
+
+.clear {
+ float:none;
+ clear:both;
+ font-size:1px;
+ line-height:1px;
+ height:1px;
+ overflow:hidden;
+}
+
+#mpc {
+ position:absolute;
+ left:50%;
+ top:50%;
+ margin-left:-19em;
+ margin-top:-19em;
+ width:38em;
+ _width:37.3em;
+ border:3px solid #666;
+ border:3px solid rgba(255,255,255,0.25);
+ -moz-border-radius:12px;
+ -webkit-border-radius:12px;
+ border-radius:12px;
+ z-index:2;
+}
+
+#mpc #wrapper {
+ position:relative;
+ background:#333;
+ background:rgba(0,0,0,0.5);
+ padding:0.5em;
+ -moz-border-radius:12px;
+ -webkit-border-radius:12px;
+ border-radius:12px;
+}
+
+#mpc ul {
+ margin:0px;
+ padding:0px;
+ margin-left:2px;
+ *margin-left:1em;
+ _margin-left:2px;
+ padding:2px 0px 2px 0px;
+}
+
+#mpc ul li {
+ position:relative;
+ float:left;
+ display:inline;
+ width:7em;
+ height:7em;
+ margin:0.5em;
+ background:#999;
+ border:1px solid rgba(0,0,0,0.75);
+ -moz-border-radius:2px;
+ -webkit-border-radius:2px;
+ border-radius:2px;
+ font:normal 1em/1em "helvetica",verdana,arial,system;
+ padding:0.5em;
+ cursor:pointer;
+ cursor:hand;
+ color:#eee;
+ text-transform:uppercase;
+ font-weight:bold;
+}
+
+#mpc ul li span {
+ text-transform:none;
+ font-weight:normal;
+ color:#ccc;
+}
+
+#mpc ul li.active {
+ background:#666;
+}
+
+#mpc ul li div {
+ /* progress indicator */
+ position:absolute;
+ left:0px;
+ bottom:1em;
+ font-size:1em;
+ line-height:1em;
+ height:1em;
+ margin:0px 0px 0px 1em;
+ width:6em;
+ background:#888 url(../image/progress.png) no-repeat -256px 0px;
+ background-repeat:no-repeat;
+ border:1px solid #666;
+ visibility:hidden;
+}
+
+#mpc ul li.active div,
+#mpc ul li.loading div {
+ visibility:visible;
+}
+
+#soundmanager-debug {
+ position:absolute;
+ right:20px;
+ bottom:20px;
+ height:12em;
+ width:50em;
+ overflow:auto;
+ margin-left:1em;
+}
+
+#soundmanager-debug div {
+ font-size:11px;
+ font-family: "lucida console",system,terminal,verdana,arial; /* IE doesn't seem to obey short-hand font family here? */
+ padding:0px 1em 0.5em 0px;
+}
+
+#mpc-debug,
+.note {
+ color:#999;
+}
+
+#mpc-debug a,
+.note a {
+ color:#6699cc;
+ text-decoration:none;
+}
+
+#isHTML5 {
+ display:none;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/image/progress.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/image/progress.png Binary files differnew file mode 100755 index 0000000..54f9631 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/image/progress.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/index.html new file mode 100755 index 0000000..7dc68f7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/index.html @@ -0,0 +1,72 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: A Javascript Sound API - MPC Demo</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="An example drum machine (MPC) demo using the SoundManager 2 JavaScript Audio API" />
+<meta name="keywords" content="javascript mpc, javascript drum machine, javascript sound, javascript audio, DHTML sound, work by Scott Schiller, schillmania, javascript to flash communication" />
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
+<link rel="stylesheet" href="css/mpc.css" media="screen" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/mpc.js"></script>
+</head>
+<body>
+
+<div id="background"></div>
+
+<div id="site">
+
+ <h1 style="margin-bottom:0px"><a href="../" style="color:#99ccff;text-decoration:none">SoundManager 2</a>: Javascript Drum Machine Demo<span id="isHTML5"></span></h1>
+ <h2 style="margin-top:0px;color:#999">Trigger the pads to play different sounds.</h2>
+ <p id="mpc-debug" class="note">View <a href="#debug=1" onclick="window.location.hash='debug=1';window.location.reload()">with debug output</a></p>
+ <p class="note">Photo: <a href="http://www.flickr.com/photos/schill/191496680/">MPC 2500</a> by .schill on Flickr</a></p>
+ <p class="note"><span style="display:none">(If supported): </span><span id="isHTML5">Your browser is cool and is using 100% HTML5 Audio. Look ma, no Flash!</span></p>
+</div>
+
+<div id="mpc">
+
+ <div id="wrapper">
+
+ <ul>
+ <li id="btn-s0" onmousedown="soundManager.play('s0')">1<div></div></li>
+ <li id="btn-s1" onmousedown="soundManager.play('s1')">2<div></div></li>
+ <li id="btn-s2" onmousedown="soundManager.play('s2')">3<div></div></li>
+ <li id="btn-s3" onmousedown="soundManager.play('s3')">4<div></div></li>
+ </ul>
+
+ <ul>
+ <li id="btn-s4" onmousedown="soundManager.play('s4')">q<div></div></li>
+ <li id="btn-s5" onmousedown="soundManager.play('s5')">w<div></div></li>
+ <li id="btn-s6" onmousedown="soundManager.play('s6')">e<div></div></li>
+ <li id="btn-s7" onmousedown="soundManager.play('s7')">r<div></div></li>
+ </ul>
+
+ <ul>
+ <li id="btn-s8" onmousedown="soundManager.play('s8')">a<div></div></li>
+ <li id="btn-s9" onmousedown="soundManager.play('s9')">s<div></div></li>
+ <li id="btn-s10" onmousedown="soundManager.play('s10')">d<div></div></li>
+ <li id="btn-s11" onmousedown="soundManager.play('s11')">f<div></div></li>
+ </ul>
+
+ <ul>
+ <li id="btn-s12" onmousedown="soundManager.play('s12')">z<div></div></li>
+ <li id="btn-s13" onmousedown="soundManager.play('s13')">x<div></div></li>
+ <li id="btn-s14" onmousedown="soundManager.play('s14')">c<div></div></li>
+ <li id="btn-s15" onmousedown="soundManager.play('s15')">v<div></div></li>
+ </ul>
+
+ <div class="clear"></div>
+
+ </div>
+
+</div>
+
+ <script type="text/javascript">if (window.location.href.toString().match(/debug/i)) { document.getElementById('mpc-debug').style.display = 'none'; }</script>
+
+</div>
+
+</body>
+</html> diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/script/mpc.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/script/mpc.js new file mode 100755 index 0000000..3f91667 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/mpc/script/mpc.js @@ -0,0 +1,144 @@ +// demo-specific code - not needed for general use
+
+// refer to bottom for initialisation and soundManager tie-ins, however!
+
+var MPC = function() {
+ var self = this;
+ this.idPrefix = 'btn-'; // HTML ID prefix
+ this.statusWidth = 6;
+ this.progressWidth = 256;
+ this.keys = {'1':0,'2':1,'3':2,'4':3,'q':4,'w':5,'e':6,'r':7,'a':8,'s':9,'d':10,'f':11,'z':12,'x':13,'c':14,'v':15}
+
+ // scope within these event handler methods: "this" = SMSound() object instance (see SMSound() in soundmanager.js for reference)
+
+ this.showProgress = function() {
+ // sound is loading, update bytes received using this.bytesLoaded / this.bytesTotal
+ if (self._getButton(this.sID).className != 'loading') self._getButton(this.sID).className = 'loading'; // a bit inefficient here..
+ self._showStatus(this.sID,this.bytesLoaded,this.bytesTotal);
+ }
+
+ this.onid3 = function() {
+ soundManager._writeDebug('mpc.onid3()');
+ var oName = null;
+ for (var oName in this.id3) {
+ soundManager._writeDebug(oName+': '+this.id3[oName]) // write out name/value ID3 pairs (eg. "artist: Beck")
+ }
+ }
+
+ this.onload = function() {
+ var sID = this.sID;
+ self._getButton(this.sID).className = '';
+ self._getButton(this.sID).title = ('Sound ID: '+this.sID+' ('+this.url+')');
+ }
+
+ this.onfinish = function() {
+ self._getButton(this.sID).className = '';
+ self._reset(this.sID);
+ }
+
+ this.onplay = function() {
+ self._getButton(this.sID).className = 'active';
+ }
+
+ this.whileplaying = function() {
+ self._showStatus(this.sID,this.position,this.duration);
+ }
+
+ this._keyHandler = function(e) {
+ var oEvt = e?e:event;
+ var sChar = String.fromCharCode(oEvt.keyCode).toLowerCase();
+ if (typeof self.keys[sChar] != 'undefined') soundManager.play('s'+self.keys[sChar]);
+ }
+
+ this._showStatus = function(sID,n1,n2) {
+ var o = self._getButton(sID).getElementsByTagName('div')[0];
+ var offX = (n2>0?(-self.progressWidth+parseInt((n1/n2)*o.offsetWidth)):-self.progressWidth);
+ o.style.backgroundPosition = offX+'px 0px';
+ }
+
+ this._getButton = function(sID) {
+ return document.getElementById(self.idPrefix+sID);
+ }
+
+ this._reset = function(sID) {
+ var id = sID;
+ self._showStatus(sID,1,1);
+ setTimeout(function(){self._showStatus(sID,0,0);},200);
+ }
+
+ this.init = function() {
+ document.onkeydown = self._keyHandler;
+ }
+
+}
+
+var mpc = new MPC();
+
+soundManager.useHTML5Audio = true; // why not.
+soundManager.flashVersion = (window.location.toString().match(/#flash8/i)?8:9);
+if (soundManager.flashVersion != 8) {
+ soundManager.useHighPerformance = true;
+ soundManager.useFastPolling = true;
+}
+soundManager.url = '../../swf/'; // path to load SWF from (overriding default)
+soundManager.bgcolor = '#333333';
+soundManager.wmode = 'transparent';
+soundManager.debugMode = false;
+soundManager.consoleOnly = false;
+soundManager.useFlashBlock = true;
+
+soundManager.onready(function() {
+
+ // This is the "onload" equivalent which is called when SoundManager has been initialised (sounds can be created, etc.)
+
+ mpc.init();
+
+ // set up some default options / event handlers - so all sounds created are given these handlers
+
+ soundManager.defaultOptions.autoLoad = true;
+ soundManager.defaultOptions.whileloading = mpc.showProgress;
+ soundManager.defaultOptions.onid3 = mpc.onid3;
+ soundManager.defaultOptions.onload = mpc.onload;
+ soundManager.defaultOptions.onplay = mpc.onplay;
+ soundManager.defaultOptions.whileplaying = mpc.whileplaying;
+ soundManager.defaultOptions.onfinish = mpc.onfinish;
+
+ // get drumkit sounds from XML file (as opposed to using createSound)
+
+ if (!soundManager.hasHTML5) {
+ soundManager.loadFromXML('acoustic-drumkit.xml');
+ } else {
+ if (!soundManager.html5.needsFlash) {
+ document.getElementById('isHTML5').style.display = 'inline';
+ }
+ var soundURLs = 'AMB_BD_1,AMB_FTM2,AMB_HHCL,AMB_HHOP,AMB_HHPD,AMB_HTM,AMB_LTM2,AMB_MTM,AMB_RIM1,AMB_SN13,AMB_SN_5,CHINA_1,CRASH_1,CRASH_5,CRASH_6,RIDE_1'.split(',');
+ for (var i=0; i<soundURLs.length; i++) {
+ soundManager.createSound('s'+i, 'audio/'+soundURLs[i]+'.mp3');
+ }
+ }
+
+ /*
+
+ You can also create sounds using Javascript methods, instead of XML.
+ Options can also be set on a per-file basis, with specific option overrides.
+ (Options not specified here will inherit defaults as defined in soundManager.defaultOptions.)
+
+ eg.
+
+ soundManager.createSound({
+ id: 'mySound',
+ url: '/path/to/some.mp3',
+ stream: true,
+ autoPlay: true,
+ multiShot: false,
+ whileloading: function() { alert('sound '+this.sID+': '+this.bytesLoaded+' of '+this.bytesTotal+' bytes loaded.'); } // event handler: "this" is scoped to SMSound() object instance for easy access to methods/properties
+ });
+
+ - OR -
+
+ If you just want a sound with all default options, you can also specify just the required id and URL as string parameters:
+
+ soundManager.createSound('mySound','/path/to/some.mp3');
+
+ */
+});
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html new file mode 100755 index 0000000..851be17 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 links on a page, "page as playlist" style</title>
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);z-index:99;
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+</style>
+<link rel="stylesheet" type="text/css" href="css/page-player.css" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/page-player.js"></script>
+<script type="text/javascript">
+
+soundManager.url = '../../swf/';
+
+// demo only..
+function setTheme(sTheme) {
+ var o = document.getElementsByTagName('ul')[0];
+ o.className = 'playlist'+(sTheme?' '+sTheme:'');
+ return false;
+}
+</script>
+</head>
+
+<body>
+
+<div>
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play a page of mp3s with javascript via SoundManager 2">SoundManager 2</a> / page as a playlist, basic template (flash 8)</h1>
+
+ <div id="sm2-container">
+ <!-- SM2 flash movie goes here -->
+ </div>
+
+ <ul class="playlist">
+
+ <li><a href="../jsAMP-preview/audio/rain.mp3">Rain</a></li>
+ <li><a href="../jsAMP-preview/audio/going_outside.mp3">Going Outside</a></li>
+ <li><a href="../jsAMP-preview/audio/office_lobby.mp3">Office Lobby</a></li>
+ <li><a href="../jsAMP-preview/audio/walking.mp3">Walking</a></li>
+ <li><a href="http://freshly-ground.com/data/audio/mpc/20060812%20-%20Groove.mp3" title="Dr. John Groove">Schill - Dr. John Groove</a></li>
+ <!-- files from the web (note that ID3 and waveformData information will *not* load from remote domains without permission, due to Flash security restrictions) -->
+ <li><a href="http://www.freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl (featureblend.com)</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/A%20Trip%20to%20the%20Basement%20Garage.mp3">A Trip To The Basement Garage</a></li>
+
+ </ul>
+
+ <div id="control-template">
+ <!-- control markup inserted dynamically after each link -->
+ <div class="controls">
+ <div class="statusbar">
+ <div class="loading"></div>
+ <div class="position"></div>
+ </div>
+ </div>
+ <div class="timing">
+ <div id="sm2_timing" class="timing-data">
+ <span class="sm2_position">%s1</span> / <span class="sm2_total">%s2</span></div>
+ </div>
+ <div class="peak">
+ <div class="peak-box"><span class="l"></span><span class="r"></span>
+ </div>
+ </div>
+ </div>
+
+ <div id="spectrum-container" class="spectrum-container">
+ <div class="spectrum-box">
+ <div class="spectrum"></div>
+ </div>
+ </div>
+
+ <p>For alternate themes, add the class to the playlist UL - eg. <a href="#" onclick="return setTheme('dark')"><ul class="playlist dark"></a> or <a href="#" onclick="return setTheme('bubblegum')"><ul class="playlist bubblegum"></a>; the base default is <a href="#" onclick="return setTheme()"><ul class="playlist"></a>.</p>
+
+ <p>A reminder that if loading from the local filesystem, Flash will deny access to remote (network/internet) URLs by default unless whitelisted via the <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">Flash Player Global Security Settings Page</a>. Some URLs in this example are remote to demonstrate this.</p>
+
+ <p>Note that by default, the Flash 8 version is used and therefore Flash 9-only features such as the VU meter, waveform etc. are not available. Refer to the main "page player" demo for configuration examples, or view the source of page-player.js for the configuration object (similar to that used in SoundManager 2 itself.)</p>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 sound player API">SoundManager 2 project</a></p>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css new file mode 100755 index 0000000..f11964e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css @@ -0,0 +1,124 @@ +/*
+ -----------------------------------------------------------------
+ In-page demo CSS for code, documentation etc.
+ See page-player.css for actual playlist-relevant stuff.
+ -----------------------------------------------------------------
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);z-index:99;
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:lighter 3em "Helvetica Neue Light","Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ margin-bottom:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h1, h2, h3 {
+ float:left;
+ clear:both;
+ border-bottom:1px solid #999;
+ padding-bottom:1px;
+ margin-bottom:0.25em;
+}
+
+h1 {
+ margin-top:0px;
+ margin-bottom:0px;
+ background-color:#666;
+ color:#ccc;
+ margin-left:-5px;
+ padding-left:5px;
+ padding-right:5px;
+}
+
+h1,
+h1 a {
+ color:#fff;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+h2 {
+ font-size:2em;
+ margin-top:1em;
+ background-color:#aaa;
+ color:#fff;
+ padding:5px;
+ margin-left:-5px;
+ min-width:23em;
+}
+
+h3 {
+ font-size:1.65em;
+ margin-top:0.5em;
+ margin-bottom:0.25em;
+ color:#333;
+ min-width:28em;
+}
+
+h3 a {
+ font-size:small;
+}
+
+h4 {
+ color:#444;
+}
+
+ul.notes {
+ margin-left:0px;
+ padding-left:1.5em;
+}
+
+.note {
+ margin-top:0px;
+ font-style:italic;
+ color:#999;
+}
+
+pre {
+ font-size:1.2em;
+ _font-size:1em;
+}
+
+code {
+ font-family:"lucida console",monaco,courier,terminal,system;
+ font-size:1em;
+ color:#003366;
+}
+
+code span {
+ color:#666;
+}
+
+ul,
+p,
+pre {
+ clear:left;
+ max-width:46em;
+}
+
+ul.tight li {
+ max-width:44.5em;
+}
+
+ul.playlist {
+ /* undo the above nonsense */
+ max-width:none;
+}
+
+ul.tight {
+ padding-left:1.5em;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css new file mode 100755 index 0000000..123457f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css @@ -0,0 +1,168 @@ +/*
+ ------------------------------------------
+ -- annotations (sub-tracks, notes etc.) --
+ ------------------------------------------
+*/
+
+ul.playlist li a.sm2_link .metadata {
+ display:none; /* hide by default */
+}
+
+ul.playlist li.sm2_paused a.sm2_link .metadata,
+ul.playlist li.sm2_playing a.sm2_link .metadata {
+ display:inline;
+}
+
+ul.playlist li ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+ position:relative;
+ font-size:small;
+ display:none;
+}
+
+ul.playlist li ul li {
+ position:relative;
+ margin:0px;
+ padding:2px 3px;
+ border:1px solid transparent;
+ -moz-border-radius:6px;
+ -khtml-border-radius:6px;
+ border-radius:6px;
+ margin-right:1em;
+ font-family:helvetica,verdana,tahoma,arial,"sans serif";
+ font-size:x-small;
+ font-weight:lighter;
+ letter-spacing:0px;
+ background-color:transparent;
+ opacity:0.66;
+}
+
+ul.playlist li ul li:hover {
+ opacity:1;
+ background-color:#fff;
+ border-color:#ccc;
+ color:#666;
+}
+
+ul.playlist li.sm2_playing ul li,
+ul.playlist li.sm2_paused ul li {
+ color:#fff;
+}
+
+ul.playlist li.sm2_playing ul li:hover {
+ background-color:#fff;
+ color:#5588bb;
+ border-color:#336699;
+ opacity:0.9;
+}
+
+ul.playlist li.sm2_paused ul li:hover {
+ background-color:#888;
+}
+
+/* metadata */
+
+ul.playlist li .metadata .duration {
+ /* optional timing data */
+ display:none;
+}
+
+ul.playlist li .metadata ul li p {
+ margin:0px;
+ padding:0px;
+}
+
+ul.playlist li .metadata ul li span {
+ display:none;
+}
+
+ul.playlist li .controls .statusbar .annotation {
+ position:absolute;
+ background-color:transparent;
+ top:0px;
+ color:#666;
+ text-align:right;
+ margin-left:10px;
+ height:0.5em;
+}
+
+ul.playlist li .controls .statusbar .annotation:hover {
+ z-index:12; /* sit on top of note */
+}
+
+ul.playlist li .controls .statusbar .annotation span.bubble {
+ /* using · */
+ display:inline-block;
+ background-color:#fff;
+ border:1px solid #666;
+ border-radius:6px;
+ -moz-border-radius:6px;
+ -webkit-border-radius:6px;
+}
+
+ul.playlist li .controls .statusbar .annotation span {
+ display:block;
+ background:transparent url(../image/divot.png) no-repeat 50% 0px;
+ width:15px;
+ margin-left:-15px;
+ height:12px;
+ text-align:center;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt {
+ top:auto;
+ bottom:0px;
+}
+
+ul.playlist li .controls .statusbar .annotation span:hover {
+ cursor:none; /* Fx3 rules. */
+ margin-top:0.1em;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt span:hover {
+ margin-top:-0.1em;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt span {
+ background:transparent url(../image/divot-bottom.png) no-repeat 50% bottom;
+}
+
+ul.playlist li .note {
+ position:absolute;
+ display:none;
+ left:0px;
+ top:0px;
+ z-index:10;
+ font-size:x-small;
+ padding:2px 4px 2px 4px;
+ width:auto;
+ color:#666;
+ background-color:#fff;
+ border:1px solid #ccc;
+ border-radius:6px;
+ -moz-border-radius:6px;
+ -webkit-border-radius:6px;
+ font-style:normal;
+ font-weight:bold;
+ font-family:arial,tahoma,verdana,"sans serif";
+ letter-spacing:0px;
+ margin-top:1.1em;
+}
+
+ul.playlist li .note.alt {
+ margin-top:-1.32em;
+}
+
+ul.playlist li .note:hover {
+ display:block !important;
+}
+
+ul.playlist li .sm2_divider {
+ font-size:0.75em;
+}
+
+ul.playlist li .sm2_metadata {
+ font-size:0.65em;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css new file mode 100755 index 0000000..62a8146 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css @@ -0,0 +1,206 @@ +/*
+ ---------------------------------
+ -- alternate (optional) themes --
+ ---------------------------------
+*/
+
+ul.playlist.dark li.sm2_playing a {
+ color:#fff;
+}
+
+ul.playlist.dark li.sm2_playing .timing,
+ul.playlist.use-peak.dark li.sm2_playing .peak {
+ color:#999;
+}
+
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container {
+ background-color:#222;
+ border-color:#444;
+}
+
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container .spectrum {
+ background-color:#999;
+}
+
+ul.playlist.dark li.sm2_paused {
+ background-color:#333;
+}
+
+ul.playlist.dark li.sm2_paused a {
+ color:#999;
+}
+
+ul.playlist.dark li.sm2_playing,
+ul.playlist.dark li.sm2_playing:hover {
+ background-color:#333;
+}
+
+ul.playlist.dark li:hover .controls .statusbar {
+ background-color:#666;
+}
+
+ul.playlist.dark li .controls {
+ background-color:#333;
+}
+
+ul.playlist.dark li .controls .statusbar {
+ background-color:#666;
+ border-color:#444;
+}
+
+ul.playlist.dark li .controls .statusbar .position {
+ background-color:#111;
+ border-right:3px solid #111;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.dark li .controls .statusbar .loading {
+ background-color:#444;
+}
+
+ul.playlist.dark li .timing,
+ul.playlist.use-peak.dark li .peak {
+ background-color:#222;
+ border-color:#444;
+}
+
+ul.playlist.dark.use-peak li .peak .l,
+ul.playlist.dark.use-peak li .peak .r {
+ border-color:#444;
+ background-color:#999;
+}
+
+
+/* gold theme */
+
+ul.playlist.gold li.sm2_paused {
+ background-color:#996600;
+}
+
+ul.playlist.gold li.sm2_playing,
+ul.playlist.gold li.sm2_playing:hover {
+ background-color:#cc9900;
+}
+
+ul.playlist.gold li .controls {
+ background-color:transparent;
+}
+
+ul.playlist.gold li .controls .statusbar {
+ background-color:#fff;
+ border-color:#fff;
+}
+
+ul.playlist.gold li .controls .statusbar .position {
+ background-color:#996600;
+ border-right:3px solid #996600;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.gold li .controls .statusbar .loading {
+ background-color:#ffeedd;
+}
+
+ul.playlist.gold li .timing,
+ul.playlist.use-peak.gold li .peak {
+ background-color:#CC9900;
+ border-color:#ffcc33;
+}
+
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container {
+ background-color:#cc9900;
+ border-color:#ffcc33;
+}
+
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container .spectrum {
+ background-color:#fff;
+}
+
+ul.playlist.gold.use-peak li .peak .l,
+ul.playlist.gold.use-peak li .peak .r {
+ border-color:#fff;
+ background-color:#fff;
+}
+
+
+/* ZOMG PONIES!!!ONEONEONE */
+
+ul.playlist.bubblegum li a {
+ font-family:"comic sans ms",verdana,arial,tahoma,"sans serif"; /* heh */
+}
+
+ul.playlist.bubblegum li.sm2_paused,
+ul.playlist.bubblegum li.sm2_paused:hover {
+ background-color:#ffccee;
+}
+
+ul.playlist.bubblegum li.sm2_paused a,
+ul.playlist.bubblegum li.sm2_paused:hover a,
+ul.playlist.bubblegum li.sm2_paused .timing,
+ul.playlist.use-peak.bubblegum li.sm2_paused .peak {
+ color:#ff6699;
+}
+
+ul.playlist.bubblegum li:hover {
+ background-color:#ffddee;
+}
+
+ul.playlist.bubblegum li.sm2_playing,
+ul.playlist.bubblegum li.sm2_playing:hover {
+ background-color:#ff7799;
+}
+
+ul.playlist.bubblegum li .controls {
+ background-color:transparent;
+}
+
+ul.playlist.bubblegum li .controls .statusbar {
+ background-color:#fff;
+ border-color:#fff;
+}
+
+ul.playlist.bubblegum li .controls .statusbar .position {
+ background-color:#ffaacc;
+ border-right:3px solid #ffaacc;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.bubblegum li .controls .statusbar .loading {
+ background-color:#ffeedd;
+}
+
+ul.playlist.bubblegum li .timing,
+ul.playlist.use-peak.bubblegum li .peak {
+ background-color:#ffaacc;
+ border-color:#ffccee;
+}
+
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container {
+ background-color:#ffaacc;
+ border-color:#ffccee;
+}
+
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container .spectrum {
+ background-color:#fff;
+}
+
+ul.playlist.bubblegum.use-peak li .peak .l,
+ul.playlist.bubblegum.use-peak li .peak .r {
+ border-color:#fff;
+ background-color:#fff;
+}
+
+
+ul.playlist.shiny li.sm2_paused,
+ul.playlist.shiny li.sm2_playing {
+ background-image:url(../image/top-highlight.png);
+ background-repeat:repeat-x;
+ background-position:0px -1px;
+ _background-image:none; /* can't be bothered with IE 6. */
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css new file mode 100755 index 0000000..2c0ca3b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css @@ -0,0 +1,320 @@ +/*
+
+ SoundManager 2: "page as playlist" example
+ ------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+*/
+
+.spectrum-container {
+ display:none;
+}
+
+ul.use-spectrum li.sm2_playing .spectrum-container {
+ position:absolute;
+ left:0px;
+ top:0px;
+ margin-left:-266px;
+ margin-top:-1px;
+ display:block;
+ background-color:#5588bb;
+ border:1px solid #99ccff;
+ -moz-border-radius:4px;
+ -webkit-border-radius:4px;
+ border-radius:4px;
+}
+
+ul.use-spectrum .spectrum-box {
+ position:relative;
+ width:255px;
+ font-size:1em;
+ padding:2px 0px;
+ height:1.2em;
+ overflow:hidden;
+}
+
+ul.use-spectrum .spectrum-box .spectrum {
+ position:absolute;
+ left:0px;
+ top:-2px;
+ margin-top:20px;
+ display:block;
+ font-size:1px;
+ width:1px;
+ height:1px; /* set to 50px for a thick line, 1px for a thin line, etc. */
+ overflow:hidden;
+ background-color:#fff;
+}
+
+ul.playlist {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+
+}
+
+ul.playlist li {
+ /* assume all items will be sounds rather than wait for onload etc. in this example.. may differ for your uses. */
+ position:relative;
+ display:block;
+ width:auto;
+ font-size:2em;
+ color:#666;
+ padding:0.25em 0.5em 0.25em 0.5em;
+ border:none;
+ letter-spacing:-1px; /* ZOMG WEB X.0. ;) */
+ background-color:#f9f9f9;
+ -webkit-transition-property: hover;
+ -webkit-transition: background-color 0.15s ease-in-out;
+ -moz-transition: background-color 0.15s linear 0s; /* firefox 4 */
+ -o-transition-property: background-color; /* opera 10.5 */
+ -o-transition-duration: 0.15s;
+
+}
+
+ul.playlist li a {
+ display:block;
+ text-decoration:none;
+ font-weight:normal;
+ color:#000;
+ font-size:120%;
+ outline:none;
+ position:relative;
+ z-index:2;
+}
+
+ul.playlist li.sm2_playing,
+ul.playlist li.sm2_paused,
+ul.playlist li.sm2_playing a {
+ color:#fff;
+ border-radius:3px;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+}
+
+ul.playlist li:hover {
+ background-color:#eee;
+}
+
+ul.playlist li:hover a {
+ color:#333;
+}
+
+ul.playlist li.sm2_playing,
+ul.playlist li.sm2_playing:hover {
+ background-color:#6699cc;
+}
+
+ul.playlist li.sm2_paused {
+ background-color:#999;
+}
+
+ul.playlist li.sm2_playing:hover a,
+ul.playlist li.sm2_paused a {
+ color:#fff;
+}
+
+ul.playlist li .controls {
+ display:none;
+}
+
+ul.playlist li .peak,
+ul.playlist.use-peak li .peak {
+ display:none;
+ position:absolute;
+ top:0.55em;
+ right:0.5em;
+}
+
+ul.playlist li.sm2_playing .controls,
+ul.playlist li.sm2_paused .controls {
+ position:relative;
+ display:block;
+}
+
+ul.playlist.use-peak li.sm2_playing .peak,
+ul.playlist.use-peak li.sm2_paused .peak {
+ display:inline;
+ display:inline-block;
+}
+
+ul.playlist.use-peak li .peak {
+ display:none; /* IE 7 */
+}
+
+ul.playlist li.sm2_paused .controls {
+ background-color:#666;
+}
+
+ul.playlist li:hover .controls .statusbar {
+ position:relative;
+ cursor:ew-resize;
+ cursor:-moz-grab;
+ cursor:grab;
+}
+
+ul.playlist li.sm2_paused .controls .statusbar {
+ background-color:#ccc;
+}
+
+ul.playlist li .controls {
+ position:relative;
+ margin-top:0.25em;
+ margin-bottom:0.25em;
+ background-color:#99ccff;
+}
+
+ul.playlist li .controls .statusbar {
+ position:relative;
+ height:0.5em;
+ background-color:#ccddff;
+ border:2px solid #fff;
+ border-radius:2px;
+ -moz-border-radius:2px;
+ -webkit-border-radius:2px;
+ overflow:hidden;
+ cursor:-moz-grab;
+ cursor:grab;
+}
+
+ul.playlist li .controls.dragging .statusbar {
+ cursor:-moz-grabbing;
+ cursor:grabbing;
+}
+
+ul.playlist li .controls .statusbar .position,
+ul.playlist li .controls .statusbar .loading,
+ul.playlist li .controls .statusbar .annotation {
+ position:absolute;
+ left:0px;
+ top:0px;
+ height:0.5em;
+}
+
+ul.playlist li .controls .statusbar .position {
+ background-color:#336699;
+ border-right:3px solid #336699;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist li.sm2_paused .controls .statusbar .position {
+ background-color:#666;
+ border-color:#666;
+}
+
+ul.playlist li .controls .statusbar .loading {
+ background-color:#eee;
+}
+
+ul.playlist li .controls .statusbar .position,
+ul.playlist li .controls .statusbar .loading {
+ width:0px;
+}
+
+ul.playlist li.sm2_playing a.sm2_link,
+ul.playlist li.sm2_paused a.sm2_link {
+ margin-right:4.5em; /* room for timing stuff */
+}
+
+ul.playlist li .timing {
+ position:absolute;
+ display:none;
+ text-align:right;
+ right:1em;
+ top:1em;
+ width:auto;
+ height:1em;
+ padding:3px 5px;
+ background-color:#5588bb;
+ border:1px solid #99ccff;
+ -moz-border-radius:4px;
+ -khtml-border-radius:4px;
+ border-radius:4px;
+ letter-spacing:0px;
+ font:44% monaco,"VT-100",terminal,"lucida console",courier,system;
+ line-height:1em;
+ vertical-align:middle;
+}
+
+ul.playlist.use-peak li .timing {
+ right:4.25em;
+}
+
+ul.playlist li:hover .timing {
+ z-index:2;
+}
+
+ul.playlist li .timing div.sm2_timing {
+ margin:0px;
+ padding:0px;
+ margin-top:-1em;
+}
+
+ul.playlist li.sm2_playing .timing,
+ul.playlist li.sm2_paused .timing {
+ display:block;
+}
+
+ul.playlist li.sm2_paused .timing .sm2_position {
+ text-decoration:blink; /* hee hee. first actual appropriate use? :D */
+}
+
+ul.playlist li.sm2_paused .timing,
+ul.playlist.use-peak li.sm2_paused .peak {
+ background-color:#888;
+ border-color:#ccc;
+}
+
+/* peak data */
+
+/* ul.playlist ... */
+
+ul.playlist.use-peak li .peak {
+ display:none;
+ zoom:1;
+ border:1px solid #99ccff;
+ padding:2px;
+ height:0.55em;
+ -moz-border-radius:4px;
+ -khtml-border-radius:4px;
+ border-radius:4px;
+ background-color:#5588bb;
+ width:0.8em;
+ height:0.55em;
+ margin-top:-3px;
+}
+
+ul.playlist.use-peak li .peak-box {
+ position:relative;
+ width:100%;
+ height:0.55em;
+ overflow:hidden;
+}
+
+ul.playlist li .peak .l,
+ul.playlist li .peak .r {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:7px;
+ height:50px;
+ background:#fff;
+ border:1px solid #fff;
+ -moz-border-radius:1px;
+ -khtml-border-radius:1px;
+ margin-top:1em;
+}
+
+ul.playlist li .peak .l {
+ margin-right:1px;
+}
+
+ul.playlist li .peak .r {
+ left:10px;
+}
+
+#control-template {
+ display:none;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png Binary files differnew file mode 100755 index 0000000..05b1dff --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png Binary files differnew file mode 100755 index 0000000..fbcf930 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png Binary files differnew file mode 100755 index 0000000..f88668d --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html new file mode 100755 index 0000000..ee5bf79 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html @@ -0,0 +1,367 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 links on a page, "page as playlist" style</title> +<meta name="robots" content="noindex" />
+
+<!-- for this page only, make things pretty -->
+<link rel="stylesheet" type="text/css" href="css/demo.css" />
+
+<!-- player core CSS -->
+<link rel="stylesheet" type="text/css" href="css/page-player.css" />
+
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+
+<!-- optional: annotations/sub-tracks/notes, and alternate themes -->
+<link rel="stylesheet" type="text/css" href="css/optional-annotations.css" />
+<link rel="stylesheet" type="text/css" href="css/optional-themes.css" />
+
+<style type="text/css">
+ul.playlist li .comment {font-size:0.65em;opacity:0.5}
+</style>
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript">
+
+/* --------
+
+ Config override: This demo uses shiny flash 9 stuff, overwriting Flash 8-based defaults
+ Alternate PP_CONFIG object must be defined before page-player JS is included/executed.
+ Alternately, edit the config in page-player.js to simply use the values below by default
+
+-------- */
+
+// demo only..
+soundManager.useHighPerformance = true; // keep flash on screen, boost performance
+soundManager.wmode = 'transparent'; // transparent SWF, if possible
+soundManager.useFastPolling = true; // increased JS callback frequency
+soundManager.url = '../../swf/';
+
+var PP_CONFIG = {
+ flashVersion: 9, // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.
+ usePeakData: true, // [Flash 9 only] whether or not to show peak data (left/right channel values) - nor noticable on CPU
+ useWaveformData: true, // [Flash 9 only] show raw waveform data - WARNING: LIKELY VERY CPU-HEAVY
+ useEQData: false, // [Flash 9 only] show EQ (frequency spectrum) data
+ useFavIcon: false, // try to apply peakData to address bar (Firefox + Opera) - performance note: appears to make Firefox 3 do some temporary, heavy disk access/swapping/garbage collection at first(?) - may be too heavy on CPU
+ useMovieStar: true // Flash 9.0r115+ only: Support for a subset of MPEG4 formats.
+}
+
+</script>
+<script type="text/javascript" src="script/page-player.js"></script>
+<script type="text/javascript">
+var is_shiny = false;
+function setTheme(sTheme) {
+ var o = pagePlayer.getElementsByClassName('playlist','ul');
+ for (var i=o.length; i--;) {
+ o[i].className = 'playlist'+(pagePlayer.cssBase?' '+pagePlayer.cssBase:'')+(sTheme?' '+sTheme:'')+(is_shiny?' shiny':'');
+ }
+ return false;
+}
+function setShiny(bShiny) {
+ is_shiny = bShiny;
+ var o = pagePlayer.getElementsByClassName('playlist','ul');
+ var sClass = 'shiny';
+ for (var i=o.length; i--;) {
+ if (!bShiny) {
+ pagePlayer.removeClass(o[i],sClass);
+ } else {
+ pagePlayer.addClass(o[i],sClass);
+ }
+ }
+}
+</script>
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play a page of mp3s with javascript via SoundManager 2">SoundManager 2</a> / "Page as a playlist"</h1>
+
+ <h2 style="margin-top:0px;border:none">Muxtape.com-style UI, MP3/AAC Player Example</h2>
+ <p class="note">*CSS 3 border-radius supported by Firefox 2.x+, Safari (2.x?) and IE 9.</p>
+
+ <p style="margin-top:1.5em;color:#333">This page uses shiny features which require Flash 9. The <a href="basic.html" title="Basic page player demo">default config</a> uses Flash 8.</p>
+
+ <div id="sm2-container">
+ <!-- SM2 flash goes here -->
+ </div>
+
+ <ul class="playlist">
+ <li><a href="../mpc/audio/CRASH_1.mp3">Crash cymbal</a></li>
+ <li><a href="../_mp3/bass.mp3">Bass</a></li>
+ <li><a href="../_mp3/sine,%20square,%20sawtooth,%20rando.mp3">440 Hz sine, square, sawtooth, pink noise, random</a></li>
+ <li><a href="../_mp3/1hz-10khz-sweep.mp3">1Hz - 10KHz sweep</a></li>
+ <!-- files from the web (note that ID3 and waveformData information will *not* load from remote domains without permission, due to Flash security restrictions) -->
+ <li><a href="http://freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></li>
+ <li><a href="http://freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl <span class="comment">(featureblend.com)</span></a></li>
+ <li><a href="http://freshly-ground.com/data/audio/binaural/Mak.mp3" class="exclude">Angry cow sound with "exclude" CSS class <span class="comment">(Browser follows link normally)</span></a></li>
+ </ul>
+
+ <h2>MPEG4 / H.264 + HE-AAC (Flash "MovieStar" 9.0r115+) format support - audio-only example</h2>
+ <h3>A subset of MPEG4 <a href="http://www.adobe.com/support/documentation/en/flashplayer/9/releasenotes.html#fixes_90115">is supported</a> including AAC, FLV, MP4, M4A, MOV, MP4V, 3GP and 3G2 files.</h3>
+
+ <ul class="playlist">
+ <li><a href="http://freshly-ground.com/data/video/Rain%20on%20Car%20Roof.aac">Rain on Car Roof <span class="comment">(MPEG4 .AAC audio, 128 kbps AAC-LC exported from QuickTime)</span></a></li>
+ <li><a href="http://freshly-ground.com/data/video/Jellyfish.mov">Jellyfish <span class="comment">(848x480 H.264 video, playing audio portion only)</span></a></li>
+ </ul>
+
+ <div id="control-template">
+ <!-- control markup inserted dynamically after each link -->
+ <div class="controls">
+ <div class="statusbar">
+ <div class="loading"></div>
+ <div class="position"></div>
+ </div>
+ </div>
+ <div class="timing">
+ <div id="sm2_timing" class="timing-data">
+ <span class="sm2_position">%s1</span> / <span class="sm2_total">%s2</span>
+ </div>
+ </div>
+ <div class="peak">
+ <div class="peak-box"><span class="l"></span><span class="r"></span></div>
+ </div>
+ </div>
+
+ <div id="spectrum-container" class="spectrum-container">
+ <div class="spectrum-box">
+ <div class="spectrum"></div>
+ </div>
+ </div>
+
+ <h3 style="margin-top:1em">Basics</h3>
+
+ <p class="note">Don't want a Flash 9 requirement, EQ/waveform, perhaps less CPU? See Flash 8-based <a href="basic.html" title="Page as playlist demo">basic demo</a>.</p>
+
+ <p>Clicking a title will start loading + playing, or pause, a sound.</p>
+ <p>Once loading, click (or click and drag) on the loading/position bar to seek within the sound.</p>
+ <p>The document title reflects the currently-playing sound, and by default the list will play sequentially if left alone. (This is configurable.)</p>
+
+ <h3>Themes</h3>
+ <p>Just for fun, a few color schemes (visible when playing/paused):</p>
+ <ul class="themes">
+ <li><a href="#" onclick="return setTheme('dark')"><ul class="playlist dark"></a> - #333 and #666, mostly</li>
+ <li><a href="#" onclick="return setTheme('gold')"><ul class="playlist gold"></a> - Frontin' the bling</li>
+ <li><a href="#" onclick="return setTheme('bubblegum')"><ul class="playlist bubblegum"></a> - ZOMG PONIES!!!ONEONEONE</li>
+ <li><a href="#" onclick="return setTheme('')"><ul class="playlist"></a> (default)</li>
+ </ul>
+
+ <form style="margin:0px;padding:0px" action="#" onsubmit="return false">
+ <div>
+ <input id="makeShiny" name="makeShiny" type="checkbox" onchange="setShiny(this.checked)" value="Shiny" /> <label for="makeShiny">Also add "shiny", eg. <ul class="shiny playlist">...</label>
+ </div>
+ </form>
+ <script type="text/javascript">document.getElementById('makeShiny').checked=false;</script>
+
+ <h2 id="metadata">Experimental (Alpha) Variant: MP3 "Metadata": Annotations / notes / sub-tracks</h2>
+ <p>A potential approach to noting interesting moments in sounds, scene changes, new tracks in seamless DJ mixes etc. Keep in mind this is a single MP3 being loaded, but annotations are placed along the timeline as shown.</p>
+ <p>A "metadata" element contains a nested list of data (UL/LI combination) - in this case, a summary of each scene - and the time at which this item occurs/begins. In order to help with positioning, the total length of the sound is also specified up-front. View the source code of this page for the details.</p>
+
+ <ul class="playlist">
+
+ <li>
+ <a href="http://freshly-ground.com/data/audio/binaural/A%20Virtual%20Haircut%20in%20San%20Francisco%20%283%20Scenes%29.mp3">A Virtual Haircut (3 scenes)</a>
+ <div class="metadata">
+ <div class="duration">4:43</div> <!-- total track time (for positioning while loading, until determined -->
+ <ul>
+ <li><p>Electric razor</p><span>0:00</span></li> <!-- first scene -->
+ <li><p>Water, scissors</p><span>2:41</span></li> <!-- start time of second scene -->
+ <li><p>More razor work</p><span>4:00</span></li>
+ </ul>
+ </div>
+ </li>
+
+ <li>
+ <a href="http://freshly-ground.com/data/audio/binaural/Rubber%20Chicken%20Launch%20%28office%29.mp3">Rubber Chicken Launch (Office)</a>
+ <div class="metadata">
+ <div class="duration">0:47</div>
+ <ul>
+ <li><p>First attempt</p><span>0:00</span></li>
+ <li><p>Fire!</p><span>0:02</span></li>
+ <li><p>"Too much angle"</p><span>0:05</span></li>
+ <li><p>Random chicken noise</p><span>0:18</span></li>
+ <li><p>"Wait a second"</p><span>0:31</span></li>
+ <li><p>Derrr..</p><span>0:34</span></li>
+ <li><p>Launch attempt #2</p><span>0:36</span></li>
+ <li><p>"Wrong angle"</p><span>0:39</span></li>
+ <li><p>"Fail"</p><span>0:42</span></li>
+ </ul>
+ </div>
+ </li>
+
+ </ul>
+
+ <h2>How It Works</h2>
+
+ <p>This example uses <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 Javascript Sound API">SoundManager 2</a> to find links to MP3 files within an unordered list, and makes them playable "in-place" on a page. The script assigns CSS classes to links' parent LI nodes to indicate their state (playing/paused, etc.)</p>
+
+ <h3>Progressive Enhancement</h3>
+
+ <p>This provides a nice HTML base for all browsers and user agents, and enhances progressively for those with Javascript and Flash. Links pointing to MP3s are assigned an onclick handler which intercepts the click (preventing the browser from following the link and unloading the page. SM2 will then create sound objects as needed to play the MP3s. In the event there is an error at runtime or a lack of support (no JS/Flash etc.), the browser will simply load the MP3s directly as it normally would. This includes iPhones, etc.</p>
+
+ <h3>HTML Fragments (UI Element Templates)</h3>
+ <p>Each item in the playlist has its own set of controls and progress indicators, etc. This content is defined once as a hidden template of HTML in-page separate from the playlist markup and is cloned for each item as needed. This can be easily styled with CSS as well, of course.</p>
+
+<h2>I'd like to use this.</h2>
+<p>See this <a href="basic.html" title="Page as playlist demo">basic demo</a> for reference.</p>
+<p>The basic demo uses the default Flash 8 configuration, but you can easily change this to use Flash 9 features. The only difference in code is the configuration.</p>
+
+<p>A reminder that if loading from the local filesystem, Flash will deny access to remote (network/internet) URLs by default unless whitelisted via the <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">Flash Player Global Security Settings Page</a>. Some URLs in this example are remote to demonstrate this.</p>
+
+<h2>Configuration + Options</h2>
+
+<h3>Default configuration</h3>
+
+<p>Behaviours such as auto-start and UI elements like VU meters and spectrum graphs are easy configurable, using an object literal format as shown below.</p>
+<p>The page player config (see related page-player.js file) as below.</p>
+<p>The custom parameters used to make this demo page are highlighted in red.</p>
+<pre class="block"><code> <span>// ( within page-player.js )</span>
+
+ this.config = {
+ flashVersion: <span style="color:red">9</span>, <span>// version of Flash to tell SoundManager to use - either 8 or 9.</span>
+ usePeakData: <span style="color:red">true</span>, <span>// [Flash 9 only] show peak (VU-meter) data</span>
+ useFavIcon: <span style="color:red">true</span>, <span>// try to show peakData in address bar (Firefox + Opera) - requires usePeakData = true too, of course.</span>
+ useWaveformData: <span style="color:red">true</span>, <span>// [Flash 9 only] true: show raw waveform data - WARNING: CPU-intensive</span>
+ useEQData: false, <span>// [Flash 9 only] show EQ (frequency spectrum) data - WARNING: CPU-intensive</span>
+ fillGraph: false, <span>// [Flash 9 only] draw full lines instead of only top (peak) spectrum points</span>
+ allowRightClick:true, <span>// let users right-click MP3 links ("save as...", etc.) or discourage (can't prevent.)</span>
+ useThrottling: false, <span>// try to rate-limit potentially-expensive calls (eg. dragging position around)</span>
+ autoStart: false, <span>// begin playing first sound when page loads</span>
+ playNext: true, <span>// stop after one sound, or play through list until end</span>
+ updatePageTitle: true, <span>// change the page title while playing sounds</span>
+ emptyTime: '-:--' <span>// null/undefined timer values (before data is available)</span>
+ }
+</code></pre>
+
+<h3>Per-page configuration override</h3>
+
+<p>Alternately, you may override the defaults on a per-page basis by defining an "alternate configuration" object <b>before</b> the page-player.js file has been included in your source code:</p>
+
+<pre class="block"><code> <span>// ( before page-player.js )</span>
+
+ var PP_CONFIG = {
+ flashVersion: 9, <span>// version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.</span>
+ usePeakData: true, <span>// [Flash 9 only] whether or not to show peak data (no notable CPU cost)</span>
+ useWaveformData: true <span>// [Flash 9 only] show raw waveform data. WARNING: Experimental, likely CPU-heavy</span>
+ }</code></pre>
+
+<p>Any options specified in PP_CONFIG will override the defaults defined in page-player.js.</p>
+
+ <h3>Basic CSS</h3>
+
+<pre>
+ If you want to make your own UI from scratch, here is the base:
+
+ ul.playlist {}
+
+ Default + hover state, "click to play":
+
+ li.sm2_link {}
+ li.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ li.sm2_playing {}
+ li.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ li.sm2_paused {}
+ li.sm2_paused:hover {}
+</pre>
+
+<p>The positioning (load status / control bar) template is also applied after each MP3 link, from an element named "control-template"</p>
+
+<p>"loading" and "position" have background colors applied, and have their width adjusted dynamically by SM2 as the sound(s) load/play. "timing" is replaced with the current time / duration, eg. 1:23 / 4:20</p>
+<p>The class names applied can be edited within the source JS also, for convenience.</p>
+<p>The controls are shown and hidden via the same dynamic CSS updates. See the source CSS for the timing / status bar layout.</p>
+
+<h2>Performance Considerations</h2>
+<h3>Experimental Flash 9 features</h3>
+<ul class="tight" style="padding-top:1px">
+ <li>
+ <h4>Dynamic "favicon" VU meter</h4>
+ <p>The VU meter "favicon" option as shown in the address/location bar for Firefox and Opera can cause a lot of disk access in Firefox (2.x/3.0 at time of writing, from what has been reported.) It may be garbage collection-related.</p>
+ <p>The behaviour seems to be connected to the dynamic swapping of <link> elements with data: URIs containing the VU meter data, and looks to be noticeable with the first sound played - after which point things settle down. Perhaps the browser is attempting to cache the favicon data being assigned.</p>
+ </li>
+ <li>
+ <h4>Waveform/spectrum visualization graph</h4>
+ <p>Enabling the waveformData and/or eqData features will result in some heavy DOM calls (manipulation of 256 <div> elements with each "frame" drawn) which can eat up a good amount of CPU and may make really old computers cower in fear.</p>
+ <p>Ultimately, the UI refresh rate will simply be limited if a CPU ceiling is hit, and audio playback should not be affected.</p>
+ </li>
+</ul>
+
+<h3>More CSS comments</h3>
+
+<div>
+<pre>
+ SoundManager 2: "page as playlist" example
+ ------------------------------------------
+
+ Clicks on links to MP3s are intercepted via JS, calls are
+ made to SoundManager to load/play sounds. CSS classes are
+ appended to the LI parent, which are used to highlight the
+ current play state and so on.
+
+ Class names are applied in addition to "sm2_link" base.
+
+ Default:
+
+ sm2_link
+
+ Additional states:
+
+ sm2_playing
+ sm2_paused
+
+ eg.
+
+ <!-- default -->
+ <li class="sm2_link"><a href="some.mp3">some.mp3</a></li>
+
+ <!-- playing -->
+ <li class="sm2_link sm2_playing"><a href="some.mp3">some.mp3</a></li>
+
+ The script also injects an HTML template containing control bar
+ and timing elements, which can also be targeted with CSS.
+
+
+ Note you don't necessarily require ul.playlist for your use
+ if only using one style on a page. You can just use .sm2_link
+ and so on, but isolate the CSS you want.
+
+ Side note: Would do multiple class definitions eg.
+
+ li.sm2_default.sm2_playing{}
+
+ .. except IE 6 has a parsing bug which may break behaviour,
+ applying sm2_playing {} even when the class is set to sm2_default.
+
+
+ If you want to make your own UI from scratch, here is the base:
+
+ Default + hover state, "click to play":
+
+ li.sm2_link {}
+ li.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ li.sm2_playing {}
+ li.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ li.sm2_paused {}
+ li.sm2_paused:hover {}
+</pre>
+</div>
+
+<p><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 sound player API">SoundManager 2 project home</a></p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js new file mode 100755 index 0000000..607cfff --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js @@ -0,0 +1,936 @@ +/*
+
+ SoundManager 2 Demo: "Page as playlist"
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ An example of a Muxtape.com-style UI, where an
+ unordered list of MP3 links becomes a playlist
+
+ Flash 9 "MovieStar" edition supports MPEG4
+ audio as well.
+
+ Requires SoundManager 2 Javascript API.
+
+*/
+
+function PagePlayer(oConfigOverride) {
+ var self = this;
+ var pl = this;
+ var sm = soundManager; // soundManager instance
+ // sniffing for favicon stuff/IE workarounds
+ var uA = navigator.userAgent;
+ var isIE = uA.match(/msie/i);
+ var isOpera = uA.match(/opera/i);
+ var isFirefox = uA.match(/firefox/i);
+ var isTouchDevice = (uA.match(/ipad|iphone/i));
+
+ this.config = {
+ flashVersion: 8, // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.
+ usePeakData: false, // [Flash 9 only]: show peak data
+ useWaveformData: false, // [Flash 9 only]: enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire.
+ useEQData: false, // [Flash 9 only]: enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive.
+ fillGraph: false, // [Flash 9 only]: draw full lines instead of only top (peak) spectrum points
+ allowRightClick:true, // let users right-click MP3 links ("save as...", etc.) or discourage (can't prevent.)
+ useThrottling: true, // try to rate-limit potentially-expensive calls (eg. dragging position around)
+ autoStart: false, // begin playing first sound when page loads
+ playNext: true, // stop after one sound, or play through list until end
+ updatePageTitle: true, // change the page title while playing sounds
+ emptyTime: '-:--', // null/undefined timer values (before data is available)
+ useFavIcon: false // try to show peakData in address bar (Firefox + Opera) - may be too CPU heavy
+ }
+
+ sm.debugMode = (window.location.href.toString().match(/debug=1/i)?true:false); // enable with #debug=1 for example
+
+ this._mergeObjects = function(oMain,oAdd) {
+ // non-destructive merge
+ var o1 = {}; // clone o1
+ for (var i in oMain) {
+ o1[i] = oMain[i];
+ }
+ var o2 = (typeof oAdd == 'undefined'?{}:oAdd);
+ for (var o in o2) {
+ if (typeof o1[o] == 'undefined') o1[o] = o2[o];
+ }
+ return o1;
+ }
+
+ if (typeof oConfigOverride != 'undefined' && oConfigOverride) {
+ // allow overriding via arguments object
+ this.config = this._mergeObjects(oConfigOverride,this.config);
+ }
+
+ this.css = { // CSS class names appended to link during various states
+ sDefault: 'sm2_link', // default state
+ sLoading: 'sm2_loading',
+ sPlaying: 'sm2_playing',
+ sPaused: 'sm2_paused'
+ }
+
+ // apply externally-defined override, if applicable
+ this.cssBase = []; // optional features added to ul.playlist
+ if (this.config.usePeakData) this.cssBase.push('use-peak');
+ if (this.config.useWaveformData || this.config.useEQData) this.cssBase.push('use-spectrum');
+ this.cssBase = this.cssBase.join(' ');
+
+ // apply some items to SM2
+ sm.useFlashBlock = true;
+ sm.flashVersion = this.config.flashVersion;
+ if (sm.flashVersion >= 9) {
+ sm.useMovieStar = this.config.useMovieStar; // enable playing FLV, MP4 etc.
+ sm.defaultOptions.usePeakData = this.config.usePeakData;
+ sm.defaultOptions.useWaveformData = this.config.useWaveformData;
+ sm.defaultOptions.useEQData = this.config.useEQData;
+ }
+
+ this.links = [];
+ this.sounds = [];
+ this.soundsByObject = [];
+ this.lastSound = null;
+ this.soundCount = 0;
+ this.strings = [];
+ this.dragActive = false;
+ this.dragExec = new Date();
+ this.dragTimer = null;
+ this.pageTitle = document.title;
+ this.lastWPExec = new Date();
+ this.lastWLExec = new Date();
+ this.vuMeterData = [];
+ this.oControls = null;
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.hasClass = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?new RegExp('(^|\\s)'+cStr+'(\\s|$)').test(o.className):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (self.hasClass(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (!self.hasClass(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getElementsByClassName = function(className,tagNames,oParent) {
+ var doc = (oParent?oParent:document);
+ var matches = [];
+ var i,j;
+ var nodes = [];
+ if (typeof(tagNames)!='undefined' && typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ if (!nodes || !nodes[tagNames[i]]) {
+ nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
+ }
+ }
+ } else if (tagNames) {
+ nodes = doc.getElementsByTagName(tagNames);
+ } else {
+ nodes = doc.all||doc.getElementsByTagName('*');
+ }
+ if (typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ for (j=nodes[tagNames[i]].length; j--;) {
+ if (self.hasClass(nodes[tagNames[i]][j],className)) {
+ matches[matches.length] = nodes[tagNames[i]][j];
+ }
+ }
+ }
+ } else {
+ for (i=0; i<nodes.length; i++) {
+ if (self.hasClass(nodes[i],className)) {
+ matches[matches.length] = nodes[i];
+ }
+ }
+ }
+ return matches;
+ }
+
+ this.getOffX = function(o) {
+ // http://www.xs4all.nl/~ppk/js/findpos.html
+ var curleft = 0;
+ if (o.offsetParent) {
+ while (o.offsetParent) {
+ curleft += o.offsetLeft;
+ o = o.offsetParent;
+ }
+ }
+ else if (o.x) curleft += o.x;
+ return curleft;
+ }
+
+ this.isChildOfClass = function(oChild,oClass) {
+ if (!oChild || !oClass) return false;
+ while (oChild.parentNode && !self.hasClass(oChild,oClass)) {
+ oChild = oChild.parentNode;
+ }
+ return (self.hasClass(oChild,oClass));
+ }
+
+ this.getParentByNodeName = function(oChild,sParentNodeName) {
+ if (!oChild || !sParentNodeName) return false;
+ sParentNodeName = sParentNodeName.toLowerCase();
+ while (oChild.parentNode && sParentNodeName != oChild.parentNode.nodeName.toLowerCase()) {
+ oChild = oChild.parentNode;
+ }
+ return (oChild.parentNode && sParentNodeName == oChild.parentNode.nodeName.toLowerCase()?oChild.parentNode:null);
+ }
+
+ this.getTime = function(nMSec,bAsString) {
+ // convert milliseconds to mm:ss, return as object literal or string
+ var nSec = Math.floor(nMSec/1000);
+ var min = Math.floor(nSec/60);
+ var sec = nSec-(min*60);
+ // if (min == 0 && sec == 0) return null; // return 0:00 as null
+ return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});
+ }
+
+ this.getSoundByObject = function(o) {
+ return (typeof self.soundsByObject[o.rel] != 'undefined'?self.soundsByObject[o.rel]:null);
+ }
+
+ this.getSoundIndex = function(o) {
+ for (var i=self.links.length; i--;) {
+ if (self.links[i].rel == o.rel) return i;
+ }
+ return -1;
+ }
+
+ this.setPageTitle = function(sTitle) {
+ if (!self.config.updatePageTitle) return false;
+ try {
+ document.title = (sTitle?sTitle+' - ':'')+self.pageTitle;
+ } catch(e) {
+ // oh well
+ self.setPageTitle = function() {return false;}
+ }
+ }
+
+ this.events = {
+
+ // handlers for sound events as they're started/stopped/played
+
+ play: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLI,this._data.className);
+ self.setPageTitle(this._data.originalTitle);
+ },
+
+ stop: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = '';
+ this._data.oPosition.style.width = '0px';
+ self.setPageTitle();
+ self.resetPageIcon();
+ },
+
+ pause: function() {
+ if (pl.dragActive) return false;
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPaused;
+ pl.addClass(this._data.oLI,this._data.className);
+ self.setPageTitle();
+ self.resetPageIcon();
+ },
+
+ resume: function() {
+ if (pl.dragActive) return false;
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLI,this._data.className);
+ },
+
+ finish: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = '';
+ this._data.oPosition.style.width = '0px';
+ // play next if applicable
+ if (self.config.playNext && this._data.nIndex<pl.links.length-1) {
+ pl.handleClick({target:pl.links[this._data.nIndex+1]}); // fake a click event - aren't we sneaky. ;)
+ } else {
+ self.setPageTitle();
+ self.resetPageIcon();
+ }
+ },
+
+ whileloading: function() {
+ function doWork() {
+ this._data.oLoading.style.width = (((this.bytesLoaded/this.bytesTotal)*100)+'%'); // theoretically, this should work.
+ if (!this._data.didRefresh && this._data.metadata) {
+ this._data.didRefresh = true;
+ this._data.metadata.refresh();
+ }
+ }
+ if (!pl.config.useThrottling) {
+ doWork.apply(this);
+ } else {
+ d = new Date();
+ if (d && d-self.lastWLExec>30 || this.bytesLoaded === this.bytesTotal) {
+ doWork.apply(this);
+ self.lastWLExec = d;
+ }
+ }
+
+ },
+
+ onload: function() {
+ if (!this.loaded) {
+ var oTemp = this._data.oLI.getElementsByTagName('a')[0];
+ var oString = oTemp.innerHTML;
+ var oThis = this;
+ 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>';
+ setTimeout(function(){
+ oTemp.innerHTML = oString;
+ // pl.events.finish.apply(oThis); // load next
+ },5000);
+ } else {
+ if (this._data.metadata) {
+ this._data.metadata.refresh();
+ }
+ }
+ },
+
+ whileplaying: function() {
+ var d = null;
+ if (pl.dragActive || !pl.config.useThrottling) {
+ self.updateTime.apply(this);
+ if (sm.flashVersion >= 9) {
+ if (pl.config.usePeakData && this.instanceOptions.usePeakData) self.updatePeaks.apply(this);
+ if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {
+ self.updateGraph.apply(this);
+ }
+ }
+ if (this._data.metadata) {
+ d = new Date();
+ if (d && d-self.lastWPExec>500) {
+ self.refreshMetadata(this);
+ self.lastWPExec = d;
+ }
+ }
+ this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');
+ } else {
+ d = new Date();
+ if (d-self.lastWPExec>30) {
+ self.updateTime.apply(this);
+ if (sm.flashVersion >= 9) {
+ if (pl.config.usePeakData && this.instanceOptions.usePeakData) {
+ self.updatePeaks.apply(this);
+ }
+ if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {
+ self.updateGraph.apply(this);
+ }
+ }
+ if (this._data.metadata) self.refreshMetadata(this);
+ this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');
+ self.lastWPExec = d;
+ }
+ }
+ }
+
+ } // events{}
+
+ var _head = document.getElementsByTagName('head')[0];
+
+ this.setPageIcon = function(sDataURL) {
+ if (!self.config.useFavIcon || !self.config.usePeakData || !sDataURL) {
+ return false;
+ }
+ var link = document.getElementById('sm2-favicon');
+ if (link) {
+ _head.removeChild(link);
+ link = null;
+ }
+ if (!link) {
+ link = document.createElement('link');
+ link.id = 'sm2-favicon';
+ link.rel = 'shortcut icon';
+ link.type = 'image/png';
+ link.href = sDataURL;
+ document.getElementsByTagName('head')[0].appendChild(link);
+ }
+ }
+
+ this.resetPageIcon = function() {
+ if (!self.config.useFavIcon) {
+ return false;
+ }
+ var link = document.getElementById('favicon');
+ if (link) {
+ link.href = '/favicon.ico';
+ }
+ }
+
+ this.updatePeaks = function() {
+ var o = this._data.oPeak;
+ var oSpan = o.getElementsByTagName('span');
+ oSpan[0].style.marginTop = (13-(Math.floor(15*this.peakData.left))+'px');
+ oSpan[1].style.marginTop = (13-(Math.floor(15*this.peakData.right))+'px');
+ // highly experimental
+ if (self.config.flashVersion > 8 && self.config.useFavIcon && self.config.usePeakData) {
+ self.setPageIcon(self.vuMeterData[parseInt(16*this.peakData.left)][parseInt(16*this.peakData.right)]);
+ }
+ }
+
+ this.updateGraph = function() {
+ if ((!pl.config.useWaveformData && !pl.config.useEQData) || pl.config.flashVersion<9) return false;
+ var sbC = this._data.oGraph.getElementsByTagName('div');
+ if (pl.config.useWaveformData) {
+ // raw waveform
+ var scale = 8; // Y axis (+/- this distance from 0)
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = (1+scale+Math.ceil(this.waveformData.left[i]*-scale))+'px';
+ }
+ } else {
+ // eq spectrum
+ var offset = 9;
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = ((offset*2)-1+Math.ceil(this.eqData[i]*-offset))+'px';
+ }
+ }
+ }
+
+ this.resetGraph = function() {
+ if (!pl.config.useEQData || pl.config.flashVersion<9) return false;
+ var sbC = this._data.oGraph.getElementsByTagName('div');
+ var scale = (!pl.config.useEQData?'9px':'17px');
+ var nHeight = (!pl.config.fillGraph?'1px':'32px');
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = scale; // EQ scale
+ sbC[255-i].style.height = nHeight;
+ }
+ }
+
+ this.refreshMetadata = function(oSound) {
+ // Display info as appropriate
+ var index = null;
+ var now = oSound.position;
+ var metadata = oSound._data.metadata.data;
+ for (var i=0, j=metadata.length; i<j; i++) {
+ if (now >= metadata[i].startTimeMS && now <= metadata[i].endTimeMS) {
+ index = i;
+ break;
+ }
+ }
+ if (index != metadata.currentItem) {
+ // update
+ oSound._data.oLink.innerHTML = metadata.mainTitle+' <span class="metadata"><span class="sm2_divider"> | </span><span class="sm2_metadata">'+metadata[index].title+'</span></span>';
+ self.setPageTitle(metadata[index].title+' | '+metadata.mainTitle);
+ metadata.currentItem = index;
+ }
+ }
+
+ this.updateTime = function() {
+ var str = self.strings['timing'].replace('%s1',self.getTime(this.position,true));
+ str = str.replace('%s2',self.getTime(self.getDurationEstimate(this),true));
+ this._data.oTiming.innerHTML = str;
+ }
+
+ this.getTheDamnTarget = function(e) {
+ return (e.target||(window.event?window.event.srcElement:null));
+ }
+
+ this.withinStatusBar = function(o) {
+ return (self.isChildOfClass(o,'controls'));
+ }
+
+ this.handleClick = function(e) {
+ // a sound (or something) was clicked - determine what and handle appropriately
+ if (e.button == 2) {
+ if (!pl.config.allowRightClick) {
+ pl.stopEvent(e);
+ }
+ return pl.config.allowRightClick; // ignore right-clicks
+ }
+ var o = self.getTheDamnTarget(e);
+ if (!o) {
+ return true;
+ }
+ if (self.dragActive) self.stopDrag(); // to be safe
+ if (self.withinStatusBar(o)) {
+ // self.handleStatusClick(e);
+ return false;
+ }
+ if (o.nodeName.toLowerCase() != 'a') {
+ o = self.getParentByNodeName(o,'a');
+ }
+ if (!o) {
+ // not a link
+ return true;
+ }
+ var sURL = o.getAttribute('href');
+ if (!o.href || (!sm.canPlayLink(o) && !self.hasClass(o,'playable')) || self.hasClass(o,'exclude')) {
+ // do nothing, don't return anything.
+ } else {
+ // we have something we're interested in.
+ var soundURL = o.href;
+ var thisSound = self.getSoundByObject(o);
+ if (thisSound) {
+ // sound already exists
+ self.setPageTitle(thisSound._data.originalTitle);
+ if (thisSound == self.lastSound) {
+ // ..and was playing (or paused) and isn't in an error state
+ if (thisSound.readyState != 2) {
+ if (thisSound.playState != 1) {
+ // not yet playing
+ thisSound.play();
+ } else {
+ thisSound.togglePause();
+ }
+ } else {
+ sm._writeDebug('Warning: sound failed to load (security restrictions, 404 or bad format)',2);
+ }
+ } else {
+ // ..different sound
+ if (self.lastSound) self.stopSound(self.lastSound);
+ thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));
+ thisSound.togglePause(); // start playing current
+ }
+ } else {
+ // create sound
+ thisSound = sm.createSound({
+ id:'pagePlayerMP3Sound'+(self.soundCount++),
+ url:decodeURI(soundURL),
+ onplay:self.events.play,
+ onstop:self.events.stop,
+ onpause:self.events.pause,
+ onresume:self.events.resume,
+ onfinish:self.events.finish,
+ whileloading:self.events.whileloading,
+ whileplaying:self.events.whileplaying,
+ onmetadata:self.events.metadata,
+ onload:self.events.onload
+ });
+ // append control template
+ var oControls = self.oControls.cloneNode(true);
+ o.parentNode.appendChild(oControls);
+ o.parentNode.appendChild(document.getElementById('spectrum-container'));
+ self.soundsByObject[o.rel] = thisSound;
+ // tack on some custom data
+ thisSound._data = {
+ oLink: o, // DOM reference within SM2 object event handlers
+ oLI: o.parentNode,
+ oControls: self.getElementsByClassName('controls','div',o.parentNode)[0],
+ oStatus: self.getElementsByClassName('statusbar','div',o.parentNode)[0],
+ oLoading: self.getElementsByClassName('loading','div',o.parentNode)[0],
+ oPosition: self.getElementsByClassName('position','div',o.parentNode)[0],
+ oTimingBox: self.getElementsByClassName('timing','div',o.parentNode)[0],
+ oTiming: self.getElementsByClassName('timing','div',o.parentNode)[0].getElementsByTagName('div')[0],
+ oPeak: self.getElementsByClassName('peak','div',o.parentNode)[0],
+ oGraph: self.getElementsByClassName('spectrum-box','div',o.parentNode)[0],
+ nIndex: self.getSoundIndex(o),
+ className: self.css.sPlaying,
+ originalTitle: o.innerHTML,
+ metadata: null
+ };
+ thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));
+ // "Metadata"
+ if (thisSound._data.oLI.getElementsByTagName('ul').length) {
+ thisSound._data.metadata = new Metadata(thisSound);
+ }
+ // set initial timer stuff (before loading)
+ var str = self.strings['timing'].replace('%s1',self.config.emptyTime);
+ str = str.replace('%s2',self.config.emptyTime);
+ thisSound._data.oTiming.innerHTML = str;
+ self.sounds.push(thisSound);
+ if (self.lastSound) self.stopSound(self.lastSound);
+ self.resetGraph.apply(thisSound);
+ thisSound.play();
+ }
+ self.lastSound = thisSound; // reference for next call
+ return self.stopEvent(e);
+ }
+ }
+
+ this.handleMouseDown = function(e) {
+ // a sound link was clicked
+ if (isTouchDevice && e.touches) {
+ e = e.touches[0];
+ }
+ if (e.button == 2) {
+ if (!pl.config.allowRightClick) pl.stopEvent(e);
+ return (pl.config.allowRightClick); // ignore right-clicks
+ }
+ var o = self.getTheDamnTarget(e);
+ if (!o) {
+ return true;
+ }
+ if (!self.withinStatusBar(o)) return true;
+ self.dragActive = true;
+ self.lastSound.pause();
+ self.setPosition(e);
+ if (!isTouchDevice) {
+ self.addEventHandler(document,'mousemove',self.handleMouseMove);
+ } else {
+ self.addEventHandler(document,'touchmove',self.handleMouseMove);
+ }
+ self.addClass(self.lastSound._data.oControls,'dragging');
+ self.stopEvent(e);
+ return false;
+ }
+
+ this.handleMouseMove = function(e) {
+ if (isTouchDevice && e.touches) {
+ e = e.touches[0];
+ }
+ // set position accordingly
+ if (self.dragActive) {
+ if (self.config.useThrottling) {
+ // be nice to CPU/externalInterface
+ var d = new Date();
+ if (d-self.dragExec>20) {
+ self.setPosition(e);
+ } else {
+ window.clearTimeout(self.dragTimer);
+ self.dragTimer = window.setTimeout(function(){self.setPosition(e)},20);
+ }
+ self.dragExec = d;
+ } else {
+ // oh the hell with it
+ self.setPosition(e);
+ }
+ } else {
+ self.stopDrag();
+ }
+ e.stopPropagation = true;
+ return false;
+ }
+
+ this.stopDrag = function(e) {
+ if (self.dragActive) {
+ self.removeClass(self.lastSound._data.oControls,'dragging');
+ if (!isTouchDevice) {
+ self.removeEventHandler(document,'mousemove',self.handleMouseMove);
+ } else {
+ self.removeEventHandler(document,'touchmove',self.handleMouseMove);
+ }
+ // self.removeEventHandler(document,'mouseup',self.stopDrag);
+ if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) {
+ self.lastSound.resume();
+ }
+ self.dragActive = false;
+ self.stopEvent(e);
+ return false;
+ }
+ }
+
+ this.handleStatusClick = function(e) {
+ self.setPosition(e);
+ if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) self.resume();
+ return self.stopEvent(e);
+ }
+
+ this.stopEvent = function(e) {
+ if (typeof e != 'undefined') {
+ if (typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof e.returnValue != 'undefined' || typeof event != 'undefined') {
+ (e||event).cancelBubble = true;
+ (e||event).returnValue = false;
+ }
+ }
+ return false;
+ }
+
+ this.setPosition = function(e) {
+ // called from slider control
+ var oThis = self.getTheDamnTarget(e);
+ if (!oThis) {
+ return true;
+ }
+ var oControl = oThis;
+ while (!self.hasClass(oControl,'controls') && oControl.parentNode) {
+ oControl = oControl.parentNode;
+ }
+ var oSound = self.lastSound;
+ var x = parseInt(e.clientX);
+ // play sound at this position
+ var nMsecOffset = Math.floor((x-self.getOffX(oControl)-4)/(oControl.offsetWidth)*self.getDurationEstimate(oSound));
+ if (!isNaN(nMsecOffset)) nMsecOffset = Math.min(nMsecOffset,oSound.duration);
+ if (!isNaN(nMsecOffset)) oSound.setPosition(nMsecOffset);
+ }
+
+ this.stopSound = function(oSound) {
+ sm._writeDebug('stopping sound: '+oSound.sID);
+ sm.stop(oSound.sID);
+ sm.unload(oSound.sID);
+ }
+
+ this.getDurationEstimate = function(oSound) {
+ if (oSound.instanceOptions.isMovieStar) {
+ return (oSound.duration);
+ } else {
+ return (!oSound._data.metadata || !oSound._data.metadata.data.givenDuration?(oSound.durationEstimate||0):oSound._data.metadata.data.givenDuration);
+ }
+ }
+
+ this.createVUData = function() {
+ var i=0;
+ var j=0;
+ var canvas = vuDataCanvas.getContext('2d');
+ var vuGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ vuGrad.addColorStop(0,'rgb(0,192,0)');
+ vuGrad.addColorStop(0.30,'rgb(0,255,0)');
+ vuGrad.addColorStop(0.625,'rgb(255,255,0)');
+ vuGrad.addColorStop(0.85,'rgb(255,0,0)');
+ var bgGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ var outline = 'rgba(0,0,0,0.2)';
+ bgGrad.addColorStop(0,outline);
+ bgGrad.addColorStop(1,'rgba(0,0,0,0.5)');
+ for (i=0; i<16; i++) {
+ self.vuMeterData[i] = [];
+ }
+ for (var i=0; i<16; i++) {
+ for (j=0; j<16; j++) {
+ // reset/erase canvas
+ vuDataCanvas.setAttribute('width',16);
+ vuDataCanvas.setAttribute('height',16);
+ // draw new stuffs
+ canvas.fillStyle = bgGrad;
+ canvas.fillRect(0,0,7,15);
+ canvas.fillRect(8,0,7,15);
+ /*
+ // shadow
+ canvas.fillStyle = 'rgba(0,0,0,0.1)';
+ canvas.fillRect(1,15-i,7,17-(17-i));
+ canvas.fillRect(9,15-j,7,17-(17-j));
+ */
+ canvas.fillStyle = vuGrad;
+ canvas.fillRect(0,15-i,7,16-(16-i));
+ canvas.fillRect(8,15-j,7,16-(16-j));
+ // and now, clear out some bits.
+ canvas.clearRect(0,3,16,1);
+ canvas.clearRect(0,7,16,1);
+ canvas.clearRect(0,11,16,1);
+ self.vuMeterData[i][j] = vuDataCanvas.toDataURL('image/png');
+ // for debugging VU images
+ /*
+ var o = document.createElement('img');
+ o.style.marginRight = '5px';
+ o.src = self.vuMeterData[i][j];
+ document.documentElement.appendChild(o);
+ */
+ }
+ }
+ };
+
+ var vuDataCanvas = null;
+
+ this.testCanvas = function() {
+ // canvas + toDataURL();
+ var c = document.createElement('canvas');
+ var ctx = null;
+ if (!c || typeof c.getContext == 'undefined') {
+ return null;
+ }
+ ctx = c.getContext('2d');
+ if (!ctx || typeof c.toDataURL != 'function') {
+ return null;
+ }
+ // just in case..
+ try {
+ var ok = c.toDataURL('image/png');
+ } catch(e) {
+ // no canvas or no toDataURL()
+ return null;
+ }
+ // assume we're all good.
+ return c;
+ }
+
+ if (this.config.useFavIcon) {
+ vuDataCanvas = self.testCanvas();
+ if (vuDataCanvas && (isFirefox || isOpera)) {
+ // these browsers support dynamically-updating the favicon
+ self.createVUData();
+ } else {
+ // browser doesn't support doing this
+ this.config.useFavIcon = false;
+ }
+ }
+
+ this.init = function() {
+ sm._writeDebug('pagePlayer.init()');
+ var oLinks = document.getElementsByTagName('a');
+ // grab all links, look for .mp3
+ var foundItems = 0;
+ for (var i=0; i<oLinks.length; i++) {
+ if ((sm.canPlayLink(oLinks[i]) || self.hasClass(oLinks[i],'playable')) && !self.hasClass(oLinks[i],'exclude')) {
+ oLinks[i].rel = 'pagePlayerMP3Sound'+i;
+ self.links[self.links.length] = oLinks[i];
+ self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration
+ foundItems++;
+ }
+ }
+ if (foundItems>0) {
+ var oTiming = document.getElementById('sm2_timing');
+ self.strings['timing'] = oTiming.innerHTML;
+ oTiming.innerHTML = '';
+ oTiming.id = '';
+ self.addEventHandler(document,'click',self.handleClick);
+ if (!isTouchDevice) {
+ self.addEventHandler(document,'mousedown',self.handleMouseDown);
+ self.addEventHandler(document,'mouseup',self.stopDrag);
+ } else {
+ self.addEventHandler(document,'touchstart',self.handleMouseDown);
+ self.addEventHandler(document,'touchend',self.stopDrag);
+ }
+ // self.addEventHandler(window,'unload',function(){}); // force page reload when returning here via back button (Opera tries to remember old state, etc.)
+ }
+ sm._writeDebug('pagePlayer.init(): Found '+foundItems+' relevant items.');
+ if (self.config.autoStart) {
+ pl.handleClick({target:pl.links[0]});
+ }
+ }
+
+var Metadata = function(oSound) {
+ var self = this;
+ var oLI = oSound._data.oLI;
+ var o = oLI.getElementsByTagName('ul')[0];
+ var oItems = o.getElementsByTagName('li');
+ var oTemplate = document.createElement('div');
+ oTemplate.innerHTML = '<span> </span>';
+ oTemplate.className = 'annotation';
+ var oTemplate2 = document.createElement('div');
+ oTemplate2.innerHTML = '<span> </span>';
+ oTemplate2.className = 'annotation alt';
+
+ var oTemplate3 = document.createElement('div');
+ oTemplate3.className = 'note';
+
+ this.totalTime = 0;
+ this.strToTime = function(sTime) {
+ var segments = sTime.split(':');
+ var seconds = 0;
+ for (var i=segments.length; i--;) {
+ seconds += parseInt(segments[i])*Math.pow(60,segments.length-1-i,10); // hours, minutes
+ }
+ return seconds;
+ }
+ this.data = [];
+ this.data.givenDuration = null;
+ this.data.currentItem = null;
+ this.data.mainTitle = oSound._data.oLink.innerHTML;
+ for (var i=0; i<oItems.length; i++) {
+ this.data[i] = {
+ o: null,
+ title: oItems[i].getElementsByTagName('p')[0].innerHTML,
+ startTime: oItems[i].getElementsByTagName('span')[0].innerHTML,
+ startSeconds: self.strToTime(oItems[i].getElementsByTagName('span')[0].innerHTML.replace(/[()]/g,'')),
+ duration: 0,
+ durationMS: null,
+ startTimeMS: null,
+ endTimeMS: null,
+ oNote: null
+ }
+ }
+ var oDuration = pl.getElementsByClassName('duration','div',oLI);
+ this.data.givenDuration = (oDuration.length?self.strToTime(oDuration[0].innerHTML)*1000:0);
+ for (i=0; i<this.data.length; i++) {
+ 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;
+ this.data[i].startTimeMS = this.data[i].startSeconds*1000;
+ this.data[i].durationMS = this.data[i].duration*1000;
+ this.data[i].endTimeMS = this.data[i].startTimeMS+this.data[i].durationMS;
+ this.totalTime += this.data[i].duration;
+ }
+ // make stuff
+ this.createElements = function() {
+ var oFrag = document.createDocumentFragment();
+ var oNode = null;
+ var oNodeSpan = null;
+ var oNode2 = null;
+ for (var i=0; i<self.data.length; i++) {
+ oNode = (i%2==0?oTemplate:oTemplate2).cloneNode(true);
+ oNodeSpan = oNode.getElementsByTagName('span')[0];
+ oNode.rel = i;
+ self.data[i].o = oNode;
+ oNode2 = oTemplate3.cloneNode(true);
+ if (i%2==0) oNode2.className = 'note alt';
+ oNode2.innerHTML = this.data[i].title;
+ // evil old-skool event handlers, css:hover-only ideally would be nice excluding IE 6
+ oNode.onmouseover = self.mouseover;
+ oNode.onmouseout = self.mouseout;
+ this.data[i].oNote = oNode2;
+ oSound._data.oControls.appendChild(oNode2);
+ oFrag.appendChild(oNode);
+ }
+ self.refresh();
+ oSound._data.oStatus.appendChild(oFrag);
+ }
+
+ this.refresh = function() {
+ var offset = 0;
+ var relWidth = null;
+ var duration = (self.data.givenDuration?self.data.givenDuration:oSound.durationEstimate);
+ for (var i=0; i<self.data.length; i++) {
+ if (duration) {
+ relWidth = (((self.data[i].duration*1000)/duration)*100);
+ self.data[i].o.style.left = (offset?offset+'%':'-2px');
+ self.data[i].oNote.style.left = (offset?offset+'%':'0px');
+ offset += relWidth;
+ }
+ }
+ }
+
+ this.mouseover = function(e) {
+ self.data[this.rel].oNote.style.visibility = 'hidden';
+ self.data[this.rel].oNote.style.display = 'inline-block';
+ self.data[this.rel].oNote.style.marginLeft = -parseInt(self.data[this.rel].oNote.offsetWidth/2)+'px';
+ self.data[this.rel].oNote.style.visibility = 'visible';
+ }
+
+ this.mouseout = function() {
+ self.data[this.rel].oNote.style.display = 'none';
+ }
+
+ // ----
+
+ this.createElements();
+ this.refresh();
+
+} // MetaData();
+
+ this.initDOM = function() {
+ // set up graph box stuffs
+ var sb = self.getElementsByClassName('spectrum-box','div',document.documentElement)[0];
+ if (sm.flashVersion >= 9) {
+ var lists = self.getElementsByClassName('playlist','ul',document.documentElement);
+ for (var i=lists.length; i--;) {
+ self.addClass(lists[i],self.cssBase);
+ }
+ var sbC = sb.getElementsByTagName('div')[0];
+ var oF = document.createDocumentFragment();
+ var oClone = null;
+ for (i=256; i--;) {
+ oClone = sbC.cloneNode(false);
+ oClone.style.left = (i)+'px';
+ oF.appendChild(oClone);
+ }
+ sb.removeChild(sbC);
+ sb.appendChild(oF);
+ }
+ this.oControls = document.getElementById('control-template').cloneNode(true);
+ this.oControls.id = '';
+ this.init();
+ }
+
+}
+
+var pagePlayer = new PagePlayer(typeof PP_CONFIG != 'undefined'?PP_CONFIG:null);
+
+soundManager.onready(function() {
+ if (soundManager.supported()) {
+ // soundManager.createSound() etc. may now be called
+ pagePlayer.initDOM();
+ }
+});
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/basic.html new file mode 100755 index 0000000..2e0e623 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/basic.html @@ -0,0 +1,60 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 Links on a page</title>
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+</style>
+<link rel="stylesheet" type="text/css" href="css/inlineplayer.css" />
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/inlineplayer.js"></script>
+</head>
+
+<body>
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play a page of mp3s with javascript via SoundManager 2">SoundManager 2</a> / page as a playlist, basic template</h1>
+
+ <p>Don't forget to set debugMode = false within <em>inlineplayer.js</em> to disable debug output.</p>
+
+ <div id="sm2-container">
+ <!-- SM2 flash goes here -->
+ </div>
+
+ <ul class="graphic">
+
+ <li><a href="../jsAMP-preview/audio/rain.mp3">Rain</a></li>
+ <li><a href="../jsAMP-preview/audio/walking.mp3">Walking</a></li>
+ <li><a href="http://www.freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl (featureblend.com)</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></li>
+ <li><a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></li>
+ <li><a href="http://freshly-ground.com/data/video/Rain%20on%20Car%20Roof.aac">Rain On Car Roof (AAC Audio)</a></li>
+ </ul>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 project page">SoundManager 2 project home</a></p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/css/inlineplayer.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/css/inlineplayer.css new file mode 100755 index 0000000..1fa31c7 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/css/inlineplayer.css @@ -0,0 +1,212 @@ +/*
+
+ SoundManager 2: In-page MP3 player example
+ ------------------------------------------
+
+ Clicks on links to MP3s are intercepted via JS, calls are
+ made to SoundManager to load/play sounds. CSS classes are
+ appended to the link, which are used to highlight the
+ current play state and so on.
+
+ Class names are applied in addition to "sm2_link" base.
+
+ Default:
+
+ sm2_link
+
+ Additional states:
+
+ sm2_playing
+ sm2_paused
+
+ eg.
+
+ <!-- default -->
+ <a href="some.mp3" class="sm2_link">some.mp3</a>
+
+ <!-- playing -->
+ <a href="some.mp3" class="sm2_link sm2_playing">some.mp3</a>
+
+
+ Note you don't require ul.graphic / ul.flat etc. for your use
+ if only using one style on a page. You can just use .sm2_link{}
+ and so on, but isolate the CSS you want.
+
+ Side note: Would do multiple class definitions eg.
+
+ a.sm2_default.sm2_playing{}
+
+ .. except IE 6 has a parsing bug which may break behaviour,
+ applying sm2_playing {} even when the class is set to sm2_default.
+
+
+ If you want to make your own UI from scratch, here is the base:
+
+ Default + hover state, "click to play":
+
+ a.sm2_link {}
+ a.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ a.sm2_playing {}
+ a.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ a.sm2_paused {}
+ a.sm2_paused:hover {}
+
+
+*/
+
+/* two different list types */
+
+ul.flat {
+ list-style-type:none;
+ padding-left:0px;
+}
+
+ul.flat li,
+ul.graphic li {
+ padding-bottom:1px;
+}
+
+ul.flat li a {
+ display:inline-block;
+ padding:2px 4px 2px 4px;
+}
+
+ul.graphic {
+ list-style-type:none;
+ padding-left:0px;
+ margin-left:0px;
+}
+
+/* background-image-based CSS3 example */
+
+ul.graphic {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+}
+
+ul.graphic li {
+ margin-bottom:2px;
+}
+
+ul.graphic li a,
+ul.graphic li a.sm2_link {
+ /* assume all items will be sounds rather than wait for onload etc. in this example.. may differ for your uses. */
+ display:inline-block;
+ padding-left:22px;
+ min-height:16px;
+ vertical-align: middle;
+ background-color:#778899;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+ border-radius:3px;
+ padding:3px 3px 3px 25px;
+ min-width:19em;
+ _width:19em; /* IE 6 */
+ text-decoration:none;
+ font-weight:normal;
+ color:#f6f9ff;
+}
+
+ul.graphic li a.sm2_link {
+ /* safari 3.1+ fun (or, proprietary crap. TBD.) */
+ -webkit-transition-property: hover;
+ -webkit-transition: background-color 0.15s linear;
+ -moz-transition: background-color 0.15s linear 0s; /* firefox 4 */
+ -o-transition-property: background-color; /* opera 10.5 */
+ -o-transition-duration: 0.15s;
+}
+
+ul.graphic li a, /* use a.sm2_link {} if you want play icons showing only if SM2 is supported */
+ul.graphic li a.sm2_paused:hover,
+ul.graphic li a.sm2_link:hover {
+ background-image:url(../image/icon_play.png);
+ background-position:3px 50%;
+ background-repeat:no-repeat;
+ _background-image:url(../image/icon_play.gif); /* IE 6 */
+}
+
+ul.graphic li a.sm2_link:hover {
+ /* default hover color, if you'd like.. */
+ background-color:#445566;
+ color:#fff;
+}
+
+ul.graphic li a.sm2_paused {
+ background-color:#ccc;
+}
+
+ul.graphic li a.sm2_paused:hover {
+ background:#999 url(../image/icon_play.png) no-repeat 3px 50%;
+ _background-image:url(../image/icon_play.gif);
+}
+
+ul.graphic li a.sm2_playing,
+ul.graphic li a.sm2_playing:hover {
+ background:#334455 url(../image/icon_pause.png) no-repeat 3px 50%;
+ _background-image:url(../image/icon_pause.gif);
+ text-decoration:none;
+}
+
+/* hide button while playing?
+ul.graphic li a.sm2_playing {
+ background-image:none;
+}
+*/
+
+body #sm2-container object,
+body #sm2-container embed {
+ /*
+ flashblock handling: hide SWF off-screen by default (until blocked timeout case.)
+ include body prefix to ensure override of flashblock.css.
+ */
+
+ left:-9999em;
+ top:-9999em;
+}
+
+/* flat CSS example */
+
+ul.flat a.sm2_link {
+ /* default state: "a playable link" */
+ border-left:6px solid #999;
+ padding-left:4px;
+ padding-right:4px;
+}
+
+ul.flat a.sm2_link:hover {
+ /* default (inactive) hover state */
+ border-left-color:#333;
+}
+
+
+ul.flat a.sm2_playing {
+ /* "now playing" */
+ border-left-color:#6666ff;
+ background-color:#000;
+ color:#fff;
+ text-decoration:none;
+}
+
+ul.flat a.sm2_playing:hover {
+ /* "clicking will now pause" */
+ border-left-color:#cc3333;
+}
+
+ul.flat a.sm2_paused {
+ /* "paused state" */
+ background-color:#666;
+ color:#fff;
+ text-decoration:none;
+}
+
+ul.flat a.sm2_paused:hover {
+ /* "clicking will resume" */
+ border-left-color:#33cc33;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.gif Binary files differnew file mode 100755 index 0000000..7f3443d --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.png Binary files differnew file mode 100755 index 0000000..5775ce2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_pause.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.gif Binary files differnew file mode 100755 index 0000000..3954336 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.png Binary files differnew file mode 100755 index 0000000..303fc4b --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/icon_play.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/test.gif b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/test.gif Binary files differnew file mode 100755 index 0000000..075c135 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/image/test.gif diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/index.html new file mode 100755 index 0000000..040966a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/index.html @@ -0,0 +1,228 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 Links on a page</title> +<meta name="robots" content="noindex" />
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:2.5em arial,tahoma,verdana;
+ font-weight:normal;
+ margin-bottom:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+ margin-top:0.5em;
+}
+
+h2, h3 {
+ color:#333;
+}
+
+h2 {
+ font-size:2em;
+}
+
+h3 {
+ font-size:1.5em;
+}
+
+h1 a,
+h1 a:hover {
+ color:#000;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+ul.notes {
+ margin-left:0px;
+ padding-left:1.5em;
+}
+
+.note {
+ margin-top:0px;
+ font-style:italic;
+ color:#999;
+}
+
+pre {
+ font-size:1.2em;
+ _font-size:1em;
+}
+
+#left {
+ max-width:56em;
+}
+
+code {
+ font-size:120%;
+ line-height:1.5em;
+ color:#006600;
+ font-weight:bold;
+}
+
+p {
+ line-height:1.75em;
+}
+
+</style>
+<link rel="stylesheet" type="text/css" href="css/inlineplayer.css" />
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/inlineplayer.js"></script>
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play MP3s inline with javascript using SoundManager 2">SoundManager 2</a> / Make MP3 links play in-place</h1>
+
+ <h2>Inline MP3 Player Example: Fancy* CSS 3 version</h2>
+ <p class="note">*CSS 3 border-radius supported only by Firefox 2.x+, Safari (2.x?) - sadly, not IE 8.</p>
+
+ <div id="sm2-container">
+ <!-- SM2 flash goes here -->
+ </div>
+
+ <ul class="graphic">
+
+ <li><a href="../jsAMP-preview/audio/rain.mp3">Rain</a></li>
+ <li><a href="../jsAMP-preview/audio/walking.mp3">Walking</a></li>
+ <!-- files from the web (note that ID3 information will *not* load from remote domains without permission, Flash restriction) -->
+ <li><a href="http://www.freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl (featureblend.com)</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></li>
+ <li><a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></li>
+ <li><a href="http://freshly-ground.com/data/video/Rain%20on%20Car%20Roof.aac">Rain On Car Roof (AAC Audio)</a></li>
+ </ul>
+
+ <h2>How It Works</h2>
+
+ <ul class="notes">
+ <li>Lightweight (single JS click event handler)</li>
+ <li>Uses existing SoundManager 2 API</li>
+ <li>CSS for UI, easy to modify to taste</li>
+ </ul>
+
+ <p>This example uses <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 Javascript Sound API">SoundManager 2</a> to find links to MP3 files, and makes them playable "in-place" on a page. The script assigns CSS classes to links to indicate their state (playing/paused, etc.)</p>
+ <p>Links pointing to MP3s are assigned an onclick handler which intercepts the click (preventing the browser from following the link and unloading the page. SM2 will then create sound objects as needed to play the MP3s.</p>
+
+ <h3>Static Examples</h3>
+ <p style="margin-top:0px">CSS classes are dynamically applied as follows:</p>
+ <ul class="graphic">
+ <li><a href="#" class="sm2_link" title="'Click to play' state">Default: class="sm2_link"</a></li>
+ <li><a href="#" class="sm2_link sm2_playing" title="'Click to pause' state">Playing: class="sm2_link sm2_playing"</a></li>
+ <li><a href="#" class="sm2_link sm2_paused" title="'Click to resume' state">Paused: class="sm2_link sm2_paused"</a></li>
+ </ul>
+ <p>:hover effects are also active.</p>
+
+ <h2>Flat (CSS-only) style</h2>
+
+ <ul class="flat">
+
+ <li><a href="../jsAMP-preview/audio/going_outside.mp3">Going Outside</a></li>
+ <li><a href="../jsAMP-preview/audio/office_lobby.mp3">Office Lobby Entrance</a></li>
+
+ <!-- files from the web (note that ID3 information will *not* load from remote domains without permission, Flash restriction) -->
+
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Rain 3.mp3">Rain 3</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Frogs @ Yahoo!.mp3">Frogs @ Yahoo!</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Walking past sprinklers, mailbox.mp3">Walking past sprinklers, mailbox</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Cup of Coffee.mp3">Cup of Coffee</a></li>
+
+ </ul>
+
+ <h3>Static Examples</h3>
+
+ <ul class="flat">
+
+ <li><a href="#" class="sm2_link" title="'Click to play' state">Default: class="sm2_link"</a></li>
+ <li><a href="#" class="sm2_link sm2_playing" title="'Click to pause' state">Playing: class="sm2_link sm2_playing"</a></li>
+ <li><a href="#" class="sm2_link sm2_paused" title="'Click to resume' state">Paused: class="sm2_link sm2_paused"</a></li>
+
+ </ul>
+
+ <h3>Forcing play (or exclusion) of links</h3>
+
+ <p>If you have a link to a PHP file that serves MP3 files eg. /music.php?fileID=123, it won't be picked up by the script as containing a known, playable .mp3 extension. To tell the script it should be treated as playable, include a <code>type="audio/mpeg"</code> MIME type attribute, or CSS <code>class="inline-playable"</code> in the link. eg:</p>
+
+ <p>
+ <code><a href="/music.php?fileID=123" type="audio/mpeg">A song</a></code>
+ </p>
+
+ <p>Or via CSS class name:</p>
+ <code><a href="/music.php?fileID=123" class="inline-playable">A song</a></code>
+</p>
+
+ <p>
+ To exclude an .MP3 or otherwise-playable link from being handled by SM2, use <code>class="inline-exclude"</code> and it will be ignored.
+ </p>
+
+ <p>
+ <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
+ </p>
+
+ <h3>Basic CSS</h3>
+
+<pre>
+ If you want to make your own UI from scratch, here is the base:
+
+ Default + hover state, "click to play":
+
+ a.sm2_link {}
+ a.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ a.sm2_playing {}
+ a.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ a.sm2_paused {}
+ a.sm2_paused:hover {}
+</pre>
+
+ <h3>Other Options</h3>
+
+ <p>By default, one sound will be played at a time; you can easily change a "config" object value to turn on playlist-like behaviour (i.e., play the next MP3 when the current one finishes.)</p>
+
+<pre>
+// (within inlineplayer.js)
+this.config = {
+ playNext: false // stop after one sound, or play through list until end
+}
+</pre>
+
+ <h3>I'd like to use this.</h3>
+ <p>See this <a href="basic.html" title="basic template: inline mp3 player">basic demo</a> for reference.</p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/script/inlineplayer.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/script/inlineplayer.js new file mode 100755 index 0000000..2bd1a84 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/play-mp3-links/script/inlineplayer.js @@ -0,0 +1,246 @@ +/*
+
+ SoundManager 2 Demo: Play MP3 links "in-place"
+ ----------------------------------------------
+
+ http://schillmania.com/projects/soundmanager2/
+
+ A simple demo making MP3s playable "inline"
+ and easily styled/customizable via CSS.
+
+ Requires SoundManager 2 Javascript API.
+
+*/
+
+function InlinePlayer() {
+ var self = this;
+ var pl = this;
+ var sm = soundManager; // soundManager instance
+ this.playableClass = 'inline-playable'; // CSS class for forcing a link to be playable (eg. doesn't have .MP3 in it)
+ this.excludeClass = 'inline-exclude'; // CSS class for ignoring MP3 links
+ this.links = [];
+ this.sounds = [];
+ this.soundsByURL = [];
+ this.indexByURL = [];
+ this.lastSound = null;
+ this.soundCount = 0;
+ var isIE = (navigator.userAgent.match(/msie/i));
+
+ this.config = {
+ playNext: false, // stop after one sound, or play through list until end
+ autoPlay: false // start playing the first sound right away
+ }
+
+ this.css = {
+ // CSS class names appended to link during various states
+ sDefault: 'sm2_link', // default state
+ sLoading: 'sm2_loading',
+ sPlaying: 'sm2_playing',
+ sPaused: 'sm2_paused'
+ }
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.classContains = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?o.className.match(new RegExp('(\\s|^)'+cStr+'(\\s|$)')):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr || self.classContains(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr || !self.classContains(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getSoundByURL = function(sURL) {
+ return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null);
+ }
+
+ this.isChildOfNode = function(o,sNodeName) {
+ if (!o || !o.parentNode) {
+ return false;
+ }
+ sNodeName = sNodeName.toLowerCase();
+ do {
+ o = o.parentNode;
+ } while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName);
+ return (o.nodeName.toLowerCase() == sNodeName?o:null);
+ }
+
+ this.events = {
+
+ // handlers for sound events as they're started/stopped/played
+
+ play: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ stop: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = '';
+ },
+
+ pause: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPaused;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ resume: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLink,this._data.className);
+ },
+
+ finish: function() {
+ pl.removeClass(this._data.oLink,this._data.className);
+ this._data.className = '';
+ if (pl.config.playNext) {
+ var nextLink = (pl.indexByURL[this._data.oLink.href]+1);
+ if (nextLink<pl.links.length) {
+ pl.handleClick({'target':pl.links[nextLink]});
+ }
+ }
+ }
+
+ }
+
+ this.stopEvent = function(e) {
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.getTheDamnLink = (isIE)?function(e) {
+ // I really didn't want to have to do this.
+ return (e && e.target?e.target:window.event.srcElement);
+ }:function(e) {
+ return e.target;
+ }
+
+ this.handleClick = function(e) {
+ // a sound link was clicked
+ if (typeof e.button != 'undefined' && e.button>1) {
+ // ignore right-click
+ return true;
+ }
+ var o = self.getTheDamnLink(e);
+ if (o.nodeName.toLowerCase() != 'a') {
+ o = self.isChildOfNode(o,'a');
+ if (!o) return true;
+ }
+ var sURL = o.getAttribute('href');
+ if (!o.href || (!sm.canPlayLink(o) && !self.classContains(o,self.playableClass)) || self.classContains(o,self.excludeClass)) {
+ return true; // pass-thru for non-MP3/non-links
+ }
+ var soundURL = (o.href);
+ var thisSound = self.getSoundByURL(soundURL);
+ if (thisSound) {
+ // already exists
+ if (thisSound == self.lastSound) {
+ // and was playing (or paused)
+ thisSound.togglePause();
+ } else {
+ // different sound
+ thisSound.togglePause(); // start playing current
+ sm._writeDebug('sound different than last sound: '+self.lastSound.sID);
+ if (self.lastSound) self.stopSound(self.lastSound);
+ }
+ } else {
+ // create sound
+ thisSound = sm.createSound({
+ id:'inlineMP3Sound'+(self.soundCount++),
+ url:soundURL,
+ onplay:self.events.play,
+ onstop:self.events.stop,
+ onpause:self.events.pause,
+ onresume:self.events.resume,
+ onfinish:self.events.finish
+ });
+ // tack on some custom data
+ thisSound._data = {
+ oLink: o, // DOM node for reference within SM2 object event handlers
+ className: self.css.sPlaying
+ };
+ self.soundsByURL[soundURL] = thisSound;
+ self.sounds.push(thisSound);
+ if (self.lastSound) self.stopSound(self.lastSound);
+ thisSound.play();
+ // stop last sound
+ }
+
+ self.lastSound = thisSound; // reference for next call
+
+ if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else {
+ event.returnValue = false;
+ }
+ return false;
+ }
+
+ this.stopSound = function(oSound) {
+ soundManager.stop(oSound.sID);
+ soundManager.unload(oSound.sID);
+ }
+
+ this.init = function() {
+ sm._writeDebug('inlinePlayer.init()');
+ var oLinks = document.getElementsByTagName('a');
+ // grab all links, look for .mp3
+ var foundItems = 0;
+ for (var i=0, j=oLinks.length; i<j; i++) {
+ if ((sm.canPlayLink(oLinks[i]) || self.classContains(oLinks[i],self.playableClass)) && !self.classContains(oLinks[i],self.excludeClass)) {
+ self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration
+ self.links[foundItems] = (oLinks[i]);
+ self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
+ foundItems++;
+ }
+ }
+ if (foundItems>0) {
+ self.addEventHandler(document,'click',self.handleClick);
+ if (self.config.autoPlay) {
+ self.handleClick({target:self.links[0],preventDefault:function(){}});
+ }
+ }
+ sm._writeDebug('inlinePlayer.init(): Found '+foundItems+' relevant items.');
+ }
+
+ this.init();
+
+}
+
+var inlinePlayer = null;
+
+soundManager.debugMode = true; // disable or enable debug output
+soundManager.useFlashBlock = true;
+soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
+
+// optional: enable MPEG-4/AAC support (requires flash 9)
+
+soundManager.flashVersion = 9;
+soundManager.useMovieStar = true;
+
+// ----
+
+soundManager.onready(function() {
+ if (soundManager.supported()) {
+ // soundManager.createSound() etc. may now be called
+ inlinePlayer = new InlinePlayer();
+ }
+});
+
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/template/deferred-example.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/deferred-example.html new file mode 100755 index 0000000..2f33a55 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/deferred-example.html @@ -0,0 +1,127 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Deferred loading / Lazy-loading / Dynamic script loading Example</title>
+<meta name="description" content="How to load soundmanager2.js on-the-fly using JavaScript, and start it dynamically after window.load() has already fired using beginDelayedInit()." />
+<style type="text/css">
+#soundmanager-debug {
+ /* SM2 debug container (optional, use or customize this as you like - makes in-browser debug output more useable) */
+ position:fixed;_position:absolute;right:1em;bottom:1em;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:monaco,"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+</style>
+<!-- some CSS for this demo page, not required for SM2 -->
+<link rel="stylesheet" href="template.css" />
+
+<!-- SM2 BAREBONES TEMPLATE: START -->
+
+<script type="text/javascript">
+
+function loadScript(sURL,onLoad) {
+ try {
+ var loadScriptHandler = function() {
+ var rs = this.readyState;
+ if (rs == 'loaded' || rs == 'complete') {
+ this.onreadystatechange = null;
+ this.onload = null;
+ if (onLoad) {
+ onLoad();
+ }
+ }
+ }
+ function scriptOnload() {
+ this.onreadystatechange = null;
+ this.onload = null;
+ window.setTimeout(onLoad,20);
+ }
+ var oS = document.createElement('script');
+ oS.type = 'text/javascript';
+ if (onLoad) {
+ oS.onreadystatechange = loadScriptHandler;
+ oS.onload = scriptOnload;
+ }
+ oS.src = sURL;
+ document.getElementsByTagName('head')[0].appendChild(oS);
+ } catch(e) {
+ // oh well
+ }
+}
+
+function msg(s) {
+ document.getElementById('sm2-status').innerHTML = s;
+}
+
+window.onload = function() {
+ msg('Window loaded, waiting 1 second...');
+ setTimeout(function(){
+ msg('Loading soundmanager2.js...');
+ loadScript('../../script/soundmanager2.js',function(){
+ // SM2 script has loaded
+ soundManager.url = '../../swf/';
+ soundManager.onready(function() {
+ if (soundManager.supported()) {
+ soundManager.createSound({
+ id:'foo',
+ url:'../_mp3/mouseover.mp3'
+ }).play();
+ }
+ msg(soundManager.supported()?'started OK':'Loaded OK, but unable to start: unsupported/flash blocked, etc.');
+ });
+ soundManager.beginDelayedInit(); // ensure start-up in case document.readyState and/or DOMContentLoaded are unavailable
+ });
+ },1000);
+}
+
+</script>
+</head>
+
+<body style="height:100%">
+
+<div style="margin-right:43em">
+ <h1>SoundManager 2: Lazy Loading Example</h1>
+ <p>This is an example of dynamically loading SoundManager 2 using JS, after window.onload() has fired.</p>
+ <h2>How it works</h2>
+ <p>This page waits until window.onload(), delays 1 second and loads soundmanager2.js, which should then start up.</p>
+
+<p>SoundManager 2 status: <b id="sm2-status">Waiting for window.onload()...</b></p>
+
+<pre>window.onload = function() {
+ <span>// Window loaded, waiting 1 second...</span>
+ setTimeout(function() {
+ <span>// Loading soundmanager2.js...</span>
+ loadScript('../../script/soundmanager2.js',function() {
+ <span>// SM2 script has loaded</span>
+ soundManager.url = '../../swf/';
+ soundManager.onready(function() {
+ if (soundManager.supported()) {
+ soundManager.createSound({
+ id:'foo',
+ url:'../_mp3/mouseover.mp3'
+ }).play();
+ }
+ <span>// msg(soundManager.supported()?'started OK':'Loaded OK, but unable to start: unsupported/flash blocked, etc.');</span>
+ });
+ soundManager.beginDelayedInit(); <span>// ensure start-up in case document.readyState and/or DOMContentLoaded are unavailable</span>
+ });
+ },1000);
+}</pre>
+
+ <h2 id="flashblock-handling">Handling flash blockers</h2>
+ <p>It's good to let users see the flash component of SM2, so those with flash blockers can unblock it and allow SM2 to start. For more info on this, see the <a href="../flashblock/" title="SoundManager 2 with Flash block handling" onclick="if (!document.domain) this.href=this.href+'index.html'">Flashblock</a> example.</p>
+
+ <h2>Making SM2 wait for window.onload()</h2>
+ <p>If you prefer to have the library wait for window.onload() before calling soundManager.onload()/onerror() methods, you can modify SM2's "waitForWindowLoad" property:</p>
+<code>soundManager.waitForWindowLoad = true;</code>
+ <h2 style="margin-top:1em">Disabling debug output</h2>
+ <p>SoundManager 2 will write to a debug <div> element or a javascript console if available, by default. To disable it, simply set the relevant property to false:</p>
+<code>soundManager.debugMode = false;</code>
+ <p>To see related configuration code, refer to the source of this page which basically does all of the above "for real."</p>
+ <h2>Troubleshooting</h2>
+ <p>If SM2 is failing to start and throwing errors due to flash security, timeouts or other issues, check out the <a href="../../doc/getstarted/#troubleshooting" title="SoundManager 2 troubleshooting tool" onclick="if (!document.domain) this.href=this.href.replace(/\#/,'index.html#')">troubleshooting tool</a> which can help you fix things.</p>
+ <h2>No-debug, compressed version of soundmanager2.js</h2>
+ <p>Once development is finished, you can also use the "minified" (60% smaller) version of SM2, which has debug output and comments removed for you: <a href="../../script/soundmanager2-nodebug-jsmin.js">soundmanager2-nodebug-jsmin.js</a>. If you can, serve this with gzip compression for even greater bandwidth savings!</p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/template/html5-dtd-test.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/html5-dtd-test.html new file mode 100755 index 0000000..4d1b102 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/html5-dtd-test.html @@ -0,0 +1,77 @@ +<!DOCTYPE html>
+<html>
+<head>
+<title>SoundManager 2: HTML 5 DTD test</title>
+<meta name="description" content="A test page using SoundManager 2 under an HTML 5 DOCTYPE." />
+<script>
+
+// -- Movie size/positioning test case, Firefox/Win32 --
+
+// SM2 normally works at 6x6px SWF size, position:fixed bottom/left:0px.
+// Was failing with this case using HTML 5 doctype? ..
+// Started working when 8x8px SWF size was used.
+
+// Previous notes, courtesy Jacob Seidelin ...
+
+// This fails to load in Firefox 3.6 (Win7) but will load after one of the following changes:
+// 1. Remove the doctype or set it to eg.
+// <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+// 2. Set soundManager.useHighPerformance = false
+// 3. Set soundManager.debugFlash = true
+
+function loadScript(sURL,onLoad) {
+ try {
+ var loadScriptHandler = function() {
+ var rs = this.readyState;
+ if (rs == 'loaded' || rs == 'complete') {
+ this.onreadystatechange = null;
+ this.onload = null;
+ if (onLoad) {
+ onLoad();
+ }
+ }
+ }
+ function scriptOnload() {
+ this.onreadystatechange = null;
+ this.onload = null;
+ window.setTimeout(onLoad,20);
+ }
+ var oS = document.createElement('script');
+ oS.type = 'text/javascript';
+ if (onLoad) {
+ oS.onreadystatechange = loadScriptHandler;
+ oS.onload = scriptOnload;
+ }
+ oS.src = sURL;
+ document.getElementsByTagName('head')[0].appendChild(oS);
+ } catch(e) {
+ // oh well
+ }
+}
+
+window.onload = function() {
+ loadScript('../../script/soundmanager2.js', function() {
+ soundManager.flashVersion = 9;
+ soundManager.flash9Options.useEQData = true;
+ soundManager.flash9Options.useWaveformData = true;
+ soundManager.allowPolling = true;
+ soundManager.url = '../../swf/'; // path to directory containing SoundManager2 .SWF file
+ soundManager.onload = function() {
+ alert('Loaded!');
+ };
+ soundManager.debugMode = true;
+ soundManager.useHighPerformance = true;
+ soundManager.debugFlash = false;
+ soundManager.beginDelayedInit(); // ensure things start, in case document.readyState / domReady are missed (eg. Firefox 3.5.5/win32 with HTML5 DTD, no document.readyState??)
+ });
+}
+
+</script>
+
+</head>
+
+<body>
+
+</body>
+</html>
+
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/template/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/index.html new file mode 100755 index 0000000..214342c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/index.html @@ -0,0 +1,131 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Template</title>
+<style type="text/css">
+#soundmanager-debug {
+ /* SM2 debug container (optional, use or customize this as you like - makes in-browser debug output more useable) */
+ position:fixed;_position:absolute;right:1em;bottom:1em;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:monaco,"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+</style>
+<!-- some CSS for this demo page, not required for SM2 -->
+<link rel="stylesheet" href="template.css" />
+
+
+<!-- SM2 BAREBONES TEMPLATE: START -->
+
+<!-- include SM2 library -->
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+
+<!-- And now, customize it! -->
+<script type="text/javascript">
+
+// soundManager.debugMode = false; // disable debug output
+soundManager.url = '../../swf/'; // path to directory containing SoundManager2 .SWF file
+soundManager.flashVersion = 8;
+soundManager.useFlashBlock = false; // skip for now. See the flashblock demo when you want to start getting fancy.
+
+soundManager.onload = function() {
+ // soundManager.createSound() etc. may now be called
+ soundManager._writeDebug('soundManager.onload() - your code executes here');
+}
+
+</script>
+
+<!-- SM2 BAREBONES TEMPLATE: END -->
+
+
+
+</head>
+
+<body style="height:100%">
+
+<div style="margin-right:43em">
+ <h1>SoundManager 2 Template Example</h1>
+ <p>This is a basic template for adding SoundManager to your page.</p>
+ <h2>How it works</h2>
+ <p>This page includes the SM2 script, which starts up on its own as appropriate. By default it will try to start as soon as possible.</p>
+ <p>The minimal code needed to get SoundManager 2 going is below, with <em><em>configurable parts</em></em>:</p>
+<code>
+<pre>
+
+<span><!-- include SM2 library --></span>
+<script type="text/javascript" src="<em><em>/path/to/soundmanager2.js</em></em>"></script>
+
+<span><!-- configure it for your use --></span>
+<script type="text/javascript">
+
+soundManager.url = '<em><em>/path/to/sm2-flash-movies/</em></em>'; <span>// directory where SM2 .SWFs live</span>
+
+<span>// Note that SoundManager will determine and append the appropriate .SWF file to the URL,
+// eg. /path/to/sm2-flash-movies/soundmanager2.swf automatically.</span>
+
+<span>// Beta-ish HTML5 audio support (force-enabled for iPad), flash-free sound for Safari + Chrome. Enable if you want to try it!</span>
+<span>// soundManager.useHTML5Audio = true;</span>
+
+<span>// do this to skip flash block handling for now. See the <a href="../flashblock/" title="SoundManager 2 flashblock handling demo" onclick="if (!document.domain) this.href=this.href+'index.html'">flashblock demo</a> when you want to start getting fancy.</span>
+soundManager.useFlashBlock = false;
+
+<span>// disable debug mode after development/testing..</span>
+<span>// soundManager.debugMode = false;</span>
+
+<span style="background:#eee;padding:0.25em">// Option 1: Simple onload() + createSound() method</span>
+
+soundManager.onload = function() {
+ <span>// SM2 has loaded - now you can create and play sounds!</span>
+ <em><em>soundManager.createSound('helloWorld','/path/to/hello-world.mp3');
+ soundManager.play('helloWorld');</em></em>
+};
+
+<span style="background:#eee;padding:0.25em">// Option 2 (better): More flexible onload() + createSound() method</span>
+
+soundManager.onload = function() {
+ <em><em>var mySound = soundManager.createSound({
+ id: 'aSound',
+ url: '/path/to/an.mp3'
+ <span>// onload: <span>[ event handler function object ],</span></span>
+ <span>// other options here..</span>
+ });
+ mySound.play();
+</em></em>}
+
+<span style="background:#eee;padding:0.25em">// Option 3 (best): onready() + createSound() methods, handle load/failure together:</span>
+
+soundManager.onready(function() {
+ <span>// check if SM2 successfully loaded..</span>
+ <em><em>if (soundManager.supported()) {</em></em>
+ <span>// SM2 has loaded - now you can create and play sounds!</span>
+ <em><em>var mySound = soundManager.createSound({
+ id: 'aSound',
+ url: '/path/to/an.mp3'
+ <span>// onload: <span>[ event handler function object ],</span></span>
+ <span>// other options here..</span>
+ });
+ mySound.play();
+ } else {
+ <span>// (Optional) Hrmm, SM2 could not start. Show an error, etc.?</span>
+ }</em></em>
+});
+
+</script></pre></code>
+
+ <h2 id="flashblock-handling">Handling flash blockers</h2>
+ <p>It's good to let users see the flash component of SM2, so those with flash blockers can unblock it and allow SM2 to start. For more info on this, see the <a href="../flashblock/" title="SoundManager 2 with Flash block handling" onclick="if (!document.domain) this.href=this.href+'index.html'">Flashblock</a> example.</p>
+
+ <h2>Making SM2 wait for window.onload()</h2>
+ <p>If you prefer to have the library wait for window.onload() before calling soundManager.onload()/onerror() methods, you can modify SM2's "waitForWindowLoad" property:</p>
+<code>soundManager.waitForWindowLoad = true;</code>
+ <h2 style="margin-top:1em">Disabling debug output</h2>
+ <p>SoundManager 2 will write to a debug <div> element or a javascript console if available, by default. To disable it, simply set the relevant property to false:</p>
+<code>soundManager.debugMode = false;</code>
+ <p>To see related configuration code, refer to the source of this page which basically does all of the above "for real."</p>
+ <h2>Troubleshooting</h2>
+ <p>If SM2 is failing to start and throwing errors due to flash security, timeouts or other issues, check out the <a href="../../doc/getstarted/#troubleshooting" title="SoundManager 2 troubleshooting tool" onclick="if (!document.domain) this.href=this.href.replace(/\#/,'index.html#')">troubleshooting tool</a> which can help you fix things.</p>
+ <h2>No-debug, compressed version of soundmanager2.js</h2>
+ <p>Once development is finished, you can also use the "minified" (down to 10% of original size with gzip!) version of SM2, which has debug output and comments removed for you: <a href="../../script/soundmanager2-nodebug-jsmin.js">soundmanager2-nodebug-jsmin.js</a>. Serve with gzip compression wherever possible for best bandwidth savings.</p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/template/template.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/template.css new file mode 100755 index 0000000..448853e --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/template.css @@ -0,0 +1,67 @@ +/*
+
+ DEMO ONLY, just to make the demo page pretty.
+
+ You don't need this stuff for SM2 to work. :)
+
+*/
+
+body {
+ font-size:75%;
+}
+
+code, pre {
+ font-family:"lucida console",monaco,courier,terminal,system;
+ font-size:100%;
+ color:#2233cc;
+}
+
+em em {
+ font-weight:normal;
+ font-style:normal;
+ color:#339933;
+}
+
+h1,
+h2.special {
+ letter-spacing:-1px;
+}
+
+h1, h2, h3, h4 {
+ font-family:"helvetica neue",helvetica,verdana,arial,tahoma,"sans serif";
+ font-size:1em;
+ margin:0px;
+ padding:0px;
+ vertical-align:middle;
+}
+
+h1 {
+ font-size:2em;
+}
+
+h2 {
+ font-family:helvetica,arial,verdana,tahoma,"sans serif";
+ font-size:1.5em;
+}
+
+h3 {
+ font-size:1.17em;
+ border-bottom:1px solid #ccc;
+ padding-bottom:0.25em;
+ margin-top:1.5em;
+}
+
+h4 {
+ margin:1.5em 0px 0.5em 0px;
+ font-size:1.1em;
+}
+
+
+p {
+ font:normal 1em verdana,tahoma,arial,"sans serif";
+}
+
+code span,
+pre span {
+ color:#666;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/template/xhtml-test.xhtml b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/xhtml-test.xhtml new file mode 100755 index 0000000..a77db8f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/template/xhtml-test.xhtml @@ -0,0 +1,86 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Template</title>
+<style type="text/css">
+#soundmanager-debug {
+ /* SM2 debug container (optional, use or customize this as you like - makes in-browser debug output more useable) */
+ position:fixed;_position:absolute;right:1em;bottom:1em;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:monaco,"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
+}
+</style>
+<!-- some CSS for this demo page, not required for SM2 -->
+<link rel="stylesheet" href="template.css" />
+
+
+
+<!-- SM2 BAREBONES TEMPLATE: START -->
+
+<!-- include SM2 library -->
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+
+<!-- And now, customize it! -->
+<script type="text/javascript">
+
+// soundManager.debugMode = false; // disable debug output
+
+soundManager.url = '../../swf/'; // path to directory containing SoundManager2 .SWF file
+
+soundManager.onload = function() {
+ // soundManager.createSound() etc. may now be called
+ soundManager._writeDebug('soundManager.onload() - your code executes here');
+}
+
+</script>
+
+<!-- SM2 BAREBONES TEMPLATE: END -->
+
+
+
+</head>
+
+<body>
+<div style="margin-right:43em">
+ <h1>SoundManager 2 Template Example</h1>
+ <p>This is a basic template for adding SoundManager to your page.</p>
+ <h2>How it works</h2>
+ <p>This page includes the SM2 script, which starts up on its own as appropriate. By default it will try to start as soon as possible.</p>
+ <p>The minimal code needed to get SoundManager 2 going is below, with <em><em>configurable parts</em></em>:</p>
+<code>
+<pre>
+
+<span><-- include SM2 library --></span>
+<script type="text/javascript" src="<em><em>/path/to/soundmanager2.js</em></em>"></script>
+
+<span><-- configure it for your use --></span>
+<script type="text/javascript">
+
+soundManager.url = '<em><em>/path/to/sm2-flash-movies/</em></em>'; <span>// directory where SM2 .SWFs live</span>
+
+<span>// Note that SounndManager will determine and append the appropriate .SWF file to the URL.</span>
+
+<span>// disable debug mode after development/testing..
+// soundManager.debugMode = false;</span>
+
+soundManager.onload = function() {
+ <span>// SM2 has loaded - now you can create and play sounds!</span>
+ <em><em>soundManager.createSound('helloWorld','/path/to/hello-world.mp3');
+ soundManager.play('helloWorld');</em></em>
+}
+
+</script></pre></code>
+
+ <h2>Making SM2 wait for window.onload()</h2>
+ <p>If you prefer to have the library wait for window.onload() before calling soundManager.onload()/onerror() methods, you can modify SM2's "waitForWindowLoad" property:</p>
+<code>soundManager.waitForWindowLoad = true;</code>
+ <h2>Disabling debug output</h2>
+ <p>SoundManager 2 will write to a debug <div> element or a javascript console if available, by default. To disable it, simply set the relevant property to false:</p>
+<code>soundManager.debugMode = false;</code>
+ <p>To see related configuration code, refer to the source of this page which basically does all of the above "for real."</p>
+ <h2>No-debug, compressed version of soundmanager2.js</h2>
+ <p>Once development is finished, you can also use the "minified" (60% smaller) version of SM2, which has debug output and comments removed for you: <a href="../../script/soundmanager2-nodebug-jsmin.js">soundmanager2-nodebug-jsmin.js</a>. If you can, serve this with gzip compression for even greater bandwidth savings!</p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/doc/download/index.html b/docs/dymaxion/soundmanagerv297a-20101010/doc/download/index.html new file mode 100755 index 0000000..67a6b14 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/doc/download/index.html @@ -0,0 +1,1041 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Download</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Get the latest version of SoundManager 2 (BSD licensed.)" />
+<meta name="keywords" content="download, javascript sound, javascript audio api" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../../demo/index.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="../../demo/index.js"></script>
+<script type="text/javascript">
+ soundManager.handleFlashBlock = false;
+ soundManager.debugMode = false;
+ soundManager.url = '../../swf/';
+ soundManager.onload = function() {
+ }
+</script>
+</head>
+
+<body>
+
+<div id="content">
+
+ <div id="top">
+
+ <h1>SoundManager 2: Download</h1>
+
+ <div id="nav">
+ <ul>
+
+ <li>
+ <a href="../../">Home</a>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="../../demo/api/">API Examples</a></li>
+ <li><a href="../../demo/play-mp3-links/" class="exclude">Playable MP3 links</a></li>
+ <li><a href="../../demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="../../demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="../../demo/360-player/">360° Player UI</a></li>
+ <li><a href="../../demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="../../demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="../../demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="../../demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../getstarted/">Getting Started</a>
+ <ul>
+ <li><a href="../getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="../getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="../getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="..">Documentation</a>
+ <ul>
+ <li><a href="../#sm-config">SoundManager Properties</a></li>
+ <li><a href="../#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="../#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="../#api">SoundManager Core API</a></li>
+ <li><a href="../#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <strong><a href="#">Download</a></strong>
+ <ul>
+ <li><a href="#latest">Get SoundManager 2</a></li>
+ <li><a href="#revision-history">Revision History</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../technotes/">Technical Notes</a>
+ <ul>
+ <li><a href="../technotes/#requirements">System Requirements</a></li>
+ <li><a href="../technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../resources/">Resources</a>
+ <ul>
+ <li><a href="../resources/#licensing">Licensing</a></li>
+ <li><a href="../resources/#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+
+ <div id="filter-box" class="columnar">
+
+ <div class="c1">
+ <div id="reset-filter"></div>
+ </div>
+
+ <div class="c2">
+ <div id="search-results"><!-- search results for %s --></div>
+ </div>
+
+ </div>
+
+ <div id="newest" class="columnar">
+
+ <div class="c1">
+ <h2>Get SoundManager 2</h2>
+ <p>Get the latest and greatest.</p>
+ </div>
+
+ <div class="c2">
+ <h3>Download SoundManager 2</h3>
+ <p>Code cleanup (full debug codebase ~5% lighter), HTML5 audio tweaks, merged RTMP fork from GitHub, experimental video feature <i>removed</i>, optional crossdomain.xml feature. See <a href="#history">revision history</a> for details.</p>
+
+ <p style="padding-top:0.5em"><a href="../../download/soundmanagerv297a-20101010.zip" title="Download SoundManager 2" class="norewrite feature">Download SoundManager 2.97a.20101010</a></p>
+ <p style="padding-top:0.5em">Also on Github (dev branches, forks etc.): <a href="http://github.com/scottschiller/SoundManager2">http://github.com/scottschiller/SoundManager2</a></p>
+ <p><b>Performance tip:</b> SM2's code size varies from 90 KB (debug) down to 10 KB (optimized) over HTTP; check the <a href="../getstarted/#basic-inclusion" title="Including SoundManager 2 on your site: Script build options">pre-optimized builds</a> for details.</p>
+ </div>
+
+ </div>
+
+
+ <div id="history" class="columnar">
+
+ <div class="c1">
+ <h2>Revision History</h2>
+ <p>Latest changes and archived notes from bug fixes, API updates, feature development etc.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block c-revision-history">
+
+ <h3 id="revision-history">Revision History</h3>
+
+ <p>A changelog of sorts.</p>
+
+ <ul id="revision-list" class="standard">
+
+ <li class="in">
+ <h3><b>V2.97a.20101010</b> - Code cleanup, HTML5 audio tweaks, merged RTMP fork, removal of experimental video, optional usePolicyFile crossdomain.xml feature</h3>
+ <p>Shuffling of SoundManager 2 core, approximately 5% shaved off full debug-enabled file size after bug fixes, additional comments, new features and so on. Internal event handling code cleaned up. .SWF builds optimized, Flash 9 non-debug version now under 10 KB. Debug version now flash debugger-enabled. Merged GitHub user kjvarga's RTMP fork including improvements for Red5 + Flash Media Server streaming cases - buffering, event and state handling. Experimental video feature is toast, createVideo() no longer implemented. iPhone + iPad touch events on page player + 360° player UI demos; tap and drag to seek, etc.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>No HTML5 audio for *any* Safari on OS X Snow Leopard 10.6.[3|4] due to underlying bugs causing intermittent audio playback failure; ongoing Apple issue, on their radar. (See <a href="http://github.com/scottschiller/SoundManager2/commit/707697685408ef4aafd23811eeaa61a2d2ec120a">related GitHub commit</a>)</li>
+ <li>Don't <code>unload()</code> at <code>onfinish()</code> for HTML5 audio (was originally done to be conservative, but results in additional HTTP requests despite caching expectations?)</li>
+ <li><code>onload()</code> for HTML5 now using proper boolean values</li>
+ <li>Fix NetStream-specific <code>autoLoad</code>/<code>autoPlay</code>/<code>volume</code> <code>createSound()</code> call, specific null flash sound object error scenario. (Related <a href="http://github.com/scottschiller/SoundManager2/commit/0867fd641e83fda4e99665567a62f3398651fac4">changes on GitHub</a>.)</li>
+ <li>Fix for "<code>onbufferchange(1)</code> followed immediately by <code>onbufferchange(0)</code>" case when audio was actually still buffering.</li>
+ <li>Removed <code>setPosition()</code> within <code>unload()</code>, cleaner exit when destroying a sound</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">Merged: RTMP Fork</p>
+ <ul class="nested compact flat">
+ <li>Merged GitHub user kjvarga's <a href="http://github.com/kjvarga/SoundManager2/">RTMP fork of SoundManager 2</a>, including buffering, event and state handling fixes and improvements. For more RTMP documentation/features, see the readme on GitHub, or <a href="../../README.rdoc" class="norewrite">view locally</a>.</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li><b>Removed</b> experimental video feature (originally added late 2008, never developed further.) <code>createVideo()</code>, <code>allowFullScreen</code> and related video methods are now gone. Other dedicated HTML5/flash video player projects have since solved this problem.</li>
+ <li>New SMSound option: <a href="../#smsound-usepolicyfile" title="SoundManager sound option: usePolicyFile">usePolicyFile</a> - (boolean, default: <code>false</code>) - enables Flash to request /crossdomain.xml file for content on third-party domains, if access to ID3/metadata such as wave/peak/spectrum is needed. Will automagically enable if <code>onid3()</code> or peak/wave/spectrum features are being used.</li>
+ <li><code>console.warn()</code>-style messaging (instead of throwing exceptions) if <code>createSound()</code> etc. are called before SM2 init has fired. Now calls similar warning and exits if called after a failed, unsuccessful startup (ie., timeout or not-supported case.)</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>SoundManager 2 core code cleanup, ~5% shaved off soundmanager2.js code size after new features, bug fixes and comments etc. Internal event handling (DOM-related events for init, IE 6 vs. everybody else) improved.</li>
+ <li>Flash builds optimized; Flash 9 SWF build now under 10 KB. Debug-enabled Flash 9 SWF now hooks into Flash debug player/IDE debugging tools (compiled with <code>-debug=true</code>)</li>
+ <li>Attempt to detect RTL documents, position Flash accordingly if so to avoid long horizontal scrollbar issue (<a href="http://getsatisfaction.com/schillmania/topics/rtl_window_scroll_bar_issues_with_container_position" rel="nofollow">related discussion</a>)</li>
+ <li>iPhone + iPad <code>touchmove()</code> and related events added to page player + 360° player UI demos; tap and drag to seek should now work.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+
+ <li class="in">
+ <h3><b>V2.96a.20100822</b> - HTML5 audio support no longer alpha, Safari 5.0.1/SL HTML5 audio issues continue, iPad/iPhone "play through", Flash tweak for Android (<a href="../../download/soundmanagerv296a-20100822.zip">Download archived version</a>)</h3>
+ <p><code>useHTML5Audio</code> feature now considered beta-worthy, though disabled by default to be safe (with the exception of iPhone + iPad.) iPhone/iPad will now play a sequence of sounds, user interaction only required to start first one. Flash on-screen positioning tweak for Android devices that run Flash. Safari 5.0.1 on Snow Leopard exhibits same buggy HTML5 audio issue, disabled by default; Apple have been notified. IE 9 "Platform Preview 4" has <code><audio></code> but no <code>Audio()</code> support (yet?) See <a href="https://connect.microsoft.com/IE/feedback/details/586311/audio-but-no-audio-support">bug #586311</a> (may require connect.microsoft.com / Windows Live ID, login first etc.)</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>HTML5 <code>Audio()</code> still broken in Safari 5.0.1 on Snow Leopard (10.6.3, 10.6.4), where sounds intermittently fail to load and play. Apple are aware of the regression. Related bug: <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c14">#32519</a>. Include <code>sm2-ignorebadua</code> in URL on SM2 pages to ignore this check and verify broken behaviour, etc.</li>
+ <li>Tweaks for experimental RTMP feature re: handling of paused state, tracking of position and <code>onfinish()</code> firing early.</li>
+ <li>Bumped SWF z-index to 5000 for Safari 5, SoundCloud-reported bug-and-fix for Safari 5-specific bad redraw issues, and occasional crash case referencing WebCore::RenderLayer::paintLayer</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>iPhone/iOS 4 and iPad can now play a sequence of sounds (once the user starts sound initially), provided <code>onfinish()</code> is used to create/play the next sound. Example: Muxtape-style UI on homepage will play through list without further interaction once a user plays something in the list.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Special case for getting SM2 working more reliably on HTC Android + Flash 10.1, where flash does not load until on-screen (ie., in view.) If off-screen, Flash is repositioned at left/top 0px in order to load (including scroll/resize if needed), then events released and movie is repositioned off-screen. If movie is in the DOM already eg. as in <code>useFlashBlock</code> cases, <code>flashLoadTimeout</code> is set to 0 to allow infinite wait (eg., SM2 will not timeout with an error, and will simply load when the flash is scrolled into view.)</li>
+ <li>Documentation: Clarified <code>createSound()</code> behaviour if an existing sound ID is given (returns sound object "as-is", ignores any options passed.)</li>
+ <li>Page-player demo updated to use <code>canPlayLink()</code> instead of <code>canPlayURL</code>, more flexible link/type handling.</li>
+ <li>Homepage and documentation UI/layout and language tweaks, a few new "as seen on the internets" icons etc.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.96a.20100624</b> - Safari 5/Snow Leopard 10.6.3/10.6.4 HTML5 Audio() issue, X-domain SWF build fixes (<a href="../../download/soundmanagerv296a-20100624.zip">Download archived version</a>)</h3>
+
+ <p>Disabling HTML5 Audio for Safari 5 on Snow Leopard 10.6.3 + 10.6.4 (current release) only, as it is broken similar to Safari 4.x (also on Snow Leopard only.) Related bug: <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c14">#32519</a>. Also, version info in SWFs and fixed X-domain SWF build.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>HTML5 Audio() still broken in Safari 5 on Snow Leopard (10.6.3, 10.6.4) - disabling for now, falling back to Flash as with Safari 4.x on Snow Leopard. Include <code>sm2-ignorebadua</code> in URL to ignore this check and verify broken behaviour, etc.</li>
+ <li>Fixed X-domain SWF builds to actually work cross-domain.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Added version info string to SWFs in Flash right-click / context menu, helpful when troubleshooting SWFs.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.96a.20100606</b> - RTMP (Flash Media Server) Support, HTML5 Updates (<a href="../../download/soundmanagerv295b-20100606.zip">Download archived version</a>)</h3>
+
+ <p>HTML5 update, new RTMP feature: Experimental Flash Media Server support, <code>onposition()</code> event listener, SMSound <code>type</code> option and code cleanup.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New experimental <a href="../#smsound-serverurl" title="SMSound serverURL property">RTMP support</a> via kjvarga's fork at <a href="http://github.com/kjvarga/SoundManager2/">http://github.com/kjvarga/SoundManager2/</a> while maintaining existing NetStream-based behaviour for non-RTMP MPEG4 audio, etc. Uses new <code>serverURL</code> parameter for FMS (I used Red5 for dev/testing,) eg. <code>soundManager.createSound({id:'rtmpTest',serverURL:'rtmp://localhost/oflaDemo',url:'oh-alberta.mp3'}).play();</code></li>
+ <li>New SMSound option for createSound(), load(), play(): '<a href="../#smsound-type" title="SMSound type option">type</a>', for specifying MIME type alongside URL to help with detecting playability. eg.
+<code>soundManager.createSound({id:'foo', url:'/player.php?stream=1', type:'audio/mp3'}).play();</code> and so on. Hat tip: <a href="http://sylvinus.org">sylvinus.org</a></li>
+ <li>New SMSound event: <a href="../#smsound-onposition" title="SMSound onposition() event">onposition()</a>, for attaching listeners to specific times within a sound.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>Flash sound unload/destroy ActionScript "could not close stream" exception/warning (finally?) fixed.</li>
+ <li>Sound looping updated for Flash 8, working (albeit with a quirk - requires preloading.)</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Removed Base64 HTML5 Audio() tests, redundant as numerous MIME (audio/mpeg, audio/mp3 etc.) checks seem to cover it.</li>
+ <li>Updated MPC (drum machine) demo from 2006-era design, modernizing the CSS a bit.</li>
+ <li><code>nullURL = 'about:blank'</code> tweak for unloading (flash 8.) May have finally fixed that dumb stream closing error on unload/destroy.</li>
+ <li>set <code>soundManager.didFlashBlock</code> *before* firing <code>onready()</code>/<code>onerror()</code> listeners</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.96a.20100520</b> - HTML5 Edition (<a href="../../download/soundmanagerv295b-20100520.zip">Download archived version</a>)</h3>
+
+ <p>Experimental HTML5 support, lots of code shuffling and performance tweaks.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New <a href="../#soundmanager-usehtml5audio" title="SoundManager: useHTML5Audio feature">soundManager.useHTML5Audio</a> (disabled by default except for iPad, Palm Pre) - adds experimental HTML5 Audio support, with Flash fallback for MP3/MP4 formats as needed.</li>
+ <li>Sound looping now works in Flash! eg. <code>mySound.play({loops:3});</code> - for an example + discussion of how to get near-seamless looping, see <a href="http://www.flickr.com/photos/schill/4499319436/" title="SoundManager 2: Seamless Looping MP3s in Flash (Demo)">Seamless Looping MP3s in Flash</a> (demo video) on Flickr.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li><code>beginDelayedInit()</code> is always used in lazy loading case (eg. via dynamic script tag/XHR etc.,) as some cases where SM2 won't auto-start eg. document.readyState empty for Firefox 3.5.5 (seen on Win32) with an HTML5 DOCTYPE.</li>
+ <li>SWF is now 8x8 pixels by default, vs. 6x6 pixels (odd fix for HTML5 Doctype on Firefox 3.6/win32)</li>
+ <li>Fixed dumb IE undefined ID bug</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>soundmanager2.swf and soundmanager2_flash9.swf are now "non-debug" versions; with debugMode enabled, soundmanager2_debug.swf and soundmanager2_flash9_debug.swf are loaded instead.</li>
+ <li>New build script for JS + SWFs, see <a href="../getstarted/#basic-inclusion" title="Including SoundManager 2, file size options">file size table</a>. JS compression now done via Google Closure compiler; new soundmanager-jsmin.js build, debug-enabled but compressed, in addition to build-script-optimized, no-debug, compressed JS (~9 KB with gzip vs. ~90 KB for raw, commented, debug-enabled version.)</li>
+ <li>Null check fix for unavailable eq/waveform data</li>
+ <li>Experimental video (flash 9-only) change: Use stage width/height instead of 0/0 when lacking metadata</li>
+ <li>Page player whileloading() calls now being throttled</li>
+ <li>Better page player click handling for IE 7</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.95b.20100323</b> (<a href="../../download/soundmanagerv295b-20100323.zip">Download archived version</a>)</h3>
+ <p><code>useFlashBlock</code>, better handling of time-out/errors (CSS-based SWF repositioning options for unblocking on time-out), "play MP3 button" demo, <code>canPlayLink()</code>, <code>canPlayMIME()</code>, <code>eqData</code> + <code>waveformData</code> for AAC/H.264 (movieStar) content, missing documentation and miscellaneous bug fixes.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New <code>soundManager.useFlashBlock</code> (disabled by default) - enables CSS classes assigned to SWF container indicate start-up state (ok/error/blocked), allowing positioning/display of SWF for unblock cases and successful recovery from unblocking. Built into homepage + (most) demos. Updated flashblock demo as well.</li>
+ <li>playableClass attribute eg. <code><a href="foo.php" class="inline-playable"></code>, allowing URLs without .mp3 to be picked up</li>
+ <li>New <code>soundManager.canPlayLink()</code> + <code>canPlayMIME()</code>, ability to check <a href="foo.php" type="audio/mp3"> for example</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li><code>soundManager.play()</code> type check fix, instanceof Object vs. typeof x === 'Object' (typo)</li>
+ <li><code>computeSpectrum()</code> can access waveform and eq (spectrum) data for movieStar (AAC/MP4, netstream-based) objects, too.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Moved old demo code using <code>$()</code> to <code>_id()</code>, <code>_$</code> in <code>soundManager2</code> to <code>_id()</code> to avoid potential jQuery (and other $-based library) collisions</li>
+ <li>Make <code>new SoundManager('/path/to/swfs/');</code> actually work.</li>
+ <li>Flash time-out (flash blockers) vs. security failure detection/other error cases is smarter on the SM2 homepage now</li>
+ <li>New "MP3 player button" demo</li>
+ <li>Removed old IE onclick handler fix in several demos for non-MP3 links</li>
+ <li><code>eqeqeq = true</code> for jslint, why not.</li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+
+ <li class="in">
+ <h3><b>V2.95b.20100101</b> (<a href="../../download/soundmanagerv295b-20100101.zip">Download archived version</a>)</h3>
+ <p>New features: Flash movie debugging in SWF via <code>debugFlash</code> (default:false), <code>SMSound.eqData = { left:[], right:[] }</code>, code tidying and debug output clean-up</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New <code>soundManager.debugFlash</code> property, enables debug messages from within flash (output to flash movie). Useful for troubleshooting start-up, security issues etc. <a href="../getstarted/#flashdebug">Flash debug output example</a></li>
+ <li><code>SMSound.eqData</code> now has left and right channels - e.g. <code>eqData = { left: [], right: [] }</code> - was previously a single array: <code>eqData = [];</code> Backwards-compatibility is maintained for now as <code>eqData[i]</code> still works with the new structure.</li>
+ </ul>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li><code>stream = true</code> is no longer automatically set when <code>SMSound.play()</code> is called and <code>readyState == 0</code>, as it was breaking the <code>stream:false</code> case where playback should not start until the sound has fully-loaded.</li>
+ <li><code>soundManager.reboot()</code> forces recreation of object/embed rather than old method of node remove/re-append (in case other options changed, eg. debugFlash was false, but assigned to true after an error during start-up.)</li>
+ </ul>
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Review of all SM2 debug output, more concise and informative messaging - especially around start-up troubleshooting/error debugging, security sandbox errors, SWF 404 case etc.</li>
+ <li>Code formatting clean-up (via jsbeautifier.org)
+ soundmanager2.js tested and passes JSLint, Edition 2009-11-22 + options: /*jslint undef: true, bitwise: true, newcap: true, immed: true */</li>
+ <li>Better organization/use of strings for debug output</li>
+ <li>New canvas-based favicon VU meter demo for home page, 360 player and muxtape-style player demos where supported (Firefox and Opera, currently.) Firefox 3.6 is disappearing support for XBM images, which were previously used.</li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+ <li class="in">
+ <h3><b>V2.95a.20090717</b> (<a href="../../download/soundmanagerv295a-20090717.zip">Download archived version</a>)</h3>
+ <p>New features: onready(), fast polling, flash blocking demos etc.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New <code>soundManager.onready(myFunction[,scope])</code> method, for asynchronous queueing of <code>onload()</code>-style handlers. Fires when SM2 has finished initializing. Accepts an <i>optional</i> scope parameter to apply to handler; if none given, window object is used. A "status" object is passed to your handler (can be ignored) which includes a <code>success</code> boolean indicating whether SM2 loaded OK or not. Handlers added via onready() after successful initialisation will fire immediately.</li>
+ <li>New <code>soundManager.oninitmovie()</code> event callback, single assignment similar to <code>onload()</code>. Fires when the flash movie has first been written to (or read from) the DOM. Used internally for a flashblock-handler-related example, custom timeout condition.</li>
+ <li>New <code>soundManager.useFastPolling</code> property (false by default), enables 1 msec Flash 9+ timer for highest-possible <code>whileplaying()</code> and related JS callback frequency (default is 20 msec.) Use with <code>soundManager.useHighPerformance = true</code> for best performance, frame rates while updating the UI via whileplaying() etc.</li>
+ <li>New sound option (soundManager.defaultOptions): <code>multiShotEvents</code> (default:false) - enable support for multiShot-style events (currently <code>onfinish()</code> only). Eg. When <code>mySound.play()</code> is called three times, <code>onfinish()</code> will subsequently fire three times.</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li><code>createSound</code> now writes a warning to debug output if the sound ID is a number, or is a string starting with a numeric character. Because SMSound objects are stored in <code>soundManager.sounds[]</code>, while not syntactically invalid, numeric IDs will be treated as array indices and are likely to break things.</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>New flashblock / "click to flash" demo, example of handling blocked conditions and graceful recovery when flash is initially blocked until user chooses to allow it.</li>
+ <li>Cross-domain-scripting enabled SWF (using <code>allowDomain("*")</code>) included in swf/ directory (in its own .zip file.) Use when you must have domain A loading SM2 .SWF from domain B, or for testing etc and can't compile your own custom x-domain SWF from source.</li>
+ <li>Documentation, layout and menu tweaks</li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+ <li class="in">
+ <h3><b>V2.95a.20090501</b> (<a href="../../download/soundmanagerv295a-20090501.zip">Download archived version</a>)</h3>
+ <p>Lots of updates.</p>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>Added <code class="in">soundManager.allowFullVideo</code> for full-screen video playback, triggered by double-clicking. Also, related <code>soundManager.onfullscreenchange</code> event handler.</li>
+ <li>Updated <code>waveformData</code> to include stereo channels. Now an object literal instead of a single array. New format: <code>SMSound.waveformData = { left: [], right: [] }</code></li>
+ <li>New <code>SMSound.ondataerror()</code> (flash 9+) handler for cases where waveform/eq data is inaccessible due to other flash movies in the current browser which have loaded sound. (Flash must have security permissions to "read" all data currently being output, long story short. Having a YouTube tab open can cause this, for example.)</li>
+ <li>New <code class="in">isBuffering</code> property for MovieStar (MP4 audio/video) content, related <code class="in">onbufferchange()</code> event handler (sound object)</li>
+ <li>New <code>bufferTime</code> property for MovieStream content. Defines seconds of data to buffer before playback begins (null = flash default of 0.1 seconds; if AAC playback is gappy, try up to 3 seconds.)</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>Off-screen flash with <code class="in">wmode</code> set to non-default value (transparent/opaque) will break SM2 for non-IE on Windows, time-out error style. SM2 will now revert wmode to default for this case (losing transparency/layering of movie) - <i>or</i> set <code>soundManager.flashLoadTimeout</code> to 0 and SM2 will retain wmode, but must now wait potentially infinitely for flash to load (until user scrolls it into view.) <code>soundManager.specialWmodeCase</code> reflects if this fix has been applied after init time. </li>
+ <li>Calling <code>soundObject.load()</code> after directly assigning a value to <code>soundObject.url</code> should now work as expected.</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Shiny new "360° UI" canvas + visualization demos (Warning: Beta-ish code.)</li>
+ <li>Experimental SM2 exception/error handling + stack trace reporting added, an attempt to make custom errors thrown from SM2 more meaningful (ideally showing the user's call to SM2 where things went wrong in the stack.)</li>
+ <li>Calling <code>soundObject.load()</code> after directly assigning a value to <code>soundObject.url</code> should now work as expected.</li>
+ <li><code class="in">soundManager.useHighPerformance</code> update: Now false/disabled by default. Strange bug with JS/flash communication breaking with wmode=opaque on flash, specific (?) to Firefox on windows. SM2 does not normally set wmode. When <code class="in">useHighPerformance = true</code>, wmode=transparent will be used on the flash movie by default.</li>
+ <li>Tweaks related to position, whileplaying(), playState, buffering and state resetting when sound has finished playing (fixes for a few edge cases if replaying or reusing the same sound or video.)</li>
+ <li>Better code/feature separation and clean-up on inline player, Muxtape-style demos</li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+ <li class="in">
+ <h3><b>V2.94a.20090206</b> (<a href="../../download/soundmanagerv294a-20090206.zip">Download archived version</a>)</h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API Updates</p>
+ <ul class="nested compact flat">
+ <li>New <code class="in">isBuffering</code> property, related <code class="in">onbufferchange()</code> event handler (sound object)</li>
+ <li>New <code class="in">soundManager.reboot()</code> method (<i>experimental</i>): Shut down and re-initialise SoundManager, remove and recreate flash movie (possibly handy for cases where you want to restart after flashblock-type whitelisting, etc.)</li>
+ <li>New <code class="in">soundManager.flashLoadTimeout</code> property, milliseconds SM2 will wait for flash movie callback before failing and calling soundManager.onerror() during start-up/init. If set to 0, SM2 will wait indefinitely for flash (good for reboot/flashblock-type scenarios.)</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>Reverted Firebug 1.3 console.log().apply() hack, was breaking console.log() under IE 8 RC1 (as used with debug mode.) Firebug 1.3 seems to have a bug, occasional "console undefined" error.</li>
+ <li>Fixed a dumb flash 9/AS3 bug with setVolume() passing an extra parameter to flash.</li>
+ <li><code class="in">soundManager.useHighPerformance</code> update: Now false/disabled by default. Strange bug with JS/flash communication breaking with wmode=opaque on flash, specific (?) to Firefox on windows. SM2 does not normally set wmode. When <code class="in">useHighPerformance = true</code>, wmode=transparent will be used on the flash movie by default.</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Tweaked project page / documentation UI, nicer code/debug formatting</li>
+ <li>Misc. API documentation fixes, improvements</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+
+ <li class="in">
+ <h3><b>V2.93a.20090117</b> (<a href="../../download/soundmanagerv293a-20090117.zip">Download archived version</a>)</h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">General Updates</p>
+ <ul class="nested compact flat">
+ <li>New SoundManager 2 start-up debugger / troubleshooting tool, built into project home (see <a href="../getstarted/#troubleshooting" title="SM2 troubleshooting">troubleshooting</a>, and a standalone version - see "<a href="../../troubleshoot/" title="SoundManager 2 standalone troubleshooting tool" class="norewrite">troubleshoot/</a>" directory of download package)</li>
+ <li>New soundManager.getMemoryUse() method (flash 9+.) Returns RAM use for flash plugin (appears to be browser-wide, possibly system-wide by design.) <a href="../../demo/video/" title="SM2 javascript video demo">Video demo</a> includes an example RAM use monitor.</li>
+ <li>highPerformance disabled by default for Firefox on Windows due to reports of bugs preventing SM2 start-up in some cases. To override the disabling safety check, set <code class="in">soundManager.useHighPerformance = 'always';</code></li>
+ <li>Updated API demo testcases (<a href="../../demo/api/">API Demo page</a>)</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Fixed Flash 8 bug with <code class="in">autoLoad</code>/<code class="in">autoPlay</code> and <code class="in">playState</code> not being correctly set.</li>
+ <li class="in">Fixed a bug with <code class="in">onfinish()</code> not firing when <code class="in">autoPlay</code> is used.</li>
+ <li class="in">Fixed a bug with pan and volume defaults not being correctly inherited and handled</li>
+ <li class="in">console[method]() now uses apply(), preventing possible Firebug 1.3-related scope issue where this != console</li>
+ <li class="in">IE now appends (vs. destructive .innerHTML write) SWF movie to target element, appends DIV with className "sm2-object-box"</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+
+ <li class="in">
+ <h3><b>V2.92a.20081224</b> (<a href="../../download/soundmanagerv292a-20081224.zip">Download archived version</a>)</h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">General Updates</p>
+ <ul class="nested compact flat">
+ <li>Note: Flash (SWF) assets moved to swf/ subdirectory, starting with this version.</li>
+ <li>Updated design on API demo page, new <a href="../../demo/api/#looping">looping example</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Improved regular-expression-based URL detection for <code>canPlayURL()</code>, flash 8/9 and MovieStar (video) formats</li>
+ <li class="in">Improved <code>soundManager.url</code>-related <code>normalizeURL()</code> handling. If GET parameters are in the URL including the SWF, it will be left alone.</li>
+ <li class="in">Fixed out-of-bounds issue with <code>setPosition()</code>.</li>
+ <li class="in">Fixed a <code>setPosition(0)</code> and <i>before</i> <code>onfinish()</code>-related issue, so it is possible to nicely loop sounds from within <code>onfinish()</code> - see <a href="../../demo/api/#looping">looping a sound</a> (API demo)</li>
+ <li class="in">Fixed an error condition where destroying a loading sound would not terminate the HTTP request, relating to error cases involving <code>netStream.close()</code>.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+
+ <li class="in">
+ <h3><b>V2.91a.20081205</b> (<a href="../../download/soundmanagerv291a-20081205.zip">Download archived version</a>)</h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">General Updates</p>
+ <ul class="nested compact flat">
+ <li>Completely-redesigned project page, multiple pages/sections, more-legible grid-based documentation layout</li>
+ <li>Code verified with <a href="http://jslint.com">jslint</a>. 0 errors reported with default settings, Edition 2008-11-26</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">True XHTML DOM compatibility. Rewrote <code>createMovie()</code> to use standard DOM <code>createElement()</code> methods, vs. previous writing to .innerHTML method which caused exceptions with XHTML documents.</li>
+ <li class="in">Special-cased <code>useHighPerformance</code> for Firefox 2 only, disabling it as it seems to be problematic. Further research pending.</li>
+ <li class="in">Removed try .. catch error handling within <code>soundManager.onload()</code>, catching exceptions when calling user-defined onload handler. Errors should now fall through as normally expected.</li>
+ <li class="in">Fixed several <code>setPosition()</code>-related bugs (NaN/undefined error, seeking to invalid position, position inconsistencies with pause/resume)</li>
+ </ul>
+ </li>
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.90a.20081028 (Old documentation theme) - <a href="http://schillmania.com/projects/soundmanager2/download/soundmanagerv290a-20081028.zip">Download archived version</a></b></h3>
+
+ <ul class="double">
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li>Fixed numerous Flash AS3 exceptions for Flash 10 plugin users of SM2 with Flash 9 .SWF</li>
+ <li class="in">Fixed a <code>setPosition()</code> bug where position > duration would stop sounds playing in other tabs</li>
+ <li class="in">Fixed <code>createSound(); play(); destruct();</code> sequence to correctly stop sound under Flash 9</li>
+ <li class="in">Changed Flash 9 <code>onload()</code> to properly pass boolean "false" on load failure, same as Flash 8</li>
+ <li class="in">Fixed <code>autoLoad</code>=true bug with Flash 9 movieStar (MPEG4) content, now pauses after creating</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">API: New shiny!</p>
+ <ul class="nested compact flat">
+ <li class="in"><code>soundManager.useHighPerformance</code>: Minimize JS/Flash lag, ~3x <code>whileplaying()</code> frequency! (Most noticeable on Mac OS X, and Safari on Windows? Investigating IE cases.)</li>
+ <li class="in"><code>soundManager.pauseAll()</code> / <code>soundManager.resumeAll()</code>: Global pause/resume</li>
+ <li class="in"><code>soundManager.muteAll()</code> / <code>soundManager.unmuteAll()</code>: Global mute/unmute</li>
+ </ul>
+ </li>
+
+ <li>
+ <p class="compact">MovieStar MPEG4 video support! <em>(experimental)</em></p>
+ <ul class="nested compact flat">
+ <li class="in"><code>soundManager.createVideo()</code> / <code>soundManager.destroyVideo()</code> for MovieStar MPEG4 formats!</li>
+ <li>Uses same SMSound instance object and API methods/options as regular sounds, with a few extra parameters</li>
+ <li class="in"><code>soundManager.useVideo</code> will show video when applicable (false/disabled by default)</li>
+ <li class="in"><code>SMSound.onmetadata</code>: Meta data handler for MPEG4 video files - provides dimensions (w/h)</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li><b>Removed</b> experimental flashBlock support. Considering eliminating SM2 timeout-based onerror() behaviour in favour of asynchronous loading (eg. user may initially block, notice flash movie and take action to unblock many seconds after loading - thus, flash movie eventually loads and can eventually trigger successful SM2 init.)</li>
+ <li class="in">Modified <code>pause()</code> and <code>resume()</code> to only affect playing sounds (eg. <code>playState != 0</code>).</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <!-- not newest -->
+
+ <li class="in">
+ <h3><b>V2.80a.20081005</b></h3>
+
+ <ul class="double">
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Changed Flash 8 <code>onload()</code> boolean "loaded" to be based on sound duration being >0, better test of load success.</li>
+ <li class="in">Modified Flash 9 <code>onload()</code> to include boolean result for success/fail, parity with Flash 8</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">API: New shiny!</p>
+ <ul class="nested compact flat">
+ <li class="in">
+ <p style="font-weight:normal;padding-top:0px">Added <em>experimental</em> Flash 9.0r115+ (flash codename "<a href="http://www.adobe.com/support/documentation/en/flashplayer/9/releasenotes.html#fixes_90115">MovieStar</a>", Flash 9 Update 3) MPEG4 / HE-AAC support (audio only.) A subset of MPEG4 should be supported including FLV, MP4, M4A, MOV, MP4V, 3GP and 3G2 files. Feature is disabled by default.</p>
+ <ul class="nested compact flat">
+ <li class="in">New soundManager <code>useMovieStar</code> property, controls feature availability (currently disabled by default.)</li>
+ <li>New SMSound option, <code>isMovieStar</code>, configures feature behaviour on a per-sound basis. Default (null) is to auto-detect .mp4, .mov etc. in URL and enable if found, but can also be forced on or off (true / false).</li>
+ <li class="in">Video-based formats use the Flash 9 <code>NetStream</code> and <code>NetConnection</code> objects, whose API differs slightly from the Sound object. Seeking is limited to video key frames and is not as smooth as an MP3.</li>
+ <li class="in">Audio playback has been seen to pause during certain events (window scrolling, etc.) while playing MovieStar formats. It doesn't appear to be from CPU overload. More investigation is needed.</li>
+ <li class="in">Basic load, progress, onload, whileplaying API support is provided (page player demo includes MP4 and FLV formats). Not all methods (eg. setVolume) have been tested.</li>
+ <li class="in">.AVI is not included by default, but may work if the format is actually MPEG4-based.</li>
+ <li>Format limitation note: EQ, peak and spectrumData are not available with MovieStar content. This may be a Flash 9/AS3 limitation.</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <ul class="double">
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li>Added CSS checks to page player: "exclude" and "playable" to override default URL matching behaviour.</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.78a.20080920</b></h3>
+
+ <ul class="double">
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Added <code>SoundLoaderContext</code> parameter to <code>load()</code>, Flash should now check policy-related (crossdomain.xml) files when loading resources from remote domains. Should fix previous security exception warnings when trying to access ID3 and/or waveform/EQ data. See related <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundLoaderContext.html">SoundLoaderContext documentation</a> (ActionScript 3)</li>
+ <li class="in">Fixed a bug with <code>load()</code>, was improperly expecting an options object - now works properly.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">API: New shiny!</p>
+ <ul class="nested compact flat">
+ <li class="in">Added <code>soundManager.altURL</code> property (and <code>useAltURL</code> conditional) for convenient offline and other URL switching cases (dev vs. production environments, etc.)</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li class="in">Renamed internal soundManager and SMSound <code>self</code> closure references to <code>_s</code> and <code>_t</code>, respectively, to avoid potential conflicts with others' code</li>
+ <li class="in">Moved self-destruct to use <code>window.onunload</code> instead of <code>onbeforeunload</code>, given the latter event can be caught and canceled if desired by the user</li>
+ <li class="in">Inline player demo: Added <code>autoPlay</code> option</li>
+ <li class="in">"Basic" demo directory (demo/basic/) moved to demo/api/, added <code>load()</code>-related testcase</li>
+ </ul>
+ </li>
+ </ul>
+
+ </li>
+
+ <li class="in">
+ <h3><b>V2.78a.20080920</b></h3>
+
+ <ul class="double">
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Added <code>SoundLoaderContext</code> parameter to <code>load()</code>, Flash should now check policy-related (crossdomain.xml) files when loading resources from remote domains. Should fix previous security exception warnings when trying to access ID3 and/or waveform/EQ data. See related <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundLoaderContext.html">SoundLoaderContext documentation</a> (ActionScript 3)</li>
+ <li class="in">Fixed a bug with <code>load()</code>, was improperly expecting an options object - now works properly.</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">API: New shiny!</p>
+ <ul class="nested compact flat">
+ <li class="in">Added <code>soundManager.altURL</code> property (and <code>useAltURL</code> conditional) for convenient offline and other URL switching cases (dev vs. production environments, etc.)</li>
+ </ul>
+ </li>
+ <li class="in">
+ <p class="compact">Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li class="in">Renamed internal soundManager and SMSound <code>self</code> closure references to <code>_s</code> and <code>_t</code>, respectively, to avoid potential conflicts with others' code</li>
+ <li class="in">Moved self-destruct to use <code>window.onunload</code> instead of <code>onbeforeunload</code>, given the latter event can be caught and canceled if desired by the user</li>
+ <li class="in">Inline player demo: Added <code>autoPlay</code> option</li>
+ <li class="in">"Basic" demo directory (demo/basic/) moved to demo/api/, added <code>load()</code>-related testcase</li>
+ </ul>
+ </li>
+ </ul>
+
+ </li>
+
+ <li class="old">
+ <h3><b>V2.77a.20080901</b></h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Fixed some <code>mute()</code> / <code>unmute()</code>-related bugs, global muting should now work properly. Added some related demo page examples.</li>
+ <li class="in">Removed comment on flash9Options merging code, was previously new and didn't actually work as it was commented out. Oops. :D</li>
+ <li class="in">Added <i>experimental</i> Flashblock exception handling (mozilla/firefox extension), "notification bar"-style UI which can message and assist users in unblocking SM2 .swf. Configured via <code>soundManager.flashBlockHelper</code> object, currently disabled by default.</li>
+ <li class="in">Modified <code>soundManager.destroySound()</code> and <code>sound.destruct()</code>, fixed a bug with these methods and flash's unloading of sounds which was breaking things. Hopefully fixes destroying sounds within whileplaying() and related event handlers, too.</li>
+ <li class="in">Modified flash 9 "peak data" code to only set the data if the feature is actually enabled.</li>
+ <li class="in">Modified <code>soundManager._debug()</code> to list all sound object details, instead of just ID/URL.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </li>
+
+ <li class="old">
+ <h3><b>V2.76a.20080808</b></h3>
+
+ <ul class="double">
+
+ <li class="in">
+ <p class="compact">API: Bug fixes</p>
+ <ul class="nested compact flat">
+ <li class="in">Fixed some memory "leaks" / garbage collection issues. RAM allocated to load sounds previously wasn't freed until page unload; now memory should be garbage collected some time after <code>sound.unload()</code> and/or <code>soundManager.destroySound()</code>/<code>sound.destruct()</code> methods are called. In certain cases, Flash sound objects may be destroyed and re-created (transparent to the JS-side) to release memory. Note that garbage collection is not instantaneous, and is affected by CPU/system load and other variables.</li>
+ <li class="in">Fixed an issue with <code>play()</code> not working on sounds created with <code>autoPlay</code>.</li>
+ <li class="in">Fixed SM2 to work under proper XHTML (served as <code>application/xhtml+xml</code> MIME type). Rewrote object/embed code <em>again</em>, now version-agnostic for IE (no CLSID parameters.)</li>
+ <li class="in">Corrected reported <code>loadFromXML()</code> bug, multiple loadFromXML() calls should work.</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">API: New shiny!</p>
+ <ul class="nested compact flat">
+ <li class="in">New <code>useWaveformData</code> and <code>useEQData</code> sound options, providing access to raw waveform and sound frequency/EQ spectrum data via sound.waveformData and sound.eqData.</li>
+ <li class="in">Renamed <code>useSpectrumData</code> to <code>useWaveformData</code> - if using waveform stuff currently, make sure you update your code!</li>
+ <li class="in">Added <code>soundManager.features</code> object, which reflects the "support" state for <code>peakData</code>, <code>waveformData</code> and <code>eqData</code>. Handy for current and future version/support branching.</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">API: Miscellaneous</p>
+ <ul class="nested compact flat">
+ <li class="in">New <code>flash9Options</code> configuration object for logical separation. When Flash 9+ is used, these options are merged into the <code>defaultOptions</code> object.</li>
+ <li class="in">Added <code>allowDomain()</code> stubs and documentation to .as source for allowing .swf on external domains to work (recompile of .swf required)</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">"Page As Playlist" demo: Updates</p>
+ <ul class="nested compact flat">
+ <li>Added "favicon" VU meter display option (Flash 9+ only, experimental, currently Firefox/Opera only)</li>
+ <li class="in">More-efficient RAM use via <code>unload()</code> and <code>destruct()</code> sound methods, discarding inactive sounds and freeing RAM as appropriate.</li>
+ <li class="in">Added <code>useEQData</code>, showing sound spectrum (frequency range) instead of raw waveform</li>
+ <li class="in">Added <code>fillGraph</code> config option, allowing solid waveform graphs instead of only peak points</li>
+ <li class="in">Fixed <code>playNext</code> bug where same track couldn't be played twice in a row.</li>
+ <li>Fixed duplicate URL bug; items with identical MP3 URLs will now work. (Previously, URL was the ID for items and thus had to be unique. Lookup is now done by object.)</li>
+ <li>Modified MP3 URL search to include URL parameters, characters after ".mp3"</li>
+ </ul>
+ </li>
+
+ <li class="in">
+ <p class="compact">Other updates</p>
+ <ul class="nested compact flat">
+ <li>Demo code clean-up, externalised CSS, prettier demo layout and code color highlighting</li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+ <li class="old">
+ <h3><b>V2.75a.20080707</b></h3>
+ <ul class="nested">
+ <li class="in">Flash 9 support! (soundmanager2_flash9.swf) - <code>multiShot</code> now actually works (layering/"chorus" effects on sounds), new <code>spectrumData</code> and <code>peakData</code> API features. All existing API features should have parity.</li>
+ <li class="in">Added <code>soundManager.flashVersion</code> property. Flash 8 is the supplied default.</li>
+ <li class="in">Modified <code>soundManager.url</code> to require only a path, eg. <code>/path/to/soundmanager-swfs/</code> to allow loading of varying .SWF versions.</li>
+ <li class="in">Basic (API) demo: Updated multiShot/Flash 9 behaviour documentation</li>
+ <li class="in">Page player demo: Added optional spectrum and VU (spectrumData/peakData) features</li>
+ <li class="in">MPC + animation demos: Modified to use Flash 9 (demo improved multiShot feature)</li>
+ <li>Flash 9 behaviour differences:
+ <ul>
+ <li class="in"><code>multiShot</code> properly allows <code>play()</code> to be called multiple times on a sound object, creating desired "chorus" effect. Will call <code>onfinish()</code> multiple times, but <code>whileplaying()</code> etc. are called only for the first "play instance" to avoid complications.</li>
+ <li class="in">New <code>soundSpectrum</code> and <code>peakData</code> sound features (spectrum graph / "VU" meter-style data) available</li>
+ <li>Sounds can be actually unloaded ("null" MP3 no longer needed to cancel loading of an MP3), but URL cannot be changed without destroying and recreating the related Flash sound object. The Flash 9 version does this to maintain API consistency.</li>
+ </ul>
+ </li>
+ <li>New + improved documentation/project page, updated 2-column layout with content filters, "Get Satisfaction" integration and self-update checks (and a light-switch-related easter egg.)</li>
+ </ul>
+ </li>
+
+ <li class="old">
+ <h3>V2.5b.20080525</h3>
+ <ul class="nested">
+ <li class="in">Added <code>waitForWindowLoad</code> for delayed init</li>
+ <li class="in">Added <code>onpause()</code> and <code>onresume()</code> event handlers</li>
+ <li class="in">Added <code>mute()</code> and <code>unmute()</code></li>
+ <li class="in">Updated demos, revised documentation</li>
+ </ul>
+ </li>
+
+ <li class="old">
+ <h3>V2.5b.20080505</h3>
+ <ul class="nested">
+ <li class="in">To improve startup time, <code>soundManager.go()</code> (<code>createMovie()</code> alias) now fires at <code>onDOMContentLoaded()</code> by default if supported. (Otherwise, falls back to <code>window.onload()</code>.)</li>
+ <li class="in">Improved initialisation routine - <code>soundManager.onerror()</code> is called when the Flash init "times out." Specifically, <code>onerror()</code> is called when Flash fails to make an ExternalInterface (Flash-> JS) call to SM2 within 1 second of <code>window.onload()</code> firing.</li>
+ <li>Added logic to handle special Safari delayed init case (Flash not loading when in a new, unfocused tab until focused) as a exception to the above.</li>
+ <li>Added better exception handling + debug messaging for initialisation failure cases (Flash security restrictions due to loading from local file system, no flash support, no ExternalInterface support etc.)</li>
+ <li class="in">Updated .swf appendChild() target to use best-to-worst options: <code>(document.body || document.documentElement || document.getElementsByTagName('div')[0])</code></li>
+ <li>Safari console[log|warn|error]-style messages are now properly formatted.</li>
+ <li class="in">Added tons of semicolons to closing braces, eg. <code>};</code></li>
+ <li>"No-debug", minified version of SM2 included: <a href="script/soundmanager2-nodebug-jsmin.js" title="No-debug, minified version of SoundManager 2 script">soundmanager2-nodebug-jsmin.js</a> (17.4 KB, down from full size of 35 KB.) With Gzip compression, file size is ~6 KB. (Commented, debug-enabled version compresses to 10 KB with Gzip.)</li>
+ </ul>
+ </li>
+
+ <li class="old">
+
+ <h3>V2.5b.20080501</h3>
+ <p class="compact"><b>Warning:</b> A little experimental too, read details below.</p>
+ <p><em>Changelog</em>:</p>
+ <ul class="nested">
+ <li class="in">Rewrote SoundManager initialisation: "Way faster." Communication now initiated from Flash, verification callback then performed by JS; far faster, hopefully more-reliable (TBD.) Init time drastically reduced from seconds to milliseconds in most cases, dependent primarily on Flash movie load rather than <code>window.onload()</code>.</li>
+ <li>Above change also fixes Safari "loading SM2 in background tab" issue, where Safari does not init Flash until background tab comes into focus (when a link is opened in a new, non-focused tab.)</li>
+ <li class="in">Current drawback: Difficult to determine, save for falling back to <code>window.onload()</code> plus focus methods due to above issue, whether SM2 is actually available or not (ie., <code>soundManager.onerror()</code> will not likely be called as in past.) However, the <code>supported()</code> method will correctly reflect if SM2 has successfully initialised, for example.</li>
+ <li class="in">Added sandbox/security model code; SM2 can now tell if it is restricted to either local or internet access only, for example. Helpful in potential debugging errors, plus viewing demos off the local filesystem should no longer throw init errors requiring whitelisting (seemingly due to the new initialisation method.) Win!</li>
+ <li class="in">Opera 9.27 has been noted to have some bugs relating to ExternalInterface, seems to be unable to make calls from ActionScript-level methods using <code>setTimeout()</code> or <code>setInterval()</code>. As a reulst, SoundManager 2 events like <code>onfinish()</code>, <code>whileplaying()</code> and <code>onfinish()</code> can be sporadically called or missed altogether. No known workaround at this time, but Opera 9.5 (beta 2) does not have this issue. Popular MP3 "mix tape" site muxtape.com uses similar techniques for JS-Flash communication and appears to suffer from the same problem.</li>
+ <li class="in"><strong>Warning</strong>: Random crash issue noticed when using IE 6 + 7 and this demo page, calling <code>createSound()</code> when <code>soundManager.defaultOptions.autoLoad = true;</code> from within <code>soundManager.onload()</code>, for creating + preloading the tab/theme switch sounds. Removing autoLoad=true (leaving the default of false) fixed the crash. Exact reason not determined, perhaps recursive calls or pre-onload issue (?), seems to be isolated to the home page. MPC demo uses autoLoad also, but did not crash. Mentioning just in case.</li>
+ <li>Updated Muxtape-style demo: More themes, load/security debugging info etc.</li>
+ </ul>
+ </li>
+
+ <li class="old">
+
+ <h3>V2.2.20080420</h3>
+ <p><em>Changelog</em>:</p>
+ <ul class="nested">
+ <li>More demos! "<a href="../demo/page-player/" title="Muxtape.com-style playable page of MP3 links">Page as a playlist</a>" (muxtape.com-style) example, "<a href="../demo/play-mp3-links/" title="Play MP3 links in a web page using SoundManager 2">Make MP3 links playable inline</a>" demo</li>
+ <li class="in">Corrected <code>onStop()</code> handler inheritance/overriding behaviour (was incorrectly checking defaultOptions)</li>
+ <li class="in">Added debug output of options object for <code>createSound()</code> calls. Full options (result of merging global default + sound-instance-specific options) displayed, helpful in troubleshooting. Event handler function code is intelligently (hopefully) displayed, truncated at 64 characters of first block or end of line, whichever comes first.</li>
+ <li class="in">Removed most HTML markup from non-HTML (eg. console) <code>_writeDebug()</code> calls</li>
+ <li class="in"><code>soundManager.destruct()</code> writes to console, to be consistent</li>
+ </ul>
+
+ </li>
+
+ <li class="old">
+
+ <h3>V2.1.20080331</h3>
+ <p><em>Changelog</em>:</p>
+ <ul class="nested">
+ <li class="in">Modified <code>createSound()</code> to return a sound object if successful (more logical)</li>
+ <li class="in">Updated <code>setPosition()</code> method and added <code>position</code> option parameter, documentation + demo (bugfix)</li>
+ <li class="in">Corrected <code>createSound()</code> and <code>play()</code> sound option inheritance/overriding behaviour (eg. <code>position</code>) to work as expected (most to least important: Method call options -> sound object instance options -> SM2 global options)</li>
+ <li class="in">Updated <code>deleteSound()</code> so Array.splice() is used instead of delete, the latter doesn't cause Array.length to update (bugfix)</li>
+ <li>Modified debug=alert to only work when debug mode is enabled (potential annoyance aversion)</li>
+ <li class="in">Modified <code>togglePause()</code> to use <code>position</code> option parameter rather than undocumented <code>offset</code> (oops :D)</li>
+ <li class="in">Added <code>supported()</code> convenience method (indicates pass/fail after SM2 has initialised.)</li>
+ <li>Added disabling debug calls from Flash (performance)</li>
+ <li>Added URL hash updating/bookmarking and page title updating to jsAMP demo app</li>
+ <li>Updated project page layout</li>
+ </ul>
+
+ </li>
+
+ <li class="old">
+
+ <h3>V2.0b.20070415</h3>
+ <p><em>Changelog</em>:</p>
+ <ul class="nested">
+ <li class="in">Added <code>destroySound()</code> method</li>
+ <li>Made debug output slightly less-verbose (commented out)</li>
+ <li>Safety tweak for position-related Flash bug when loading new sounds</li>
+ <li class="in">Highly-expanded documentation (<code>SMSound</code> events + properties, examples, caveats, FAQs etc.)</li>
+ <li>Added time-sensitive light/dark theme for documentation</li>
+ </ul>
+
+ </li>
+
+ <li class="old">
+
+ <h3>V2.0b.20070201</h3>
+ <p class="compact">Second beta?</p>
+ <p><em>Changelog</em>:</p>
+ <ul class="nested">
+ <li>Fixed stopAll() bug (previously broken)</li>
+ <li>Added <code class="in">nullURL</code> parameter</li>
+ <li>Updated documentation</li>
+ </ul>
+ <h3>V2.0b.20070123</h3>
+ <h3>V2.0b.20070118</h3>
+ <h3>V2.0b.20070115</h3>
+ </li>
+
+ <li class="old">
+ <h3>V2.0b.20070107</h3>
+ <p class="compact">First beta</p>
+ </li>
+
+ <li class="old">
+ <h3>V2.0a.20060904</h3>
+ <p class="compact">Prerelease alpha</p>
+ </li>
+
+ </ul>
+
+ <!-- <script type="text/javascript">document.getElementById('revision-list').className += ' hide-old';</script> -->
+
+ </div>
+
+ </div>
+
+ </div>
+
+
+ <div id="col3" class="c3">
+
+
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2" rel="nofollow">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ <!-- /.box -->
+
+ </div>
+
+ <div id="shortcuts">
+
+<!--
+ <div class="box">
+
+ <h2>Shortcuts<span class="l"></span><span class="r"></span></h2>
+
+ <ul class="first">
+ <li onclick="setFilter(event,'c-')" class="ignore">
+
+ <ul>
+
+ <li>Demos</li>
+ <li>Getting Started</li>
+ <li>Basic Use</li>
+ <li>Download</li>
+ <li>Requirements</li>
+ <li>Limitations</li>
+
+ <li>Debug Output</li>
+ <li>Revision History</li>
+ <li>About</li>
+ </ul>
+
+ </li>
+ </ul>
+
+ </div>
+-->
+
+ </div>
+
+
+
+ </div>
+
+ <div class="clear"></div>
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+<script type="text/javascript">
+init();
+</script>
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/doc/getstarted/index.html b/docs/dymaxion/soundmanagerv297a-20101010/doc/getstarted/index.html new file mode 100755 index 0000000..9f096af --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/doc/getstarted/index.html @@ -0,0 +1,549 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Tutorial: Getting Started</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="SoundManager 2 tutorial, example code, how to get started guide including and configuring SoundManager 2 for playing MP3 audio via Javascript." />
+<meta name="keywords" content="soundmanager2 tutorial, javascript sound, javascript audio, javascript play mp3, javascript sound control, mp3, mp4, mpeg4" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../../demo/index.css" />
+<link rel="stylesheet" type="text/css" media="screen" href="../../troubleshoot/debug.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="../../demo/index.js"></script>
+<script type="text/javascript">
+ soundManager.useFlashBlock = true;
+ soundManager.debugMode = true;
+ soundManager.debugFlash = true; // enable flash debug output for this page
+ soundManager.url = '../../swf/';
+ soundManager.onload = function() {
+ }
+</script>
+<script type="text/javascript" src="../../troubleshoot/debug.js"></script>
+</head>
+
+<body>
+
+<div id="content">
+
+ <div id="top">
+
+ <h1>SoundManager 2: Getting Started</h1>
+
+ <div id="nav">
+ <ul>
+
+ <li>
+ <a href="../../">Home</a>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="../../demo/api/">API Examples</a></li>
+ <li><a href="../../demo/play-mp3-links/" class="exclude">Playable MP3 links</a></li>
+ <li><a href="../../demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="../../demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="../../demo/360-player/">360° Player UI</a></li>
+ <li><a href="../../demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="../../demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="../../demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="../../demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <strong><a href="../getstarted/">Getting Started</a></strong>
+ <ul>
+ <li><a href="../getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="../getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="../getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="..">Documentation</a>
+ <ul>
+ <li><a href="../#sm-config">SoundManager Properties</a></li>
+ <li><a href="../#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="../#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="../#api">SoundManager Core API</a></li>
+ <li><a href="../#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../download/">Download</a>
+ <ul>
+ <li><a href="../download/#latest">Get SoundManager 2</a></li>
+ <li><a href="../download/#revision-history">Revision History</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../technotes/">Technical Notes</a>
+ <ul>
+ <li><a href="../technotes/#requirements">System Requirements</a></li>
+ <li><a href="../technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../resources/">Resources</a>
+ <ul>
+ <li><a href="../resources/#licensing">Licensing</a></li>
+ <li><a href="../resources/#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+ <div class="columnar">
+ <div class="c1">
+ <h2>How SoundManager Works</h2>
+ <p>It starts out easy, but you can go down the rabbit hole if you want.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block">
+
+ <!--
+ <p style="margin-top:1px"><strong><strong>SoundManager 2 makes it easier to play MP3 audio cross browser / platform, using Javascript.</strong></strong></p>
+ -->
+
+ <h3>SoundManager 2 Tutorial: What, Why, How</h3>
+
+ <p><strong>Problem:</strong> Browsers lack good, consistent native audio support. (HTML 5's <code>Audio()</code> is the future, but does not have majority support yet.)</p>
+ <p><strong>Solution:</strong> Javascript API via Flash + ExternalInterface, works almost everywhere. If HTML5 audio support is enabled, flash fallback used for browsers that don't support "non-free" MP3 + MP4 formats.</p>
+ <p>SoundManager 2 wraps and extends both the Flash and HTML Audio Sound APIs, providing a single, unified sound API to Javascript; the API is the same, whether HTML or Flash is ultimately used to play sound. (The flash portion is hidden, transparent to both developers and end users.)</p>
+
+ </div>
+
+ <div class="f-block c-basic-use">
+
+
+ <h4 id="basic-inclusion">Including SoundManager</h4>
+
+ <p>The soundmanager2.js core can get down to 10 KB over the wire, depending on what version you use. A few versions of the SM2 script are available, balancing code size between commented, debug-enabled and production-optimized builds.</p>
+ <p>Regardless of which build you use, take advantage of <a href="http://developer.yahoo.com/performance/rules.html#gzip" title="Best Practices for Speeding Up Your Web Site (Yahoo Developer Network)">gzip compression</a> on your server for big savings. As shown below, SoundManager 2 compresses quite well with gzip; the full debug-enabled version served <i>with</i> gzip is smaller than even the minified, no-debug version served without it.</p>
+
+ <table id="sm2-filesizes" cellpadding="0" cellspacing="0">
+
+ <tr>
+ <th>Build version</th>
+ <th>Recommended use</th>
+ <th class="nw">File size</th>
+ <th class="nw">+ <a href="http://www.sergeychernyshev.com/blog/speed-up-your-site-drop-in-htaccess-file/" title="Friends don't let friends run websites without gzip!">gzip</a></th>
+ </tr>
+
+ <tr>
+ <td>
+ <p>Original, formatted debug-enabled version with comments. Passes <a href="http://jslint.com" title="jslint, the JavaScript code quality tool.">jslint</a>.</p>
+ <pre><script src="<span>soundmanager2.js</span>"></script></pre>
+ </td>
+ <td>Development, testing, debugging</td>
+ <td class="nw">90 KB</td>
+ <td class="nw">~25 KB</td>
+ </tr>
+
+ <tr>
+ <td>
+ <p>Minified (Google Closure Compiler-munged, no comments or whitespace), debug-enabled version</p>
+ <pre><script src="<span>soundmanager2-jsmin.js</span>"></script></pre>
+ </td>
+ <td>Production, with debug code</td>
+ <td class="nw">42 KB</td>
+ <td class="nw">~14 KB</td>
+ </tr>
+
+ <tr>
+ <td>
+ <p>Build-script optimized, minified, no-debug version</p>
+ <pre><script src="<span>soundmanager2-nodebug-jsmin.js</span>"></script></pre>
+ </td>
+ <td>Production-optimized, debug code removed</td>
+ <td class="nw">30 KB</td>
+ <td class="nw booyaa" title="Best-case scenario for load time/performance">~9.5 KB!</td>
+ </tr>
+
+ </table>
+
+ <p>You then need to tell SM2 where to find the flash .SWF it will need (if no HTML5 support), and optionally what version of Flash (~3 KB for flash 8, ~10 KB for flash 9) depending on what API features you want, as well as other features:</p>
+
+<pre>
+<script>
+soundManager.url = '<span>/path/to/swf-files/</span>';
+soundManager.flashVersion = 9; <span><span>// optional: shiny features (default = 8)</span></span>
+soundManager.useFlashBlock = false; <span><span>// optionally, enable when you're ready to <a href="../../demo/flashblock/" title="SoundManager 2 flash block handling demo">dive in</a></span></span>
+<span><span>// enable <a href="../#soundmanager-usehtml5audio">HTML5 audio support</a>, if you're feeling adventurous. iPad/iPhone will always get this.</span></span>
+<span><span>// soundManager.useHTML5Audio = true;</span></span>
+</script></pre>
+
+<p>If you plan to eventually use the flash block handling feature (disabled in this example), you'll want to look at the <a href="../../demo/flashblock/" title="SoundManager 2 flash block handling demo">flash block demo</a> and include the relevant CSS it uses.</p>
+
+
+
+ <h4 id="basic-template">Basic SoundManager Template</h4>
+
+ <p>For a live example of a page including SoundManager 2, check the <a href="../../demo/template/" title="SoundManager 2 template example" onclick="checkDomain(this)">bare-bones template</a>.</p>
+
+ <h4 id="file-structure">SoundManager File Structure</h4>
+ <p>Or, "What you get when you download SM2."</p>
+ <p>The core audio API bits require <code>script/soundmanager2.js</code> and the SWF files <code>swf/soundmanager2.swf</code> and <code>swf/soundmanager2_flash9.swf</code>, as well as the <code>_debug</code> versions of the SWFs. The flash 9 SWF enables some extra API features, and is only used if you set <code>soundManager.flashVersion = 9</code> (the default is 8.)</p>
+
+ <ul class="file-structure">
+ <li>
+ soundmanager2/
+ <ul>
+ <li>
+ demo/ <span>- Examples, MP3 player UIs etc.</span>
+ </li>
+ <li>
+ doc/ <span>- API method documentation, notes, troubleshooting</span>
+ </li>
+ <li class="core">
+ script/ <span>- API core, soundmanager2.js</span>
+ </li>
+ <li>
+ src/ <span>- AS2/AS3 Flash source used to build SWFs (for flash development)</span>
+ </li>
+ <li class="core">
+ swf/ <span>- API core, SoundManager 2 .SWF files</span>
+ </li>
+ <li>
+ troubleshoot/ <span>- Tool for finding/fixing startup issues</span>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+<h4 id="tech-architecture">How SoundManager 2 Really Works</h4>
+
+<p>SoundManager 2 is the result of Javascript talking to a hidden Flash movie. The Flash layer is not something you have to work with directly, but it is the component which makes audio control possible behind the scenes.</p>
+
+<div class="figure">
+
+ <div class="code">
+ <span>soundmanager2.js</span> <span class="mid"><-flash externalinterface magic-></span> <span>soundmanager2.swf</span> <span class="mid"><- HTTP -></span> <span>.mp3/.mp4</span>
+ </div>
+
+</div>
+
+<p>Flash can expose methods to Javascript via ExternalInterface, allowing bi-directional calls to be made and thus providing additional functionality to Javascript.</p>
+
+<p>For the real gory details on the behind-the-scenes action of JS + Flash, see <a href="http://www.schillmania.com/content/entries/2010/how-soundmanager2-works/" title="How SoundManager 2 works (JS + ExternalInterface + Flash)">How SoundManager 2 Works</a> on schillmania.com.</p>
+
+
+ </div>
+
+ <div class="f-block f-onload">
+
+ <h4>Startup / Initialization</h4>
+
+ <p>In brief, here is now SM2 starts up:</p>
+ <ul>
+ <li>soundmanager2.js loads</li>
+ <li>new SoundManager() constructor call, event listeners attached for dom ready/init</li>
+ <li>document.createElement('embed') (or 'object' for IE), append Flash .SWF to document</li>
+ <li>SWF loads, Flash makes call to JS function: "Hi, JS!"</li>
+ <li>JS -> Flash test (JS calls Flash function): "Hello, Flash!"</li>
+ <li>-- startup is complete, soundManager.onready() fires --</li>
+ </ul>
+
+ <p class="in">A single Javascript include will link in all of the required code for the library, which will automatically begin loading either at <code>onDOMContentLoaded()</code> if supported, or alternately, after <code>window.onload()</code> (eg., IE 6 and others.) The default behaviour is to start "as soon as possible", but the library can be configured to wait for <code>window.onload()</code> in all cases as well. Loading and initialisation are separate events.</p>
+
+ <p class="in">Once initialised, SM2 will call event handlers/listeners registered via <code>soundManager.onready()</code>. There are also "old-skool" onload()/onerror() event handlers which you can define just as you would with <code>window.onload()</code>.</p>
+
+ <p>If you want to lazy-load or defer SM2, see <a href="#lazy-loading" title="Lazy-loading SM2 and SM2_DEFER object">Lazy-loading and SM2_DEFER</a>.</p>
+
+ <h4>SoundManager onready/onload/onerror Event Handlers</h4>
+
+ <p><code>onready()</code> is the most flexible and can be used to queue numerous listeners for SM2's start-up. It is a single handler for completion of start-up. Simply pass a callback function, and check <code>soundManager.supported()</code> to know whether sound is available or not:</p>
+
+<pre class="block"><code>soundManager.onready(function() {
+ if (soundManager.supported()) {
+ <span><span>// SM2 is ready to go!</span></span>
+ makeSomeNoise(); <span><span>// soundManager.createSound(), etc.</span></span>
+ } else {
+ <span><span>// unsupported/error case</span></span>
+ }
+});</code></pre>
+
+ <p>The above example is simplified, slightly; <code>onready()</code> also passes an object literal parameter to your handler that indicates success/fail, so you can check state without having to use <code>soundManager.supported()</code>. For more examples and detail, see <a href="../#soundmanager-onready">soundManager.onready()</a>.</p>
+
+ <h4>SoundManager onload() + onerror()</h4>
+
+<p>A more traditional, less-flexible style of event handling is to assign single onload() / onerror() handlers. You should use <code>onready()</code> as it can be assigned at any time once soundManager has been defined, and is more robust.</p>
+
+<pre class="block"><code>soundManager.onload = function() {
+ <span><span>// SM2 is ready to go!</span></span>
+ makeSomeNoise(); <span><span>// soundManager.createSound(), etc.</span></span>
+}
+
+soundManager.onerror = function() {
+ <span><span>// SM2 could not start, no sound support, something broke etc. Handle gracefully.</span></span>
+ disableSoundInMyApp(); <span><span>// for example</span></span>
+}</code></pre>
+
+ <h4 id="lazy-loading">Lazy-loading SM2 (deferred start-up): SM2_DEFER</h4>
+
+ <p>Let's say you wanted to load and start SM2 after your page has loaded, using Javascript to insert a script node etc., or otherwise only start SM2 conditionally. You can edit soundmanager2.js and take out the SoundManager() constructor call at the bottom, <i>or</i> set the global variable SM2_DEFER = true which will have the same effect.</p>
+ <p>Example:</p>
+
+<pre class="block"><code>function lazy_load_sm2() {
+ window.SM2_DEFER = true;
+ <span><span>// -- load soundmanager2.js via <script>, createElement('script') or XHR etc. --
+ // imaginary load_script() function ..</span></span>
+ load_script('<span>/path/to/soundmanager2.js</span>', function() {
+ <span><span>// once soundmanager2.js has loaded and has parsed, construct + init.</span></span>
+ window.soundManager = new SoundManager(); <span><span>// Flash expects window.soundManager.</span></span>
+ soundManager.beginDelayedInit(); <span><span>// start SM2 init.</span></span>
+ });
+}</code></pre>
+
+ <p>For a live demo, check out the <a href="../../demo/template/deferred-example.html" title="SoundManager 2 deferred loading example">deferred loading example</a>.</p>
+
+ </div>
+
+
+ </div>
+
+ </div>
+
+ <div class="columnar">
+
+ <div class="c1">
+ <h2>Sound Options Object Format</h2>
+ <p>Object Literal, JSON-style data passed to <code>createSound()</code> and <code>play()</code></p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block s-onload"> <!-- f-createsound s-sid s-url s-autoload s-autoplay s-onload -->
+
+ <h3 id="object-literal-format">Object Literal Format</h3>
+
+ <p>Sounds can be created with instance-specific parameters in an object literal (JSON-style) format, where omitted parameters inherit default values as defined in soundManager.</p>
+
+<pre class="block"><code>soundManager.createSound({
+ id: '<span>mySound</span>',
+ url: '<span>/path/to/some.mp3</span>',
+ autoLoad: <span>true</span>,
+ autoPlay: <span>false</span>,
+ onload: <span>function() {
+ alert('<span>The sound </span>'+<span>this.sID</span>+'<span> loaded!</span>');
+ }</span>,
+ volume: <span>50</span>
+</span>});</code></pre>
+
+ <p>This object can also be passed as an optional argument to the <code class="in">play</code> method, overriding options set at creation time.</p>
+
+ <p>For a full list of available options, see <a href="../#sound-properties" title="SoundManager 2 API info: Sound Properties" onclick="resetFilter()">Sound Properties Object</a></p>
+
+ </div>
+
+
+ </div>
+
+ </div>
+
+ <div class="columnar">
+ <div class="c1">
+ <h2>"Use Responsibly"</h2>
+ <p>Only you can prevent audio pollution?</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block">
+
+ <h3>A Word Of Vice</h3>
+ <p>Not every button, link, element or paragraph on the web needs to zoom, move, change colour <em>and</em> be noisy, repetitive and annoying all at the same time. Use your own discretion!</p>
+ <p>Sites which automatically start playing background sound, and/or don't have volume or mute controls are the kind of things you should avoid building. As a developer, gentle reader, you may eventually find yourself in such a situation. Please do your part in enhancing the web with sound if you use SM2, while at the same time keeping it audibly usable. :)</p>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div id="troubleshooting" class="columnar">
+
+ <div id="troubleshooting-flash8" class="c1">
+ <h2 id="troubleshooting-flash9">Troubleshooting</h2>
+ <p>Console-style messaging, useful for troubleshooting start-up and runtime issues.</p>
+ </div>
+
+ <div id="troubleshooting-flash9-highperformance" class="c2">
+
+ <h3>SoundManager 2 Start-up and Debug Tools</h3>
+ <p>This troubleshooting tool can come in handy for debugging SM2 start-up problems.</p>
+
+ <p class="note">Flash options: <a href="#troubleshooting-flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (default), <a href="#troubleshooting-flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal) or <a href="#troubleshooting-flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance + fastPolling</a> modes.</p>
+
+ <div id="sm2-test">
+ <ul class="items">
+
+ <li id="d-onload" class="default">
+ <h3><span class="yay">OK</span><span class="boo">FAIL</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>SoundManager 2 start-up</span></h3>
+ <div id="sm2-startup" class="details">
+ <p>soundManager.onload() or soundManager.onerror() is ultimately called when start-up completes.</p>
+ <p>If you're seeing a failure, refer to the below for troubleshooting details for common causes.</p>
+ </div>
+ </li>
+
+ <li id="d-hasflash" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash</span></h3>
+ <div class="details">
+ <p>The Flash 8 plugin is a minimal requirement for SoundManager 2, but the exact requirement varies based on soundManager.flashVersion. You are currently using <b id="d-flashversion">[unknown]</b>.</p>
+ </div>
+ </li>
+
+ <li id="d-swf" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash SWF</span></h3>
+ <div class="details">
+ <p>SoundManager 2 must load a flash movie before initialisation can proceed. If you have errors here, check that soundManager.url is correctly defined and that the URL being loaded is correct.</p>
+ <p>If the Flash movie URL is OK, Flash security or flash blockers are the likely cause. Check the section below.</p>
+ </div>
+ </li>
+
+ <li id="d-flashtojs" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash -> JS</span></h3>
+ <div class="details">
+ <p>Once the flash component of SM2 has loaded, it tries to make a call to Javascript-land. This is a common point of failure, for security reasons.</p>
+ <ul>
+ <li>
+ <p><b>Have a flash blocker?</b> Check that the <a href="#flashdebug">SM2 flash movie</a> (below) is loading and is not being blocked.</p>
+ </li>
+ <li>
+ First time opening SM2 after downloading it? Is your browser URL at file:// or c:/path/ or otherwise not using HTTP? Flash security "whitelisting" is required to allow Flash + JS to work when offline, placing it in the "LocalTrusted" Flash security sandbox rather than "localWithFile".
+
+ <div id="d-flashtojs-offline" style="padding-bottom:1em">
+ <h4>Offline viewing: Adding a "trusted location" to the Flash Security Settings Panel</h4>
+ <p>The Flash Player Global Security Settings Panel is a web-based control panel which allows you to configure Flash security. You will need to add the path of the SoundManager 2 project in order for it to work "offline" (ie., when viewing via file:// or c:/)</p>
+ <p id="ss"><a href="#screenshots" onclick="document.getElementById('ss-box').style.display = 'block';document.getElementById('ss').style.display='none';return false">Show me how</a>: Adding a "trusted location"</p>
+ <div id="ss-box" style="display:none">
+ <h4>Illustrated guide: Adding a "trusted location" in Flash</h4>
+ <p>Below: Adding a location, and selecting "Browse for folder" (or directory), to whitelist the SoundManager 2 project directory for offline viewing.</p>
+ <p><img src="../../troubleshoot/fpgss-add-location.png" alt="Adding a location: Browse for the file or directory to whitelist" style="width:100%;_width:auto;min-width:72px;max-width:396px" /></p>
+ <p><img src="../../troubleshoot/fpgss-added-location.png" alt="Whitelisted location has now been added, JS + Flash will work under this path" style="width:100%;_width:auto;min-width:72px;max-width:396px" /></p>
+ </div>
+ <p><a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html" target="_blank" class="feature">Launch the Flash Security Settings Panel</a></p>
+ </div>
+
+ </li>
+ <li style="margin-top:0.5em">Flash blockers (FlashBlock, "click to flash" etc.) preventing flash load and start-up - need whitelisting/"allow this domain" to work smoothly. If you suspect blocking is the issue, try the <a href="../../demo/flashblock/">SoundManager 2 Flashblock demo</a>.</li>
+ <li style="margin-top:0.5em">Online viewing (HTTP/S): Same-domain security rules apply to HTML + Flash content by default (crossdomain.xml/allowDomain() in .AS source required to override.)</li>
+ </ul>
+ <p>See <a href="#flashdebug" title="SoundManager 2 flash debug output">Flash debug output</a> for more security error details.</p>
+
+ <div id="d-flashtojs-online">
+ <h4>Online viewing: Cross-domain security restrictions</h4>
+ <p>HTML page on domain A loading .SWF from domain B: Flash security prevents JS + Flash when a cross-domain XML permission file is not available on domain B, and/or flash movie was not compiled with allowDomain('domainA') or allowDomain('*') - note that the SWF distributed with SM2 does not use this by default; try using the cross-domain version of the SWF, or compile your own which whitelists your own domain(s).</p>
+
+ <h4>Flash Blockers</h4>
+ <p>Browser extensions/add-ons like "FlashBlock" and "click to flash" can prevent the .SWF from loading, and this will mean SM2 will time-out and fail waiting for a response from Flash. For development, it's best to whitelist the domain(s) or the .SWF for SM2 to allow it to work.</p>
+ <p>Have a flash blocker installed? Want to test it? Try the <a href="../../demo/flashblock">SoundManager 2 Flashblock demo</a>.</p>
+
+ </div>
+
+ </div>
+ </li>
+
+ <li id="d-jstoflash" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>JS -> Flash</span></h3>
+ <div class="details">
+ <p>At this point, Javascript attempts to respond to Flash's initial outgoing Flash -> JS call, completing the test for JS/flash communication. If SM2 does not receive a response from flash, it will eventually fail.</p>
+ <p>Offline viewing conditions and cross-domain security rules will prevent Flash <-> JS communication. See the details of Flash -> JS for information.</p>
+ </div>
+ </li>
+
+ <li id="d-soundtest" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Sound test</span></h3>
+ <div class="details">
+ <p>Here, a simple createSound() call is made to test SM2's actual operation. A sound should load and play provided SM2 was able to start successfully.</p>
+ </div>
+ </li>
+
+ </ul>
+ </div>
+
+ <p>Flash detection code from <a href="http://www.featureblend.com/javascript-flash-detection-library.html" title="Javascript flash detection library">Flash Detect</a> (featureblend.com)</p>
+
+ <h3 id="flashdebug">Flash Movie Debug Output</h3>
+ <p>When <code>soundManager.debugFlash = true</code>, Flash will write debug info as text to the flash movie. This can be helpful for troubleshooting Flash/JS issues when timeouts or security errors are involved which prevent Flash from talking to Javascript, potentially hiding useful debug information. A CSS class of <code>flash_debug</code> will also be appended to the Flash <code>#sm2-container</code> DIV element when enabled, if you wish to style it differently.</p>
+ <p>You can also specify ?debug=1 in the URL to the SWF, and it will write debug output. Try <a href="../../swf/soundmanager2_debug.swf?debug=1" title="Test debug output" class="norewrite">soundmanager2_debug.swf?debug=1</a>, or <a href="../../swf/soundmanager2_flash9_debug.swf?debug=1" title="Test debug output, Flash 9" class="norewrite">soundmanager2_flash9_debug.swf?debug=1</a>.
+
+ <div id="sm2-container">
+ <!-- flash movie with debug output goes here -->
+ </div>
+
+ <h3>Live Debug Output</h3>
+ <p>SoundManager 2 relies on Javascript and Flash communicating via ExternalInterface, and this is subject to a number of timing, loading and browser security conditions. Because of this complexity, debug information is essential for troubleshooting start-up, loading, initialization and error conditions between Flash and Javascript.</p>
+ <p class="in">With debug mode enabled via <code>soundManager.debugMode = true</code>, SM2 can write helpful troubleshooting information to javascript <code>console.log()</code>-style interfaces. Additionally, output can be written to an optional DIV element with the ID of "<code>soundmanager-debug</code>".</p>
+ <p>If loading from the local filesystem (offline eg. file://, not over HTTP), Flash security is likely preventing SM2 from talking to Javascript. You will need to add this project's directory to the trusted locations in the <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">Flash global security settings panel</a>, or simply view this page over HTTP.</p>
+ <p>Below is a live example of debug output.</p>
+ <div id="live-debug" class="block">
+ <div id="soundmanager-debug" class="code">
+ <!-- live debug goes here -->
+ </div>
+ </div>
+ <p>For more examples of live debug output, see the <a href="../../demo/template/" title="Basic SoundManager 2 template">Basic Template</a>, <a href="../../demo/api/" title="API demo">API demo</a> and other demos in the top navigation.</p>
+
+ <h3>Standalone version of troubleshooting tool</h3>
+ <p class="in">For debugging your development/production environment with this widget, see the <a href="../../troubleshoot/" title="SoundManager 2: Standalone debug widget">troubleshooting</a> subdirectory of the SoundManager 2 package.</p>
+
+ </div>
+
+ </div>
+
+ <div id="col3" class="c3">
+
+
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2" rel="nofollow">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ <!-- /.box -->
+
+ </div>
+
+ <div id="shortcuts">
+
+ </div>
+
+
+
+ </div>
+
+ <div class="clear"></div>
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+<script type="text/javascript">
+init();
+sm2DebugInit();
+</script>
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/doc/index.html b/docs/dymaxion/soundmanagerv297a-20101010/doc/index.html new file mode 100755 index 0000000..9411539 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/doc/index.html @@ -0,0 +1,1667 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Documentation</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="API documentation for SoundManager 2, a JavaScript-based MP3 and MP4 audio API. BSD licensed." />
+<meta name="keywords" content="javascript sound, javascript audio, documentation, api documentation, soundmanager 2" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../demo/index.css" />
+<link rel="stylesheet" type="text/css" media="screen" href="../demo/flashblock/flashblock.css" />
+<script type="text/javascript" src="../script/soundmanager2.js"></script>
+<script type="text/javascript" src="../demo/index.js"></script>
+<script type="text/javascript">
+ soundManager.useFlashBlock = false;
+ soundManager.debugMode = false;
+ soundManager.url = '../swf/';
+ soundManager.onload = function() {
+ }
+</script>
+</head>
+
+<body id="doc">
+
+<div id="content">
+
+ <div id="top">
+
+ <h1>SoundManager 2: Documentation</h1>
+
+ <div id="nav">
+ <ul>
+
+ <li>
+ <a href="..">Home</a>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="../demo/api/">API Examples</a></li>
+ <li><a href="../demo/play-mp3-links/" class="exclude">Playable MP3 links</a></li>
+ <li><a href="../demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="../demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="../demo/360-player/">360° Player UI</a></li>
+ <li><a href="../demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="../demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="../demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="../demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="getstarted/">Getting Started</a>
+ <ul>
+ <li><a href="getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <strong><a href="#">Documentation</a></strong>
+ <ul>
+ <li><a href="#sm-config">SoundManager Properties</a></li>
+ <li><a href="#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="#api">SoundManager Core API</a></li>
+ <li><a href="#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="download/">Download</a>
+ <ul>
+ <li><a href="download/#latest">Get SoundManager 2</a></li>
+ <li><a href="download/#revision-history">Revision History</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="technotes/">Technical Notes</a>
+ <ul>
+ <li><a href="technotes/#requirements">System Requirements</a></li>
+ <li><a href="technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="resources/">Resources</a>
+ <ul>
+ <li><a href="resources/#licensing">Licensing</a></li>
+ <li><a href="resources/#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+
+ <div id="filter-box" class="columnar">
+
+ <div class="c1">
+ <div id="reset-filter"></div>
+ </div>
+
+ <div class="c2">
+ <div id="search-results"><!-- search results for %s --></div>
+ </div>
+
+ </div>
+
+ <div id="soundmanager-properties" class="columnar">
+ <div class="c1">
+ <h2>SoundManager Configuration</h2>
+ <p>Flash URLs, version + performance options</p>
+ </div>
+ <div class="c2">
+
+ <h3>SoundManager Properties</h3>
+
+ <div class="f-block f-useconsole f-consoleonly f-waitforwindowload f-allowpolling f-nullurl f-usemoviestar f-allowscriptaccess">
+
+ <p class="in">SoundManager has properties which configure debug mode, flash movie path and other behaviours. At minimum, the <code>soundManager.url</code> property must be assigned a path used to look for the necessary flash movie.</p>
+
+<pre class="small block specialcommentblock"><code><span>allowPolling = true; <span>// enable flash status updates. Required for whileloading/whileplaying.</span>
+consoleOnly = false; <span>// if console is being used, do not create/write to #soundmanager-debug</span>
+debugMode = true; <span>// enable debugging output (div#soundmanager-debug, OR console..)</span>
+debugFlash = false; <span>// enable debugging output inside SWF, troubleshoot Flash/browser issues</span>
+flashLoadTimeout = 1000; <span>// ms to wait for flash movie to load before failing (0 = infinity)</span>
+flashVersion = 8; <span>// version of flash to require, either 8 or 9. Some features require 9.</span>
+nullURL = 'about:blank'; <span>// (Flash 8 only): URL of silent/blank MP3 for unloading/stop request.</span>
+url = '/path/to/swfs/'; <span>// path (directory) where SM2 .SWF files will be found.</span>
+useConsole = true; <span>// use firebug/safari console.log()-type debug console if available</span>
+useMovieStar = true; <span>// enable <a href="http://www.adobe.com/support/documentation/en/flashplayer/9/releasenotes.html#fixes_90115">Flash 9.0r115+</a> MPEG4 audio support</span>
+useFastPolling = false; <span>// fast timer=higher callback frequency, combine w/useHighPerformance</span>
+useHighPerformance = false;<span>// position:fixed flash movie for faster JS/flash callbacks</span>
+waitForWindowLoad = false; <span>// always delay soundManager.onload() until after window.onload()</span>
+wmode = 'transparent'; <span>// null, transparent, opaque (last two allow HTML on top of flash)</span>
+allowScriptAccess = 'always'; <span>// for scripting SWF (object/embed prop.), 'always' or 'sameDomain'</span>
+useFlashBlock = true; <span>// better handling of SWF if load fails, let user unblock. See <a href="../demo/flashblock/" title="SoundManager 2 flash block demo">demo</a>.</span>
+useHTML5Audio = false; <span>// <a href="#soundmanager-usehtml5audio">beta feature</a>: Use HTML5 Audio() where supported.</span>
+</span></code></pre>
+ <p>To modify global SoundManager default parameters for SM2 itself or for all sound objects, edit the main soundmanager2.js file (look for above section in code) or assign new values in your own application script before either <code class="in">onDOMContentLoaded()</code> or <code class="in">window.onload()</code> fire. (Specifically, both external and inline script blocks which immediately execute are OK.)</p>
+ <p>Example per-application override:</p>
+<pre class="block"><code><span>soundManager.debugMode = false; <span>// disable debug mode</span>
+soundManager.defaultOptions.volume = 33; <span>// set global default volume for all sound objects</span>
+</span></code></pre>
+
+ </div>
+
+ <div class="f-block f-debugmode">
+ <h4 id="soundmanager-debugmode">soundManager.debugMode</h4>
+ <p class="in"><code>soundManager.debugMode</code> configures SM2's debug behaviour, enabled (true) by default. When enabled, SoundManager 2 will write console-like output to <code>console.log()</code>-style javascript interfaces, and/or an HTML element with the ID <code>soundmanager-debug</code> (will be created if not found in the DOM at runtime.)</p>
+ <p>For a live example of debug output, see <a href="technotes/#debug-output" title="SoundManager 2 debug output demo">Debug + Console Output</a>.</p>
+ </div>
+
+ <div class="f-block f-debugflash">
+ <h4 id="soundmanager-debugflash">soundManager.debugFlash</h4>
+ <p class="in"><code>soundManager.debugFlash</code> configures SM2's flash debugging output, disabled (false) by default. When enabled, the Flash portion of SM2 will write debug statements within the Flash movie. This can be useful for troubleshooting Flash/JS/browser (ExternalInterface) issues and so on.</p>
+ <p>A CSS class of <code>flash_debug</code> will also be appended to the Flash <code>#sm2-container</code> DIV element when enabled, if you wish to style it differently.</p>
+ <p>For a live example, see <a href="getstarted/#flashdebug" title="SoundManager 2 flash debug output demo">Flash Movie Debug Output</a> in the Troubleshooting section.</p>
+ </div>
+
+ <div class="f-block f-url">
+ <h4 id="soundmanager-url">soundManager.url</h4>
+ <p class="in"><code>soundManager.url</code> specifies the "online", generally HTTP-based path which SM2 will load .SWF movies from. The "local" (current) directory will be used by default. The appropriate .SWF required (depending on the desired Flash version) will be appended to the URL.</p>
+ <p class="in">Example: <code>soundManager.url = '/path/to/swfs/';</code> (Note trailing slash)</p>
+ <p class="in">For cases where SM2 is being used "offline" in non-HTTP cases (eg., development environments), see <code>altURL</code>.</p>
+ </div>
+
+ <div class="f-block f-alturl">
+ <h4 id="soundmanager-alturl">soundManager.altURL</h4>
+ <p class="in"><code>soundManager.altURL</code> specifies an alternate path to <code>soundManager.url</code> which SM2 can load its SWF from. It is a simple convenience for when you may need to load SWFs from different paths depending on your hosting environment (eg., offline development vs. production.)</p>
+ <p class="in">Example: <code>soundManager.altURL = '../';</code> (Load from parent directory - note trailing slash)</p>
+ <p class="in">For altURL to be used, it must be defined and an "alternate environment" condition must be met:</p>
+ <p class="in"><code>soundManager.useAltURL = (!document.location.protocol.match(/http/i));</code></p>
+ <p>By default and as shown above, SM2 will use this property when the hosting page is not being served over HTTP, and thus is assumed to being served "offline" - for example, when loading via file://, from the local file system.</p>
+ <p>This can easily be adapted to taste, eg., checking the domain matching yourdomain.com vs. localhost:</p>
+ <p class="in"><code>soundManager.useAltURL = (!document.location.match(/mydomain.com/i));</code></p>
+ <p class="in">If <code>soundManager.altURL</code> is null (the default), <code>soundManager.url</code> will be used for all cases.</p>
+ </div>
+
+ <div class="f-block f-flashversion">
+
+ <h4 id="soundmanager-flashversion">soundManager.flashVersion</h4>
+
+ <p class="in">SoundManager 2 started with a Flash 8 base requirement, but can also now use Flash 9 and take advantages of some new features Flash 9 offers. By default Flash 8 will be used, but the version can be easily changed by setting <code>flashVersion</code> appropriately.</p>
+
+ <p class="in">Example: <code>soundManager.flashVersion = 9;</code></p>
+
+ <p class="in">The Flash 8 version is <code>soundmanager2.swf</code>, and the flash 9 version is <code>soundmanager2_flash9.swf</code>, accordingly. Note that only Flash 8 and Flash 9 are supported at this time; other values will result in errors.</p>
+
+ </div>
+
+
+ <div class="f-block f-flashversion">
+
+ <p>New Flash 9-only features:</p>
+
+ <ul>
+ <li class="in">MPEG-4 (HE-AAC/H.264) audio support</li>
+ <li class="in">True "multi-shot" sound behaviour. <code>play()</code> can be called multiple times, giving a layered, "chorus" effect. Sound will also fire <code>onfinish()</code> multiple times. (Previous behaviour did not layer sounds, but would re-play a single instance.)</li>
+ <li class="in"><code>waveformData</code> array: 256 waveform data values available while playing sound</li>
+ <li class="in"><code>eqData</code> array: 256 EQ spectrum data values available while playing sound</li>
+ <li class="in"><code>peakData</code> object: Left and right channel peak/volume data available while playing sound</li>
+ </ul>
+
+ </div>
+
+
+ <div class="f-block f-flashloadtimeout">
+ <h4 id="soundmanager-flashloadtimeout">soundManager.flashLoadTimeout</h4>
+ <p class="in">After initializing the flash component during start-up, SM2 will wait for a defined period of time before timing out and calling <code>soundManager.onerror()</code>.</p>
+ <p>The default value is 1000 (msec.) Setting a value of 0 disables the timeout and makes SM2 wait indefinitely for a call from the flash component. If you want to handle flash block-type situations, see <a href="#soundmanager-useflashblock" onclick="resetFilter()">soundManager.useFlashBlock</a>.</p>
+ <p>Setting this parameter to 0 may be useful when attempting to gracefully recover from a flashBlock situation, where the user has whitelisted the movie after it was blocked etc.</p>
+ <p>Note that when the timeout is disabled, soundManager will not fire its onerror() handler if there is an error at the flash loading stage.</p>
+ </div>
+
+ <div class="f-block f-usefastpolling f-usehighperformance">
+ <h4 id="soundmanager-usefastpolling">soundManager.useFastPolling</h4>
+ <p>By default <code>useFastPolling = false</code>, and thus SoundManager uses a 20-milisecond timer inside Flash when polling for updated sound properties such as <code>bytesLoaded</code> and data and event callbacks eg. <code>whileloading()</code>, <code>whileplaying()</code> and so on. With <code>useFastPolling = true</code>, a 1-msec timer is used and callback frequency may noticeably increase. This is best combined with <code>useHighPerformance</code> for optimal results.</p>
+ </div>
+
+ <div class="f-block f-usehighperformance f-usefastpolling">
+ <h4 id="soundmanager-highperformance">soundManager.useHighPerformance</h4>
+ <p>Perhaps intuitively, Flash is given higher priority when positioned within the viewable area of the browser, at least 6px in height (oddly), fully-opaque, visible and displayed on the screen. By default, <code class="in">soundManager.useHighPerformance</code> is enabled and should noticeably reduce JS/flash lag and increase the frequency of callbacks such as <code class="in">whileplaying()</code> in some circumstances.</p>
+ <p><code class="in">soundManager.useHighPerformance = true;</code></p>
+ <p>This has made a noticeable impact in responsiveness on Mac OS X, and Safari on Windows; animation lag is practically non-existent (see <a href="../demo/animation-2b/" title="SoundManager JS + DOM + sound demo 2b" style="display:inline" onclick="checkDomain(this)">demo</a>). Because setting wmode=transparent and fixed position has been reported to cause some issues, the feature is disabled by default.</p>
+ <p>To be least-obtrusive, SM2 attempts to set position:fixed, and uses bottom/left:0px to stay within view (though using wmode=transparent where possible, to be hidden from view.) It occupies an 8x8px square. If you wish to position the movie yourself or show it inline, have a DIV element with the ID of <code class="in">sm2-container</code> present in the DOM for SM2 to reference and it will write the movie there without positioning.</p>
+ </div>
+
+ <div class="f-block f-useflashblock">
+ <h4 id="soundmanager-useflashblock" title="Recently-added feature" class="recent">soundManager.useFlashBlock</h4>
+ <p>Flash blockers (eg. FlashBlock, "Click To Flash") can prevent the flash portion of SM2 from loading, which will cause a start-up error with a time-out.</p>
+ <p>SM2 historically has kept the flash movie off-screen and out of view, and thus the user could not click on and unblock it. Now with <code>useFlashBlock = true</code>, the movie positioning can be handled by CSS. The initial state is still off-screen by default, but will change to be in view when a blocking (time-out) situation may be encountered. You can also edit the CSS to taste, of course.</p>
+ <p>When starting up, CSS classes are appended to the <code>#sm2-container</code> DIV (which you can provide, or SM2 will create and append to the document.) The CSS classes change with the state of SM2's start-up, eg. <code>#sm2-container.swf_timedout { border:1px solid red; }</code> could be used to highlight the movie to the user for unblocking and so on.</p>
+ <p>Setting <code>useFlashBlock = true</code> will cause SM2 to wait infinitely for the Flash content to load after an initial (non-fatal) timeout, having already waited for <code>flashLoadTimeout</code> to pass. If <code>flashLoadTimeout = 0</code>, SM2 will immediately go into "flash block mode" on start-up.</p>
+ <p>The relevant CSS is as follows:</p>
+<pre class="block"><code>#sm2-container {
+ <span><span>/* Initial state: position:absolute/off-screen, or left/top:0 */</span></span>
+}
+#sm2-container.swf_timedout {
+ <span><span>/* Didn't load before time-out, show to user.
+ Maybe highlight on-screen, red border, etc..? */</span></span>
+}
+#sm2-container.swf_unblocked {
+ <span><span>/* Applied if movie loads successfully
+ (flash started, so move off-screen etc.) */</span></span>
+}
+#sm2-container.swf_error {
+ <span><span>/* "Fatal" error case: SWF loaded,
+ but SM2 was unable to start for some reason.
+ (Flash security or other error case.) */</span></span>
+}
+#sm2-container.high_performance {
+ <span><span>/* Additional modifier for "high performance" mode
+ should apply position:fixed and left/bottom 0 to stay on-screen
+ at all times (better flash performance) */</span></span>
+}
+#sm2-container.flash_debug {
+ <span><span>/* Additional modifier for flash debug output mode
+ should use width/height 100% so you can read debug messages */</span></span>
+}</code></pre>
+
+ <p>For a live example, see the <a href="../demo/flashblock/">FlashBlock Demo</a>.</p>
+ </div>
+
+ <div class="f-block f-usehtml5audio">
+
+ <h4 id="soundmanager-usehtml5audio">soundManager.useHTML5Audio</h4>
+
+ <p><em><b style="color:#993333">Warning: Beta-ish, in-progress feature</b>; subject to bugs, API changes etc. By default, special check to enable feature for the Apple iPad 3.2+ (which does not support Flash) and Palm Pre, otherwise currently disabled by default. Works on iPhone OS 4.0 / iOS 4.0+.</em></p>
+ <p>Determines whether HTML5 <code>Audio()</code> support is used to play sound, if available, with Flash as the fallback for playing MP3/MP4 (AAC) formats. Browser support for HTML5 Audio varies, and format support (eg. MP3, MP4/AAC, OGG, WAV) can vary by browser/platform.</p>
+ <p>The SM2 API is effectively transparent, consistent whether using Flash or HTML5 <code>Audio()</code> for sound playback behind the scenes. The HTML5 Audio API is roughly equivalent to the Flash 8 feature set, minus ID3 tag support and a few other items. (Flash 9 features like waveform data etc. are not available.)</p>
+
+ <h5>SoundManager 2 + useHTML5Audio: Init Process</h5>
+
+ <p>At DOM ready (if useHTML5Audio = true), a test for <code>Audio()</code> is done followed by a series of <code>canPlayType()</code> tests to see if MP3, MP4, WAV and OGG formats are supported. If none of the "required" formats (MP3 + MP4, by default) are supported natively, then Flash is also added as a requirement for SM2 to start.</p>
+ <p><code>soundManager.audioFormats</code> currently defines the list of formats to check (MP3, MP4 and so on), their possible <code>canPlayType()</code> strings (long story short, it's complicated) and whether or not they are "required" - that is, whether Flash should be loaded if they don't work under HTML5. (Again, only MP3 + MP4 are supported by Flash.) If you had a page solely using OGG, you could make MP3/MP4 non-required, but many browsers would not play them inline.</p>
+ <p>SM2 will indicate its state (HTML 5 support or not, using Flash or not) in <code>console.log()</code>-style debug output messages when <code>debugMode = true</code>.</p>
+
+ <h5>"My browser does HTML5, why not MP3"?</h5>
+
+ <p>Despite best efforts, some browsers eg. Chrome on Windows may only return "maybe" for <code>Audio().canPlayType('audio/mpeg; codecs=mp3')</code> and variants; by default, SoundManager 2 will only assume a format is supported if a "probably" response is given. You can modify <code>soundManager.html5Test</code> to something like <code>/(probably|maybe)/i</code> if you want to be a bit riskier, but you should consider potential false positives.</p>
+
+ <p>At this time, only Safari and Chrome (excluding Chromium?) support MP3 and MP4 formats. Other browsers have excluded them because MP3 and MP4 are not "free" formats. For these cases, Flash is used as the fallback support for MP3/MP4 as needed.</p>
+
+ <h5>Bonus HTML5 formats: OGG, WAV</h5>
+
+ <p>WAVe (an old standard) and OGG (a MP3-like codec, except free) are both supported in a majority of browsers via HTML5, so SoundManager 2 will also test for support for these formats. A Flash fallback for these formats has not been implemented.</p>
+
+ <h5>Testing audio format support</h5>
+
+ <p>Once <code>soundManager.onready()</code> has fired and SM2 has started, you can check for support via a number of methods. Namely, <a href="#soundmanager-canplaylink">soundManager.canPlayLink()</a> will take an <code><a></code> element and check its <code>href</code> and <code>type</code> attributes, if available, for hints as to its format or type. You can also pass arbitrary URLs to <a href="#soundmanager-canplayurl">soundManager.canPlayURL()</a>, which will make a "best guess" based on the extension it finds. In any event, SM2 will return a true/false value from canPlay methods based on HTML and/or flash capabilities.</p>
+
+ <p>To see what formats are supported by HTML5, watch SM2's debug/console output when debug is enabled, or dump the contents of <code>soundManager.html5</code> to the console; it will show the results of tests for simple items like "mp3", as well as <code>canPlayType()</code> strings such as 'mpeg; codecs=mp3'
+
+ <h5>Apple iPad, iPhone, Palm Pre: Special Cases</h5>
+ <p>The "Big iPhone" doesn't do Flash, and does support HTML5 <code>Audio()</code> pretty decently - so SM2 makes a special exception to enable <code>useHTML5Audio</code> when it detects an iPad, iPhone or Palm Pre user agent string by default. Feel free to disable this if you wish.</p>
+ <p>iPad and iPhone require user interaction to start a sound, eg. the createSound() and play() call should happen within an onclick() handler on a link, etc. The "security" model here seems to be implemented similarly to the way pop-up blockers work. You may "chain" sounds (eg. create and play a new one) provided it is done via the onfinish() event of a sound initiated by a user, however. The Muxtape-style demo on the SM2 homepage uses this, and will advance the playlist on the iPad/iPhone if allowed.</p>
+ <p>iPad 3.2 gets hung up on the "BC quail" HE-AAC example sound for some reason, and endlessly loops it rather than finishing and moving on to the next item. May be an iPad playback bug, as other formats are fine. iPhone OS 4 (iOS 4) does not show this issue.</p>
+ <p>iPhone OS version < 3.1 doesn't work, but 3.1 (and possibly earlier versions, not verified) have a native <code>Audio()</code> object. However, they seem to simply not play sound when <code>play()</code> is called, so SM2 looks for and ignores the iPhone with these OS revisions.</p>
+ <p>The Palm Pre <a href="http://developer.palm.com/index.php?option=com_content&view=article&id=1741&Itemid=265#using_html_5_audio_objects" title="Palm Developer Center: Audio">supports</a> a number of MP3, MP4 and WAV formats (WebOS 1.4.1 was tested; it didn't seem to like MP3s at 192kbps, but 128kbps was fine.)</p>
+
+ <h5>Known HTML5 Audio bugs/limitations/annoyances</h5>
+
+ <p>As of the October, 2010 release of SM2 (V2.97a.20101010):</p>
+ <ul>
+ <li>HTML5 audio is disabled for all versions of Safari (4 and 5) on Snow Leopard (OS X 10.6.3 and 10.6.4) until Apple fixes issues with audio loading and playback due to bugs in "underlying frameworks." See <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c9" title="Safari Snow Leopard HTML5 Audio Bug">Webkit #32159</a>.</li>
+ </ul>
+
+ <p>As of the August, 2010 release of SM2 (V2.96a.20100822):</p>
+ <ul>
+ <li>Safari 5.0.1 (533.17.18) on Snow Leopard (10.6.x) continues to show buggy HTML5 audio load/playback behaviour. Apple are aware of the regression, which began with Safari 4.0 on Snow Leopard (perhaps with the new QuickTime.) See <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c9" title="Safari Snow Leopard HTML5 Audio Bug">Webkit #32159</a>.</li>
+ <li>iPad/iPhone iOS4 will now play a sequence of sounds if using <code>onfinish()</code> to create/start the next (eg., the Muxtape-style playlist on the SM2 homepage will play through once the user starts it.) In any event, user interaction is always required to start the first sound.</li>
+ </ul>
+
+ <p>As of the June, 2010 release of SM2 (V2.96a.20100624):</p>
+ <ul>
+ <li>Safari 5.0 (533.16) on OS X Snow Leopard (10.6.x) continues to show buggy HTML5 audio load/playback behaviour, same as with Safari 4.0.5 on Snow Leopard only - may be related to underlying QuickTime implementation (a guess, at this point.) SM2 will disable HTML5 audio support by default for this specific browser + OS combo. See <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c9" title="Safari Snow Leopard HTML5 Audio Bug">Webkit #32159</a> for discussion + testcases.</li>
+ </ul>
+
+ <p>As of the May, 2010 release of SM2 (V2.96a.20100520):</p>
+ <ul>
+ <li>Safari 4.0.5 on OS X Snow Leopard (10.6.x) appears to have an annoying bug where audio inconsistently fails to load / play; SM2 will currently disable or ignore the HTML5 feature on this exact browser + OS version. See <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c9" title="Safari Snow Leopard HTML5 Audio Bug">Webkit #32159</a> for discussion + testcases. Note that Safari on OS X 10.5 "Leopard" and on Windows <i>do not</i> appear to have this bug; it seems to be limited to Snow Leopard, seen on OS X 10.6.3.</li>
+ <li>Some browsers (and iPad 3.2?) do not fire <code>progress</code> events, and/or do not implement bytesLoaded/bytesTotal-style attributes.</li>
+ <li>iPad 3.2 appears to be able to only play one sound at a time, and will terminate other sounds.</li>
+ <li>iPad 3.2 may also loop AAC+ (HE-AAC) and WAV sounds, perhaps not firing onfinish() and resetting the position to 0 each time, but is fine with MP3s. This has been observed, but not fully-tested.</li>
+ <li>Looping in HTML5 is either "infinite" or "none". A wrapper may be created for SM2 so that a number of loops can be specified, as with Flash. This is not yet implemented.</li>
+ <li>Panning (left/right channel balance) does not appear to be in HTML5.</li>
+ <li>Flash-only features such as ID3 tag reading, waveform and spectrum data will simply be ignored, and their related events will not fire on SMSound objects which are using HTML5.</li>
+ </ul>
+
+ <h5>General Disclaimer</h5>
+ <p>HTML5 audio support may still be in flux, and may not be fully-supported or implemented consistently in modern browsers. Be careful out there.</p>
+ </div>
+
+ <div class="f-block f-wmode">
+ <h4 id="soundmanager-wmode">soundManager.wmode</h4>
+ <p>The <code>wmode</code> property is applied directly to the flash movie, and can be either <code>null</code>, <code>'window'</code>, <code>'transparent'</code> or <code>'opaque'</code>. By default if <code>useHighPerformance</code> is enabled, transparency will be attempted by SM2 unless there are known issues with the rendering mode.</p>
+ <p>It appears that non-IE browsers on Windows will not load SWF content "below the fold" (out of scrollable view) when wmode is set to anything other than null (window). This will break SM2 as it expects Flash to load within a reasonably short amount of time - so SM2 by default will reset wmode for this case. If you wish to force retention of your <code>wmode</code>, set <code>soundManager.flashTimeout = 0</code> which will ensure that if the content is below the fold, SM2 will not time out waiting for it to load.</p>
+ <p>Additionally, <code>soundManager.specialWmodeCase</code> will be set to <code>true</code> if wmode has been reset due to this special condition.</p>
+ </div>
+
+ </div>
+
+
+ </div>
+
+ <div id="api" class="columnar">
+
+ <div class="c1">
+ <h2>SoundManager Core API</h2>
+ <p>Methods for the soundManager object.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block">
+
+ <h3>SoundManager Global Object</h3>
+
+ <p>This is a collection of methods, collections, properties and event handlers available via the <span class="code">soundManager</span> Javascript object. Sound properties and methods can be set on a global (inherited) default, or per-sound basis.</p>
+
+ </div>
+
+ <dl id="soundmanager-canplaylink" class="f-block f-canplaylink" style="margin-top:2em">
+ <dt><span>canPlay:boolean</span> canPlayLink(<span><a>:DOM element</span>)</dt>
+ <dd>Normalized method which checks <code>canPlayMIME()</code> and <code>canPlayURL()</code> as needed to estimate the playability of an HTML link; this means both the <code>href</code> and <code>type</code> attributes, if provided, are checked for matching file extension and/or MIME type patterns.</dd>
+ <dd>Example:
+<pre class="block"><code><span><span>/* example links:
+ <a id="song1" href="/music/player.php?songID=1" type="audio/mp3">play song 1</a> <span>// type match</span>
+ <a id="song2" href="song2.mp3">play song 2</a> <span>// URL match</span>
+*/</span></span>
+var aLink = document.getElementById('<span>mySong</span>');
+if (soundManager.canPlayLink(aLink)) {
+ soundManager.play('<span>mySongSound</span>',aLink.href);
+}</code></pre></dd>
+ </dl>
+
+ <dl id="soundmanager-canplaymime" class="f-block f-canplaymime">
+ <dt><span>canPlay:boolean</span> canPlayMIME(<span>MIMEtype:string</span>)</dt>
+ <dd>Returns a boolean indicating whether soundManager can play the given MIME type - eg., <code>audio/mp3</code>. The types supported vary based on Flash version and MPEG4 (MovieStar mode) options.</dd>
+ <dd>
+ MIME type patterns are as follows:
+ <ul>
+ <li>Defaults: <code>/^audio\/(?:x-)?(?:mp(?:eg|3))\s*;?/i;</code> - eg. <code>audio/mp3</code> or <code>audio/mpeg</code></li>
+ <li>MovieStar-only formats: <code>/^audio\/(?:x-)?(?:mp(?:eg|3)|mp4a-latm|aac|speex)\s*;?/i; </code> - eg. <code>audio/m4a or audio/aac</code></li>
+ </ul>
+ </dd>
+ <dd>Example:
+<pre class="block"><code><span><span>// link example: <a id="song1" href="foo.php?songID=1" type="audio/mp3">play song 1</a></span></span>
+var aLink = document.getElementById('<span>song1</span>');
+if (soundManager.canPlayLink(aLink)) {
+ soundManager.play('<span>song1Sound</span>',aLink.href);
+}</code></pre></dd>
+ <dd>If no <code>type</code> attribute is found, this method will return <code>null</code> instead of <code>false</code>.</dd>
+ </dl>
+
+ <dl id="soundmanager-canplayurl" class="f-block f-canplayurl">
+ <dt><span>canplay:boolean</span> canPlayURL(<span>mediaURL:string</span>)</dt>
+ <dd>Returns a boolean indicating whether soundManager can play the given URL. Playability is determined by a matching URL pattern set at runtime, based on Flash version and MPEG4 (MovieStar mode) support.</dd>
+ <dd>Example:
+<pre class="block"><code>var sURL = '<span>/path/to/some.mp3</span>';
+if (soundManager.canPlayURL(sURL)) {
+ soundManager.createSound('<span>fooSound</span>',sURL);
+}</code></pre></dd>
+ <dd>If no <code>href</code> attribute is found, this method will return <code>null</code> instead of <code>false</code>.</dd>
+ </dl>
+
+ <dl id="soundmanager-createsound" class="f-block f-createsound s-autoplay">
+
+ <dt style="margin-top:2em"><span>object:SMSound </span>createSound(<span>object:options</span>)</dt>
+ <dd title="object:options">Creates a sound with an arbitrary number of optional arguments. Returns a <code>SMSound</code> object instance. Requires <code>id</code> and <code>url</code> at a minimum.</dd>
+ <dd>
+ Example:
+<pre class="block"><code>soundManager.createSound({<span>
+ id: 'mySound', <span>// required</span>
+ url: '/audio/mysoundfile.mp3', <span>// required</span>
+ <span>// optional sound parameters here, see <a href="#sound-properties" title="SoundManager 2 API Info: Sound Properties Object" onclick="resetFilter()">Sound Properties</a> for full list</span>
+ volume: 50,
+ autoPlay: true,
+ whileloading: soundIsLoading
+</span>});</code></pre>
+ <p>Each <code>createSound()</code> call results in the creation of a <code>SMSound</code> object which stores all properties, methods and events relevant to that particular sound instance.</p>
+ <p>Individual sound objects can also easily be referenced as returned from <code>createSound()</code>:</p>
+<pre class="block"><code>var mySoundObject = soundManager.createSound({<span>
+ id: 'mySound',
+ url: '/audio/mysoundfile.mp3'
+</span>});
+mySoundObject.play(); <span><span>// SMSound object reference, same as soundManager.getSoundById('mySound')</span></span></code></pre>
+
+ <p>(Note: Code formatting is stylistic, not necessarily recommended.) See <a href="#object-literal-format" title="SoundManager 2 API Info: Sound Properties Object" onclick="resetFilter()">Object Literal Format</a>.</p>
+ </dd>
+ <dd>If <code>createSound</code> is called with the ID of an existing sound, that sound object will be returned "as-is". Any other <code>createSound</code> options passed (eg., <code>url</code> or <code>volume</code>, etc.) will be ignored.</dd>
+
+ </dl>
+
+ <dl id="soundmanager-createsound-overloaded" class="f-block f-createsound">
+ <dt><span>object:SMSound </span>createSound(<span>id:string,url:string</span>) - overloaded method</dt>
+ <dd title="id:string,url:string">Creates a sound with the specified ID and URL (simple two-parameter method.)</dd>
+ <dd>Example: <code>soundManager.createSound('<span>mySound</span>','<span>/audio/mysoundfile.mp3</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-destroysound" class="f-block f-destroysound">
+ <dt>destroySound(<span>id:string</span>)</dt>
+ <dd title="id:string">Stops, unloads and destroys a sound specified by ID.</dd>
+ <dd>Example: <code>soundManager.destroySound('<span>mySound</span>');</code></dd>
+ <dd>SMSound equivalent example: <code>mySound.destruct();</code></dd>
+ </dl>
+
+ <dl id="soundmanager-mute" class="f-block f-mute">
+ <dt><span>object:SMSound </span>mute(<span>[id:string]</span>)</dt>
+ <dd title="id:string">Mutes the sound specified by ID and returns that sound object. If no ID specified, all sounds will be muted and null is returned. Affects <span>muted</span> property (boolean.)</dd>
+ <dd>Example: <code>soundManager.mute('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-onready" class="f-block f-onready">
+ <dt>onready(<span>callback:function(status),[scope]</span>)</dt>
+ <dd title="callback:function">Queue <code>onload()</code>-style event listener(s) processed at (or immediately, if added after) SM2 initialization, just before <code>soundManager.onload()</code> or <code>onerror()</code> are called. More flexible than single <code>soundManager.onload()</code> event, allows separate scripts to add listeners etc. An optional scope parameter can be specified; if none, the callback is scoped to the window.</dd>
+ <dd>Example: <code>soundManager.onready(<span>myOnReadyHandler</span>); soundManager.onready(<span>myOtherHandler</span>);</code></dd>
+ <dd>A "status" object is also passed to the callback, which can be safely ignored. It includes a "success" parameter, indicating the state of <code>soundManager.supported()</code>.</dd>
+ <dd>Example:
+<pre class="block"><code>soundManager.onready(<span>function(oStatus) {
+ if (oStatus.success) {
+ alert('Yay, SM2 loaded OK!');
+ } else {
+ alert('Oh snap, SM2 could not start.');
+ }
+}</span>);</code></pre>
+ <p>You may also check <code>soundManager.supported()</code> instead.</p>
+<pre class="block"><code>soundManager.onready(<span>function() {
+ if (soundManager.supported()) {
+ alert('Yay, SM2 loaded OK!');
+ } else {
+ alert('Oh snap, SM2 could not start.');
+ }
+}</span>);</code></pre>
+ </dd>
+ <dd>The same listener may be added multiple times; there is no duplicate checking. Queue is processed in order of addition.</dd>
+ <dd>If <code>soundManager.reboot()</code> is called, all listeners' "fired" flags will be reset and they will be eligible to fire again when SM2 starts up.</dd>
+ </dl>
+
+ <dl id="soundmanager-play" class="f-block f-play">
+ <dt><span>object:SMSound</span> play(<span>id:string,[options object]</span>)</dt>
+ <dd title="soundID:string">Starts playing the sound specified by ID. (Will start loading if applicable, and will play ASAP.)</dd>
+ <dd>Returns an <code>SMSound</code> (sound object) instance.</dd>
+ <dd>Example: <code>soundManager.play('<span>mySound</span>');</code></dd>
+ <dd>Note that the second parameter, <code>options object</code>, is not required and can take almost any argument from the object literal format (eg. volume.) It is convenient when you wish to override the sound defaults for a single instance.</dd>
+ <dd>Example: <code>soundManager.play('<span>mySound</span>',{<span>volume:50,onfinish:playNextSound</span>});</code></dd>
+ </dl>
+
+ <dl id="soundmanager-pause" class="f-block f-pause">
+ <dt><span>object:SMSound</span> pause(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Pauses the sound specified by ID. Does not toggle. Affects <span>paused</span> property (boolean.) Returns the given sound object.</dd>
+ <dd>Example: <code>soundManager.pause('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-pauseall" class="f-block f-pauseall">
+ <dt>pauseAll()</dt>
+ <dd>Pauses all sounds whose playState is >0. Affects <span>paused</span> property (boolean.)</dd>
+ <dd>Example: <code>soundManager.pauseAll();</code></dd>
+ </dl>
+
+ <dl id="soundmanager-reboot" class="f-block f-reboot">
+ <dt>reboot()</dt>
+ <dd title="soundID:string">Destroys any created SMSound objects, unloads the flash movie (removing it from the DOM) and restarts the SM2 init process, retaining all currently-set properties.</dd>
+ <dd>Example:
+<pre class="block"><code>soundManager.onerror = function() {<span>
+ <span>// Something went wrong during init - in this example, we *assume* flashblock etc.</span>
+ soundManager.flashLoadTimeout = 0; <span>// When restarting, wait indefinitely for flash</span>
+ soundManager.onerror = {}; <span>// Prevent an infinite loop, in case it's not flashblock</span>
+ soundManager.reboot(); <span>// and, go!</span>
+}</span></code></pre>
+ </dd>
+ <dd>This method may be helpful when trying to gracefully recover from FlashBlock-type situations where the user has prevented the SWF from loading, but is able to whitelist it. For more ideas, see <a href="../demo/flashblock/">Flashblock demo</a>.</dd>
+ <dd>When using this method also consider <a href="#flashloadtimeout" onclick="resetFilter()">flashLoadTimeout</a>, which can have SM2 wait indefinitely for the flash to load if desired.</dd>
+ </dl>
+
+ <dl id="soundmanager-resume" class="f-block f-resume">
+ <dt><span>object:SMSound</span> resume(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Resumes and returns the currently-paused sound specified by ID.</dd>
+ <dd>Example: <code>soundManager.resume('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-resumeall" class="f-block f-resumeall">
+ <dt>resumeAll()</dt>
+ <dd title="soundID:string">Resumes all currently-paused sounds.</dd>
+ <dd>Example: <code>soundManager.resumeAll();</code></dd>
+ </dl>
+
+ <dl id="soundmanager-setpan" class="f-block f-setpan">
+ <dt><span>object:SMSound</span> setPan(<span>id:string,volume:integer</span>)</dt>
+ <dd title="id:string,volume:integer">Sets the stereo pan (left/right bias) of the sound specified by ID, and returns the related sound object. Accepted values: -100 to 100 (L/R, 0 = center.) Affects <span>pan</span> property.</dd>
+ <dd>Example: <code>soundManager.setPan('<span>mySound</span>',<span>-80</span>);</code></dd>
+ </dl>
+
+ <dl id="soundmanager-setposition" class="f-block f-setposition">
+ <dt><span>object:SMSound</span> setPosition(<span>id:string,msecOffset:integer</span>)</dt>
+ <dd title="id:string,msecOffset:integer">Seeeks to a given position within a sound, specified by miliseconds (1000 msec = 1 second) and returns the related sound object. Affects <span>position</span> property.</dd>
+ <dd>Example: <code>soundManager.setPosition('<span>mySound</span>',<span>2500</span>);</code></dd>
+ <dd>Can only seek within loaded sound data, as defined by the <span>duration</span> property.</dd>
+ </dl>
+
+ <dl id="soundmanager-setvolume" class="f-block f-setvolume">
+ <dt><span>object:SMSound</span> setVolume(<span>id:string,volume:integer</span>)</dt>
+ <dd title="id:string,volume:integer">Sets the volume of the sound specified by ID and returns the related sound object. Accepted values: 0-100. Affects <span>volume</span> property.</dd>
+ <dd>Example: <code>soundManager.setVolume('<span>mySound</span>',<span>50</span>);</code></dd>
+ </dl>
+
+ <dl id="soundmanager-stop" class="f-block f-stop">
+ <dt><span>object:SMSound</span> stop(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Stops playing the sound specified by ID. Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.stop('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-stopall" class="f-block f-stopall">
+ <dt>stopAll()</dt>
+ <dd>Stops any currently-playing sounds.</dd>
+ <dd>Example: <code>soundManager.stopAll();</code></dd>
+ </dl>
+
+ <dl id="soundmanager-togglemute" class="f-block f-togglemute">
+ <dt><span>object:SMSound</span> toggleMute(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Mutes/unmutes the sound specified by ID. Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.toggleMute('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-togglepause" class="f-block f-togglepause">
+ <dt><span>object:SMSound</span> togglePause(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Pauses/resumes play on the sound specified by ID. Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.togglePause('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-unload" class="f-block f-unload">
+ <dt><span>object:SMSound</span> unload(<span>id:string</span>)</dt>
+ <dd title="soundID:string">Stops loading the sound specified by ID, canceling any current HTTP request. Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.unload('<span>mySound</span>');</code></dd>
+ <dd>Note that for Flash 8, SoundManager does this by loading a new, tiny "stub" MP3 file, <code class="in">./null.mp3</code>, which replaces the current one from loading. This is defined in the SM2 global object as <code class="in">nullURL</code>, and can be edited.</dd>
+ </dl>
+
+ <dl id="soundmanager-unmute" class="f-block f-unmute">
+ <dt><span>object:SMSound</span> unmute(<span>[id:string]</span>)</dt>
+ <dd title="id:string">Unmutes the sound specified by ID. If no ID specified, all sounds will be unmuted. Affects <span>muted</span> property (boolean.) Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.unmute('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-load" class="f-block f-load">
+ <dt><span>object:SMSound</span> load(<span>id:string,[options object]</span>)</dt>
+ <dd title="soundID:string">Starts loading the sound specified by ID, with options if specified. Returns the related sound object.</dd>
+ <dd>Example: <code>soundManager.load('<span>mySound</span>');</code></dd>
+ <dd>Example 2: <code>soundManager.load('<span>mySound</span>',{<span>volume:50,onfinish:playNextSound</span>});</code></dd>
+ </dl>
+
+ <dl id="soundmanager-getsoundbyid" class="f-block f-getsoundbyid">
+ <dt><span>object:SMSound </span>getSoundById(<span>id:string</span>)</dt>
+ <dd title="id:string">Returns an <code>SMSound</code> object specified by ID, or null if a sound with that ID is not found.</dd>
+ <dd>Example: <code>var mySMSound = soundManager.getSoundById('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="soundmanager-getmemoryuse" class="f-block f-getmemoryuse">
+ <dt class="flash9" title="Requires Flash 9.0+"><span>number:bytesUsed </span>getMemoryUse()</dt>
+ <dd>Returns the total number of bytes allocated to the Adobe Flash player or Adobe AIR, or 0 if unsupported (Flash 9+ only.) This number may include memory use across all tabs, browsers etc. See <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html#totalMemory" title="System.totalMemory property documentation">system.totalMemory</a> (livedocs.adobe.com)</dd>
+ <dd>Example: <code>var mbUsed = (soundManager.getMemoryUse()/1024/1024).toFixed(2); <span><span>// eg. 12.05 MB</span></span></code></dd>
+ </dl>
+
+ <dl id="soundmanager-loadfromxml" class="f-block f-loadfromxml">
+ <dt>loadFromXML(<span>xmlURL:string</span>)</dt>
+ <dd>Loads and creates sounds as defined in a <a href="http://www.schillmania.com/projects/soundmanager/" title="SoundManager v1 project page">SoundManager v1</a> XML file (legacy)</dd>
+ <dd>Note that per-sound options are not supported with this method, and sound objects will be created immediately upon loading and parsing of the XML. The sounds will inherit the <code>defaultOptions</code> settings, with the exception of the <code>stream</code> attribute as set in the XML (true if defined, defaultOption applied if omitted.)</dd>
+ <dd>Example: <code>soundManager.loadFromXML('<span>/path/to/some.xml</span>');</code></dd>
+ <dd>XML format example: <a href="../demo/mpc/acoustic-drumkit.xml">MPC drumkit XML file</a></dd>
+ </dl>
+
+ <dl id="soundmanager-supported" class="f-block f-supported">
+ <dt><span>isSupported:boolean</span> supported()</dt>
+ <dd>Returns a boolean indicating whether soundManager has attempted to and succeeded in initialising. This function will return false if called before initialisation has occurred.</dd>
+ <dd>Example: <code>var isSupported = soundManager.supported();</code></dd>
+ </dl>
+
+ </div>
+
+ </div>
+
+ <div id="smsoundmethods" class="columnar">
+
+ <div class="c1">
+ <h2>SMSound (Sound Object) API</h2>
+ <p class="in">Each <code>createSound()</code> call generates a matching <code>SMSound</code> (sound instance) object, which lasts for the life of the page or until explicitly destroyed. Each instance stores stateful information (eg. <code>playState</code>) and provides event handlers for state changes (eg. <code>onload()</code>.)</p>
+ <p>SoundManager is a convenient wrapper for most sound object methods: It will check for and gracefully exit if a sound object (specified by ID) does not exist, and provides convenient global functionality, eg. muting or pausing of all sounds.</p>
+ <p class="in">Nonetheless, each <code>SMSound</code> object can have its methods called directly. eg. <code>mySound.mute()</code> instead of <code>soundManager.mute('mySound')</code>, and so on.</p>
+ <p class="in">Note that for code examples, <code>mySound</code> is assumed to be a valid SMSound instance object - eg.,<br /><code>var mySound = soundManager.createSound();</code> or<br /> <code>var mySound = soundManager.getSoundById();</code></p>
+ </div>
+
+ <div class="c2">
+
+ <div>
+
+ <h3>Sound Object Methods</h3>
+
+ <p class="in">Each sound under SoundManager 2 is given a <code>SMSound</code> object instance which includes the following events, methods and properties. Note that most methods will return the sound object instance, allowing for method chaining if desired.</p>
+
+ <dl id="smsound-destruct" class="f-block s-destruct">
+ <dt>destruct()</dt>
+ <dd>Stops, unloads and destroys a sound, freeing resources etc.</dd>
+ <dd>Example: <code>mySound.destruct();</code></dd>
+ </dl>
+
+ <dl id="smsound-load" class="f-block s-load">
+ <dt><span>object:SMSound</span> load(<span>[options object]</span>)</dt>
+ <dd title="soundID:string">Starts loading the given sound, with options if specified.</dd>
+ <dd>Example: <code>mySound.load();</code></dd>
+ <dd>Example 2: <code>mySound.load({<span>volume:50,onfinish:playNextSound</span>});</code></dd>
+ </dl>
+
+ <dl id="smsound-mute" class="f-block s-mute">
+ <dt><span>object:SMSound</span> mute()</dt>
+ <dd>Mutes the given sound. Affects <span>muted</span> property.</dd>
+ <dd>Example: <code>mySound.mute();</code></dd>
+ </dl>
+
+ <dl id="smsound-onposition" class="f-block s-onposition">
+ <dt><span>object:SMSound</span> onposition(<span>msecOffset:integer, callback:function, [scope]</span>)</dt>
+ <dd>Registers an event listener, fired when a sound reaches or passes a certain position while playing. Position being "listened" for is passed back to event handler. Will also fire if a sound is "rewound" (eg. via <code>setPosition()</code> to an earlier point) and the given position is reached again. Listeners will be removed if a sound is unloaded. An optional scope can be passed as well.</dd>
+ <dd>Note that for <code>multiShot</code> cases, only the first play instance's <code>position</code> is tracked in Flash; therefore, subsequent "shots" will not have onposition() events being fired.</dd>
+ <dd>Example: <code>mySound.onposition(3000, function(eventPosition){<span>console.log(this.sID+' reached '+eventPosition</span>});</code></dd>
+ </dl>
+
+ <dl id="smsound-pause" class="f-block s-pause s-paused">
+ <dt><span>object:SMSound</span> pause()</dt>
+ <dd>Pauses the given sound. (Does not toggle.) Affects <span>paused</span> property (boolean.)</dd>
+ <dd>Example: <code>mySound.pause();</code></dd>
+ </dl>
+
+ <dl id="smsound-play" class="f-block s-play">
+ <dt><span>object:SMSound</span> play(<span>[options object]</span>)</dt>
+ <dd>Starts playing the given sound, with an optional options object. (Will start loading if applicable, and will play ASAP.)</dd>
+ <dd>Note that the <code>options object</code> parameter is not required and can take almost any argument from the object literal format (eg. volume.)</dd>
+ <dd>Example: <code>mySound.play('<span>mySound</span>',{<span>volume:50,onfinish:playNextSound</span>});</code></dd>
+ </dl>
+
+ <dl id="smsound-setposition" class="f-block s-setposition">
+ <dt><span>object:SMSound</span> setPosition(<span>msecOffset:integer</span>)</dt>
+ <dd title="msecOffset:integer">Seeks to a given position within a sound, specified by miliseconds (1000 msec = 1 second.) Affects <span>position</span> property.</dd>
+ <dd>Example: <code>mySound.setPosition(<span>2500</span>);</code></dd>
+ <dd>Can only seek within loaded sound data, as defined by the <span>duration</span> property.</dd>
+ </dl>
+
+ <dl id="smsound-resume" class="f-block s-resume">
+ <dt><span>object:SMSound</span> resume()</dt>
+ <dd>Resumes the currently-paused sound. Does not affect currently-playing sounds.</dd>
+ <dd>Example: <code>mySound.resume();</code></dd>
+ </dl>
+
+ <dl id="smsound-setpan" class="f-block s-setpan">
+ <dt><span>object:SMSound</span> setPan(<span>volume:integer</span>)</dt>
+ <dd title="volume:integer">Sets the stereo pan (left/right bias) of the given sound. Accepted values: -100 to 100 (L/R, 0 = center.) Affects <span>pan</span> property.</dd>
+ <dd>Example: <code>mySound.setPan(<span>-80</span>);</code></dd>
+ </dl>
+
+ <dl id="smsound-setvolume" class="f-block s-setvolume">
+ <dt><span>object:SMSound</span> setVolume(<span>volume:integer</span>)</dt>
+ <dd title="volume:integer">Sets the volume of the given sound. Accepted values: 0-100. Affects <span>volume</span> property.</dd>
+ <dd>Example: <code>mySound.setVolume(<span>50</span>);</code></dd>
+ </dl>
+
+ <dl id="smsound-togglemute" class="f-block s-togglemute">
+ <dt><span>object:SMSound</span> toggleMute()</dt>
+ <dd>Mutes/unmutes the given sound. Affected <span>muted</span> property (boolean.)</dd>
+ <dd>Example: <code>mySound.toggleMute();</code></dd>
+ </dl>
+
+ <dl id="smsound-togglepause" class="f-block s-togglepause">
+ <dt><span>object:SMSound</span> togglePause()</dt>
+ <dd>Pauses/resumes play of the given sound. Will also start a sound if it is has not yet been played.</dd>
+ <dd>Example: <code>mySound.togglePause();</code></dd>
+ </dl>
+
+ <dl id="smsound-stop" class="f-block s-stop">
+ <dt><span>object:SMSound</span> stop()</dt>
+ <dd>Stops playing the given sound.</dd>
+ <dd>Example: <code>mySound.stop();</code></dd>
+ </dl>
+
+ <dl id="smsound-unload" class="f-block s-unload">
+ <dt><span>object:SMSound</span> unload()</dt>
+ <dd>Stops loading the given sound, canceling any current HTTP request.</dd>
+ <dd>Example: <code>mySound.unload();</code></dd>
+ <dd>Note that for Flash 8, SoundManager does this by loading a new, tiny "stub" MP3 file, <code class="in">./null.mp3</code>, which replaces the current one from loading. This is defined in the SM2 global object as <code class="in">nullURL</code>, and can be edited.</dd>
+ </dl>
+
+ <dl id="smsound-unmute" class="f-block s-unmute">
+ <dt><span>object:SMSound</span> unmute()</dt>
+ <dd>Unmutes the given sound. Affects <span>muted</span> property.</dd>
+ <dd>Example: <code>mySound.unmute();</code></dd>
+ </dl>
+
+ </div>
+
+ </div>
+
+
+</div>
+
+ <div id="smsoundevents" class="columnar">
+
+ <div class="c1">
+ <h2 id="soundmanager-sound-events">SMSound Events</h2>
+ <p>Event handlers for SMSound objects.</p>
+ </div>
+
+ <div class="c2">
+
+ <div>
+
+ <h3>Sound Object Events</h3>
+
+ <p class="in">Like native javascript objects, each SoundManager <code>SMSound</code> (sound instance) object can fire a number of <code>onload</code>-like events. Handlers cannot be "directly" assigned (eg. someSound.onload), but can be passed as option parameters to several sound methods.</p>
+ <div>
+<pre class="block"><code>soundManager.play('<span>mySound</span>',{
+ onfinish: function() {
+ alert('<span>The sound </span>'+this.sID+' <span>finished playing.</span>');
+ }
+});</code></pre>
+ </div>
+ <p>Event handlers are scoped to the relevant sound object, so the <code>this</code> keyword will point to the sound object on which the event fired such that its properties can easily be accessed - eg. within an <code>SMSound</code> event handler, <code>this.sID</code> will give the sound ID.</p>
+
+ </div>
+
+ <div style="margin-top:2em">
+
+ <dl id="smsound-onbufferchange" class="f-block s-onbufferchange">
+ <dt class="flash9">onbufferchange()</dt>
+ <dd>Fires when a sound's reported buffering state has changed while playing and/or loading. The current state is reflected in the boolean <code>isBuffering</code> property.</dd>
+ <dd>Flash 9+ only. Related information on Adobe, <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/Sound.html#isBuffering">Sound.isBuffering</a>.</dd>
+ </dl>
+
+ <dl id="smsound-ondataerror" class="f-block s-ondataerror s-waveformdata s-eqdata">
+ <dt title="Flash 9+ only" class="flash9">ondataerror()</dt>
+ <dd>Fires at least once per sound play instance when Flash encounters a security error when trying to call computeSpectrum() internally. This typically happens when sounds are 'inaccessible' due to another Flash movie (eg. YouTube) in another tab which has loaded, and may (or may not be) playing sound. Flash attempts to read the "combined" output to the sound card, and must have security permissions for all sounds as a result. See <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#areSoundsInaccessible()">areSoundsInaccessible()</a> on Adobe for more info.</dd>
+ <dd>If the offending resource causing the security error is closed or becomes inactive(?), the data will become available again. Intermittent availability will result in intermittent calls to <code>ondataerror()</code>.</dd>
+ </dl>
+
+ <dl id="smsound-onbeforefinishcomplete" class="f-block s-onbeforefinishcomplete">
+ <dt>onbeforefinishcomplete()</dt>
+ <dd>Fires when a sound has finished, <code>onfinish()</code> has been called, but before the sound play state and other meta data (position, etc.) are reset.</dd>
+ </dl>
+
+ <dl id="smsound-onbeforefinish" class="f-block s-onbeforefinish">
+ <dt>onbeforefinish()</dt>
+ <dd>Fires when a playing, fully-loaded sound has reached <code>onbeforefinishtime</code> (eg. 5000 msec) from its end.</dd>
+ </dl>
+
+ <dl id="smsound-onconnect" class="f-block s-onconnect flash9">
+ <dt>onconnect()</dt>
+ <dd>Fires when a sound using an RTMP <code>serverURL</code> property has attempted to connect, and has either succeeded or failed. Affects <code>connected</code> property. Once connected, a stream can be requested from the RTMP server.</dd>
+ <dd>Example:
+<pre class="block"><code>var s = soundManager.createSound({<span>
+ id: 'rtmpTest',
+ serverURL: 'rtmp://localhost/test/',
+ url: 'song.mp3',
+ onconnect: function(bConnect) {
+ <span><span>// <b>this.connected</b> can also be used</span></span>
+ soundManager._writeDebug(this.sID+' connected: '+(bConnect?'true':'false'));
+ }
+</span>}).play();<span><span> // will result in connection being made</span></span></code></pre>
+ </dl>
+
+ <dl id="smsound-onfinish" class="f-block s-onfinish">
+ <dt>onfinish()</dt>
+ <dd>Fires when a playing sound has reached its end. By this point, relevant properties like <code>playState</code> will have been reset to non-playing status.</dd>
+ </dl>
+
+ <dl id="smsound-onid3" class="f-block s-onid3">
+ <dt id="onid3">onid3()</dt>
+ <dd>Fires when ID3 data has been received. Relevant property is <code>id3</code>, which is an object literal (JSON)-style object. Only fields with data will be populated.</dd>
+ <dd>Note that ID3V2 data is located at the beginning (header) of an MP3 file and will load almost immediately, whereas ID3V1 data is at the end and will not be received until the MP3 has fully loaded.</dd>
+ <dd>
+ Example handler code:
+ <div>
+<pre class="block"><code>soundManager._writeDebug(<span>'sound '+this.sID+' ID3 data received'</span>);
+var prop = null;
+var data = '';
+for (prop in this.id3) {
+ data += prop+': '+this.id3[prop]+','; <span><span>// eg. title: Loser, artist: Beck</span></span>
+}</code></pre>
+ </div>
+ </dd>
+ <dd>Refer to the <a href="http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002676.html" title="Flash 8 Sound.id3 property documentation">Flash 8 Sound.id3</a> documentation for a list of ID3 properties.</dd>
+ <dd>When parsing ID3 data, it is best to check for the existance of ID3V1 data first, and apply ID3V2 if no matching ID3V1 data is defined. (V1 should "inherit" from V2, ideally, if available.)</dd>
+ <dd>Note that Flash's cross-domain security restrictions may prevent access to ID3 information, even though the MP3 itself can be loaded. (crossdomain.xml files on the remote host can grant Flash permission to access this.)</dd>
+ <dd>Also note some <a href="#id3-parsing" onclick="resetFilter()">issues with parsing ID3 from iTunes</a>.</dd>
+ </dl>
+
+
+ <dl id="smsound-onjustbeforefinish" class="f-block s-onjustbeforefinish">
+ <dt>onjustbeforefinish()</dt>
+ <dd>Fires approximately <code>justbeforefinishtime</code> before the end of a fully-loaded, playing sound.</dd>
+ <dd>This is based on a polling approach given SM2 must track the sound's position, and is approximated (eg. a 200 msec value may fire at 187 msec before the end of the sound.)</dd>
+ </dl>
+
+ <dl id="smsound-onload" class="f-block s-onload">
+ <dt>onload(<span>boolean:success</span>)</dt>
+ <dd>Fires on sound load. Boolean reflects successful load (true), or fail/load from cache (false).</dd>
+ <dd>False value should seemingly only be for failure, but appears to be returned for load from cache as well. This strange behaviour comes from Flash. More detail may be available from the Flash 8 sound object documentation.</dd>
+ <dd>Failure can occur if the Flash sandbox (security) model is preventing access, for example loading SoundManager 2 on the local file system and trying to access an MP3 on a network (or internet) URL. (Security can be configured in the Flash security panel, [<a href="#fpgss" title="Configure your Flash player security settings" onclick="resetFilter()">see here</a>].)</dd>
+ <!-- <dd>Example: <code>soundManager.createSound('<span>mySound</span>','<span>/audio/mysoundfile.mp3</span>');</code></dd> -->
+ </dl>
+
+ <dl id="smsound-onpause" class="f-block s-onpause">
+ <dt>onpause()</dt>
+ <dd>Fires when a sound pauses, eg. via <code>sound.pause()</code>.</dd>
+ <dd>Example: <code>soundManager.pause('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="smsound-onplay" class="f-block s-onplay">
+ <dt>onplay()</dt>
+ <dd>Fires when <code>sound.play()</code> is called.</dd>
+ </dl>
+
+ <dl id="smsound-onresume" class="f-block s-onresume">
+ <dt>onresume()</dt>
+ <dd>Fires when a sound resumes playing, eg. via <code>sound.resume()</code>.</dd>
+ <dd>Example: <code>soundManager.resume('<span>mySound</span>');</code></dd>
+ </dl>
+
+ <dl id="smsound-onstop" class="f-block s-onstop">
+ <dt>onstop()</dt>
+ <dd>Fires when <code>sound.stop()</code> is explicitly called. For natural "sound finished" <code>onfinish()</code> case, see below.</dd>
+ </dl>
+
+ <dl id="smsound-whileloading" class="f-block s-whileloading s-bytesloaded s-bytestotal">
+ <dt>whileloading()</dt>
+ <dd>Fires at a regular interval when a sound is loading and new data has been received. The relevant, updated property is <code>bytesLoaded</code>.</dd>
+ <dd>Example handler code: <code>soundManager._writeDebug(<span>'sound '+this.sID+' loading, '+this.bytesLoaded+' of '+this.bytesTotal</span>);</code></dd>
+ <dd>Note that the <code>duration</code> property starts from 0 and is updated during <code>whileloading()</code> to reflect the duration of currently-loaded sound data (ie. when a 4:00 MP3 has loaded 50%, the duration will be reported as 2:00 in milliseconds.) However, an estimate of final duration can be calculated using <code>bytesLoaded</code>, <code>bytesTotal</code> and <code>duration</code> while loading. Once fully-loaded, <code>duration</code> will reflect the true and accurate value.</dd>
+ </dl>
+
+ <dl id="smsound-whileplaying" class="f-block s-whileplaying">
+ <dt>whileplaying()</dt>
+ <dd>Fires at a regular interval when a sound is playing, and a position (time) change is detected. The relevant, updated property is <code>position</code>.</dd>
+ <dd>Example handler code: <code>soundManager._writeDebug(<span>'sound '+this.sID+' playing, '+this.position+' of '+this.duration</span>);</code></dd>
+ </dl>
+
+
+ </div>
+
+ </div>
+
+ </div>
+
+
+ <div id="sound-object-properties" class="columnar">
+
+ <div class="c1">
+ <h2>SMSound Properties</h2>
+ <p>Instance Option properties (parameters) can be used with <code>createSound()</code> and <code>play()</code>.</p>
+ <p style="margin-bottom:0px">Example:</p>
+<pre class="block"><code>soundManager.createSound({
+ id: 'foo',
+ url: '/path/to/an.mp3'
+});</code></pre>
+ <p>Dynamic Properties can be read to monitor the state of a sound object.</p>
+ <p style="margin-bottom:0px">Example:</p>
+<pre class="block"><code>alert(mySound.playState);</code></pre>
+
+
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block">
+
+ <h3 id="soundmanager-sound-properties">Sound Object Properties</h3>
+ <p>Each sound object inherits these properties from soundManager.defaultOptions. They can be set individually or at once when enclosed in object literal form to either <code>createSound()</code> or <code>play()</code>.</p>
+
+ </div>
+
+ <div style="margin-top:2em">
+
+ <dl id="smsound-sid" class="f-block s-sid">
+ <dt>sID</dt>
+ <dd>Sound ID string as provided from the <code>id</code> parameter via <code>createSound()</code> or <code>play()</code>. Can be referenced as <code>this.sID</code> from within sound object event handlers such as <code>onload()</code>, <code>whileloading()</code> or <code>whileplaying()</code>, etc.</dd>
+ <dd>If an ID is known, the related SMSound object can be retrieved via <code>getSoundById</code> or directly referencing <code>sounds[sID]</code> on the SoundManager global object.</dd>
+ </dl>
+
+ <dl id="smsound-url" class="f-block s-url">
+ <dt>url</dt>
+ <dd>The specified URL from which the sound is loaded, typically over HTTP. Can be referenced as <code>this.url</code> from within sound object event handlers such as <code>onload()</code> or <code>whileplaying()</code>, etc.</dd>
+ </dl>
+
+ <dl id="smsound-serverurl" class="f-block s-serverurl">
+ <dt>serverURL</dt>
+ <dd><b>Note: <em>Experimental feature.</em></b> Only for use with RTMP streaming, ie., Flash Media Server and similar servers.</dd>
+ <dd>The RTMP server address which Flash will connect to using a <a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/NetStream.html" title="NetStream documentation">NetStream</a> object. Only the server address is specified here, when RTMP is in use; the <code>url</code> property is used to point to a specific resource on the server.</dd>
+ <dd>Example:
+<pre class="block"><code>soundManager.createSound({<span>
+ id: 'mySound',
+ serverURL: 'rtmp://localhost/rtmpDemo/', <span><span>// RTMP server</span></span>
+ url: 'mysong.mp3' <span><span>// path to stream</span></span>
+}</span>).play();</code></pre></dd>
+ </dl>
+
+ <dl id="smsound-usepolicyfile" class="f-block s-usepolicyfile">
+ <dt>usePolicyFile</dt>
+ <dd>Boolean value (default: <code>false</code>) which instructs Flash, when loading MP3/MP4 content from remote/third party domains, to request example.com/crossdomain.xml first in order to determine permissions for access to metadata such as ID3 info, waveform, peak and/or spectrum data.</dd>
+ <dd><code>usePolicyFile</code> will be automagically set to <code>true</code> if your sound options have an <code>onid3()</code> event handler, or uses sound data (peak/wave/spectrum) features. By default, Flash will not have access to this metadata on remote domains unless granted cross-domain security permissions via the crossdomain.xml file.</dd>
+ <dd>Consider additional HTTP traffic (albeit, perhaps with caching-like behaviour for subsequent checks?) and silent 404s in most cases given few hosts use crossdomain.xml files.</dd>
+ <dd>See Adobe's knowledge base for <a href="http://kb2.adobe.com/cps/963/50c96388.html" title="Adobe KB: ID3 does not load on cross-domain MP3s">related ID3 + crossdomain.xml</a> documentation.</dd>
+ </dl>
+
+ </div>
+
+ <div style="margin-top:2em">
+
+ <div class="f-block">
+
+ <h3 id="soundmanager-sound-dynamic-properties">Sound Object Dynamic Properties</h3>
+ <p>Each sound includes a number of properties that are updated throughout the life of a sound - while loading or playing, for example. Many of these properties have related events that fire when they are updated, and should be treated as read-only.</p>
+
+ </div>
+
+
+ <dl id="smsound-bytesloaded" class="f-block s-bytesloaded">
+ <dt>bytesLoaded</dt>
+ <dd>The number of bytes currently received while loading a sound.</dd>
+ </dl>
+
+ <dl id="smsound-bytestotal" class="f-block s-bytestotal">
+ <dt>bytesTotal</dt>
+ <dd>The total number of bytes to be downloaded, while loading a sound.</dd>
+ </dl>
+
+ <dl id="smsound-didbeforefinish" class="f-block s-didbeforefinish">
+ <dt>didBeforeFinish</dt>
+ <dd>Boolean indicating whether <code>beforeFinish()</code> condition was reached.</dd>
+ </dl>
+
+ <dl id="smsound-didjustbeforefinish" class="f-block s-didjustbeforefinish">
+ <dt>didJustBeforeFinish</dt>
+ <dd>Boolean indicating whether <code>justBeforeFinish()</code> condition was reached.</dd>
+ </dl>
+
+ <dl id="smsound-duration" class="f-block s-duration">
+ <dt>duration</dt>
+ <dd>The current length of the sound, specified in milliseconds.</dd>
+ <dd>Note that during loading, this property reflects the length of downloaded data, not the full length, until completely loaded (see <a href="#smsound-whileloading" onclick="resetFilter()">whileloading()</a>.) For an approximate "full duration" value while loading, see <code>durationEstimate</code>.</dd>
+ </dl>
+
+ <dl id="smsound-durationestimate" class="f-block s-durationestimate">
+ <dt>durationEstimate</dt>
+ <dd>The estimated duration of the sound, specified in milliseconds.</dd>
+ <dd>Due to the dynamic nature of <code>duration</code> while loading, this attempts to provide the full duration by calculating <code>parseInt((self.bytesTotal/self.bytesLoaded)*self.duration)</code> and is updated with each <code>whileloading()</code> interval.</dd>
+ <dd>Once the sound has fully loaded, <code>duration</code> should be referenced as it will contain the final and accurate value.</dd>
+ <dd>Note that this method works only with Constant Bitrate (CBR)-encoded MP3s due to the consistent data/time assumption. VBR-encoded MP3s will give inaccurate results.</dd>
+ </dl>
+
+ <dl id="smsound-eqdata" class="f-block s-eqdata">
+ <dt title="Flash 9+ only" class="flash9">eqData = {<span>left:[], right: []</span>}</dt>
+ <dd>Object containing two arrays of 256 floating-point (three decimal place) values from 0 to 1, the result of an FFT on the waveform data. Can be used to draw a spectrum (frequency range) graph while playing a sound. See <a href="../demo/page-player/#debug=1" title="Muxtape.com-style page-as-playlist, with debug output" onclick="checkDomain(this,true)">Page-as-playlist demo</a> for example implementation. Requires Flash 9+.</dd>
+ <dd>A spectrum frequency graph reflects the level of frequencies being played, from left to right, low to high (i.e., 0 to 20,000 Hz.)</dd>
+ <dd><code>eqData</code> is set and updated during <code>whileplaying()</code>. A simple graph could be drawn by looping through the values and multiplying by a vertical scale value (eg. 32, thus a graph with peaks of 32 pixels.)</dd>
+ <dd>Example code:
+<pre class="block"><code>someSoundObject.whileplaying = function() {<span>
+ <span>// Move 256 absolutely-positioned 1x1-pixel DIVs, for example (ugly, but works)</span>
+ var gPixels = document.getElementById('graphPixels').getElementsByTagName('div');
+ var gScale = 32; <span>// draw 0 to 32px from bottom</span>
+ for (var i=0; i<256; i++) {
+ graphPixels[i].style.top = (32-(gScale+Math.ceil(this.waveformData.left[i]*gScale)))+'px';
+ }
+</span>}</code></pre>
+ </dd>
+ <dd>Related Adobe technical documentation (Flash 9/AS3 Sound() object): <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()" title="Adobe Flash 9, sound object documentation">computeSpectrum()</a></dd>
+ <dd><strong>Note</strong>: Flash security measures may deny access to waveformData when loading MP3s from remote domains.</dd>
+ <dd><strong>Warning:</strong> This feature can eat up a lot of CPU in some cases. The amount of data passed from Flash to JS is not terribly large, but the JS-DOM updates and browser reflow can be expensive. Use with caution.</dd>
+ <dd><strong>Backward compatibility note:</strong> Up to SoundManager 2.95a.20090717, eqData was a single array containing one channel of data. In newer versions this is unchanged, except the array now has .left[] and .right[] objects attached to it. To ensure future compatibility, use eqData.left[0] instead of eqData[0] and so on.</dd>
+ </dl>
+
+ <dl id="smsound-id3" class="f-block s-id3">
+ <dt>id3</dt>
+ <dd>An object literal populated, if applicable, when ID3 data is received (related handler: <code>onid3()</code>)</dd>
+ <dd>For property details, see <a href="#onid3" title="onid3() documentation" onclick="resetFilter()">onid3()</a>.</dd>
+ </dl>
+
+ <dl id="smsound-isbuffering" class="f-block s-isbuffering">
+ <dt class="flash9">isBuffering</dt>
+ <dd>Boolean value reflecting the buffering state of a playing or loading object. To be notified when this property changes, see <a href="#smsound-onbufferchange" onclick="resetFilter()">onbufferchange()</a>.</dd>
+ <dd>Flash 9+ only. Related information on Adobe, <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/Sound.html#isBuffering">Sound.isBuffering</a>.</dd>
+ </dl>
+
+ <dl id="smsound-connected" class="f-block s-connected">
+ <dt class="flash9">connected</dt>
+ <dd>Boolean value reflecting the state of an RTMP server connection (when <code>serverURL</code> is used to connect to a Flash Media Server or similar RTMP service.) Calls to <code>load</code> or <code>play</code> will result in a connection attempt being made, and <code>onconnect()</code> ultimately being called.</dd>
+ <dd>For example code using <code>connected</code>, see <a href="#smsound-onconnect" onclick="resetFilter()">onconnect()</a>.</dd>
+ </dl>
+
+ <dl id="smsound-loaded" class="f-block s-loaded">
+ <dt>loaded</dt>
+ <dd>Boolean value indicating load success as returned from Flash. True indicates success, False is a failure.</dd>
+ <dd>Because of the potential for false positives, <code>duration</code> and other properties could be checked as a test of whether sound data actually loaded. For more granular state information, see <a href="#readystate" title="SMSound readyState documentation" onclick="resetFilter()">readyState</a>.</dd>
+ </dl>
+
+ <dl id="smsound-muted" class="f-block s-muted">
+ <dt>muted</dt>
+ <dd>Boolean indicating muted status. True/False.</dd>
+ <dd>Treat as read-only; use <code>mute()</code>, <code>unmute()</code> and <code>toggleMute()</code> methods to affect state.</dd>
+ </dl>
+
+ <dl id="smsound-paused" class="f-block s-paused">
+ <dt>paused</dt>
+ <dd>Boolean indicating pause status. True/False.</dd>
+ <dd>Treat as read-only; use <code>pause()</code>, <code>resume()</code> and <code>togglePause()</code> methods to affect state.</dd>
+ </dl>
+
+ <dl id="smsound-peakdata" class="f-block s-peakdata">
+ <dt title="Flash 9+ only" class="flash9">peakData = {<span>left:0.0, right:0.0</span>}</dt>
+ <dd>Object literal format including <code>left</code> and <code>right</code> properties with floating-point values ranging from 0 to 1, indicating "peak" (volume) level. Updated during <code>whileplaying()</code>. See <a href="../demo/page-player/#debug=1" title="Muxtape.com-style page-as-playlist, with debug output" onclick="checkDomain(this,true)">Page-as-playlist demo</a> as one example. Requires Flash 9+.</dd>
+ <dd>Example (within relevant sound object handler):
+<pre class="block"><code>someSoundObject.whileplaying = function() {<span>
+ soundManager._writeDebug('Peaks, L/R: '+this.peakData.left+'/'+this.peakData.right);
+</span>}</code></pre></dd>
+ </dl>
+
+ <dl id="smsound-playstate" class="f-block s-playstate">
+ <dt>playState</dt>
+ <dd>Numeric value indicating the current playing state of the sound.</dd>
+ <dd>0 = stopped/uninitialised</dd>
+ <dd>1 = playing <em>or</em> buffering sound (play has been called, waiting for data etc.)</dd>
+ <dd>Note that a 1 may not always guarantee that sound is being heard, given buffering and autoPlay status.</dd>
+ </dl>
+
+
+ <dl id="smsound-position" class="f-block s-position">
+ <dt>position</dt>
+ <dd>The current location of the "play head" within the sound, specified in milliseconds (1 sec = 1000 msec).</dd>
+ </dl>
+
+ <dl id="smsound-readystate" class="f-block s-readystate s-onload">
+ <dt id="readystate">readyState</dt>
+ <dd>Numeric value indicating a sound's current load status</dd>
+ <dd>0 = uninitialised</dd>
+ <dd>1 = loading</dd>
+ <dd>2 = failed/error</dd>
+ <dd>3 = loaded/success</dd>
+ </dl>
+
+ <dl id="smsound-type" class="f-block s-type">
+ <dt>type</dt>
+ <dd>A MIME type-like string eg. <code>audio/mp3</code>, used as a hint for SM2 to determine playability of a link with methods like <code>canPlayURL()</code>.</dd>
+ <dd>This can be helpful when you have a sound URL that does not have an .mp3 extension, but serves MP3 data (eg., a PHP or other CGI script.)</dd>
+ <dd>Example:
+<pre class="block"><code>var s = soundManager.createSound({<span>
+ id: 'aSound',
+ url: '/path/to/some.php?songID=123',
+ type: 'audio/mp3' <span><span>// indicates an MP3 link, so SM2 can handle it appropriately</span></span>
+</span>});</code></pre></dd>
+ </dl>
+
+
+ <dl id="smsound-waveformdata" class="f-block s-waveformdata">
+ <dt title="Flash 9+ only" class="flash9">waveformData = {<span>left:[], right:[]</span>}</dt>
+ <dd>Array of 256 floating-point (three decimal place) values from -1 to 1, can be used to draw a waveform while playing a sound. See <a href="../demo/page-player/#debug=1" title="Muxtape.com-style page-as-playlist, with debug output" onclick="checkDomain(this,true)">Page-as-playlist demo</a> for example implementation. Requires Flash 9+.</dd>
+ <dd><code>waveformData</code> is set and updated during <code>whileplaying()</code>. A simple graph could be drawn by looping through the values and multiplying by a vertical scale value (eg. 32, which would make a graph with peaks of -32 and +32 pixels.)</dd>
+ <dd>Example code:
+ <pre class="block"><code>someSoundObject.whileplaying = function() {<span>
+ <span>// Move 256 absolutely-positioned 1x1-pixel DIVs, for example (ugly, but works)</span>
+ var gPixels = document.getElementById('graphPixels').getElementsByTagName('div');
+ var gScale = 32; <span>// draw -32 to +32px from "zero" (i.e., center Y-axis point)</span>
+ for (var i=0; i<256; i++) {
+ graphPixels[i].style.top = (gScale+Math.ceil(this.waveformData.left[i]*-gScale))+'px';
+ }
+</span>}</code></pre>
+ </dd>
+ <dd><strong>SM2 implementation note</strong>: <code>waveformData</code> contains both left and right channels, and the data represents a raw sound wave rather than a frequency spectrum.</dd>
+ <dd>Related Adobe technical documentation (Flash 9/AS3 Sound() object): <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()" title="Adobe Flash 9, sound object documentation">computeSpectrum()</a></dd>
+ <dd><strong>Note</strong>: Flash security measures may deny access to waveformData when loading MP3s from remote domains.</dd>
+ <dd><strong>Warning:</strong> This feature can eat up a lot of CPU in some cases. The amount of data passed from Flash to JS is not terribly large, but the JS-DOM updates and browser reflow can be expensive. Use with caution.</dd>
+ </dl>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div id="smsound-methods" class="columnar">
+ <div class="c1">
+ <h2>SMSound Methods</h2>
+ <p>Functions which may be called directly on sound objects.</p>
+ </div>
+ <div class="c2">
+
+ <div class="f-block">
+ <h3>SMSound Object Methods</h3>
+ <p class="in">SoundManager provides wrappers for most SMSound methods - eg. <code>soundManager.play('<span>mySound</span>')</code> checks for a valid sound object, and then calls <code>soundManager.sounds['<span>mySound</span>'].play()</code> on that particular object; thus, it is the same as <code>var sound = soundManager.getSoundById('mySound'); mySound.play();</code></p>
+ <p>The following methods can be called directly on a SMSound instance. The method calls are the same as the SoundManager global methods documented above for existing sound objects, minus the sound ID parameter.</p>
+ </div>
+
+ <div class="f-block s-play s-setposition s-pause s-resume s-togglepause s-mute s-setvolume s-setpan s-stop s-unload s-destruct">
+
+ <dl class="tight">
+
+ <dt>destruct() <span class="archive">(also called via <a href="#soundmanager-destroysound" onclick="resetFilter()">soundManager.destroySound()</a>.)</span></dt>
+ <dt><a href="#smsound-load" onclick="resetFilter()">load()</a></dt>
+ <dt><a href="#smsound-mute" onclick="resetFilter()">mute()</a></dt>
+ <dt><a href="#smsound-pause" onclick="resetFilter()">pause()</a></dt>
+ <dt><a href="#smsound-play" onclick="resetFilter()">play(<span>[options object]</span>)</a></dt>
+ <dt><a href="#smsound-resume" onclick="resetFilter()">resume()</a></dt>
+ <dt><a href="#smsound-setposition" onclick="resetFilter()">setPosition(<span>msecOffset:integer</span>)</a></dt>
+ <dt><a href="#smsound-togglepause" onclick="resetFilter()">togglePause()</a></dt>
+ <dt><a href="#smsound-setvolume" onclick="resetFilter()">setVolume(<span>volume:integer</span>)</a></dt>
+ <dt><a href="#smsound-setpan" onclick="resetFilter()">setPan(<span>pan:integer</span>)</a></dt>
+ <dt><a href="#smsound-stop" onclick="resetFilter()">stop()</a></dt>
+ <dt><a href="#smsound-unload" onclick="resetFilter()">unload()</a></dt>
+ <dt><a href="#smsound-unmute" onclick="resetFilter()">unmute()</a></dt>
+
+ </dl>
+
+ </div>
+
+ </div>
+ </div>
+
+
+ <!-- options -->
+ <div id="smdefaults" class="columnar">
+
+ <div class="c1">
+ <h2>SoundManager Default Options</h2>
+ <p>An optional object specifying event handlers etc., passed to <code>createSound()</code> and <code>play()</code>.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block f-defaultoptions s-autoload s-loops s-stream s-onbeforefinish s-onbeforefinishtime s-onjustbeforefinishtime s-multishot s-multishotevents s-pan s-volume s-ismoviestar s-flash9options s-moviestaroptions s-buffertime s-serverurl s-onconnect">
+
+ <h3 id="sound-properties">SoundManager Global Sound Object Defaults</h3>
+
+ <p>The <code class="in">soundManager.defaultOptions</code> object contains default parameters inherited by sound objects made via <code class="in">createSound()</code>. They can be overridden on a per-sound basis at create time, or changed dynamically in some cases. Note that none of these options are required when calling <code class="in">createSound()</code> except for <code>id</code> and <code>url</code>; the others will inherit the default values if unspecified.</p>
+ <p><code class="in">soundManager.defaultOptions</code> apply the properties and event handlers as specified above. Defaults are shown below as an example.</p>
+
+<pre class="small block"><code>soundManager.defaultOptions = {<span>
+ autoLoad: false, <span>// enable automatic loading (otherwise .load() will call with .play())</span>
+ autoPlay: false, <span>// enable playing of file ASAP (much faster if "stream" is true)</span>
+ loops: 1, <span>// number of times to play the sound. Related: <a href="demo/api/#looping">looping</a> (API demo)</span>
+ multiShot: true, <span>// let sounds "restart" or "chorus" when played multiple times..</span>
+ multiShotEvents: false,<span>// allow events (onfinish()) to fire for each shot, if supported.</span>
+ onid3: null, <span>// callback function for "ID3 data is added/available"</span>
+ onload: null, <span>// callback function for "load finished"</span>
+ onstop: null, <span>// callback for "user stop"</span>
+ onfinish: null, <span>// callback function for "sound finished playing"</span>
+ onbeforefinish: null, <span>// callback for "before sound finished playing (at [time])"</span>
+ onbeforefinishtime: 5000, <span>// offset (milliseconds) from sound end, call beforefinish..</span>
+ onbeforefinishcomplete: null,<span>// function to call when said sound finishes playing</span>
+ onjustbeforefinish: null, <span>// callback for [n] msec before end of current sound</span>
+ onjustbeforefinishtime: 200, <span>// if unused, set to 0 (or null handler), event will not fire.</span>
+ onpause: null, <span>// callback for "pause"</span>
+ onplay: null, <span>// callback for "play" start</span>
+ onresume: null, <span>// callback for "resume" (pause toggle)</span>
+ position: null, <span>// offset (milliseconds) to seek to within downloaded sound.</span>
+ pan: 0, <span>// "pan" settings, left-to-right, -100 to 100</span>
+ stream: true, <span>// allows playing before entire file has loaded (recommended)</span>
+ type: null, <span>// MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3</span>
+ usePolicyFile: false, <span>// enable crossdomain.xml request for audio on remote domains (for ID3/waveform access)</span>
+ volume: 100, <span>// self-explanatory. 0-100, the latter being the max.</span>
+ whileloading: null, <span>// callback function for updating progress (X of Y bytes received)</span>
+ whileplaying: null, <span>// callback during play (position update)</span>
+
+ <span>// *** merged soundManager.flash9Options, as applicable ***</span>
+ isMovieStar: null, <span>// "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL</span>
+ usePeakData: false, <span>// enable left/right channel peak (level) data</span>
+ useWaveformData:false,<span>// enable sound spectrum (raw waveform data) - Note: May be CPU-intensive, UI redraw/layout etc.</span>
+ useEQData: false, <span>// enable sound EQ (frequency spectrum data) - Note: CPU potential also.</span>
+ onbufferchange: null, <span>// callback for "isBuffering" property change</span>
+ ondataerror: null <span>// callback for waveform/eq data access error (flash playing audio in other tabs/domains)</span>
+
+ <span>// *** merged soundManager.movieStarOptions, as applicable ***</span>
+ bufferTime: null, <span>// seconds of data to buffer (null = flash default of 0.1 - if AAC gappy, try up to 3 seconds)</span>
+ serverURL: null, <span>// rtmp: flash media server to connect to, required for RTMP</span>
+ onconnect: null <span>// rtmp: callback for connection to flash media server</span>
+
+</span>}
+</code></pre>
+
+ <p class="in">As a simple example, the following code would override the default <code>autoPlay</code>, <code>pan</code> and <code>volume</code> options for a given sound:</p>
+
+<pre class="block"><code>soundManager.createSound({
+ <span>id: 'mySound',
+ url: '/path/to/some.mp3',
+ autoPlay: true,
+ pan: -75,
+ volume: 50</span>
+});</code></pre>
+
+ <p class="alternate"><em>Note</em>: For live examples, see the code behind the "<a href="../demo/page-player/" title="muxtape-style page as playlist demo" onclick="checkDomain(this)">page as playlist</a>" demo which uses much of this functionality.</p>
+
+ </div>
+
+ <div class="f-block f-defaultoptions f-flash9options f-moviestaroptions s-ismoviestar s-usepeakdata s-usewaveformdata s-useeqdata">
+
+ <h3 id="sound-properties-flash9" title="Flash 9-only" class="flash9">Sound Properties Object: Version-specific Options (Merging)</h3>
+
+ <p>Some sound properties object items (eg. <code class="in">usePeakData</code>) are flash version-specific, non-default and are intentionally separated from <code class="in">soundManager.defaultOptions</code>. Flash 9-specific options fall under this category.</p>
+
+ <p><code class="in">soundManager.flash9Options</code> and <code class="in">soundManager.movieStarOptions</code> are both defined as separate objects, and if supported according to <code class="in">flashVersion</code> and <code class="in">defaultOptions</code> parameters, are merged "without nesting" into <code class="in">soundManager.defaultOptions</code>.</p>
+
+<pre class="small block"><code>soundManager.flash9Options = {<span>
+ isMovieStar: null, <span>// "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL</span>
+ usePeakData: false, <span>// enable left/right channel peak (level) data</span>
+ useWaveformData: false, <span>// enable sound spectrum (raw waveform data) - WARNING: May set CPUs on fire.</span>
+ useEQData: false, <span>// enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive.</span>
+ onbufferchange: null, <span>// callback for "isBuffering" property change</span>
+ ondataerror: null <span>// callback for waveform/eq data access error (flash playing audio in other tabs/domains)</span>
+</span>}
+soundManager.movieStarOptions = {<span>
+ bufferTime: null <span>// seconds of data to buffer (null = flash default of 0.1 - if AAC gappy, try up to 3 seconds)</span>
+</span>}
+<span><span>// if applicable, these options are merged into soundManager.defaultOptions at SM2 init.
+// soundManager.flash9Options.isMovieStar -> soundManager.defaultOptions.isMovieStar, etc.</span></span>
+</code></pre>
+
+ <h4 id="when-to-modify-version-specific" class="flash9" title="Flash 9+ only">defaultOptions.peakData vs. flash9Options.usePeakData</h4>
+
+ <p>Note that <code class="in">soundManager.defaultOptions.peakData</code> will be undefined until SoundManager 2 has self-initialized, at which point it determines the flash version to use and creates the .SWF, etc. Only then will defaultOptions be populated with optional option parameters, if applicable.</p>
+
+ <p class="in">Once SM2 has written out the .SWF, it is safe to modify <code>soundManager.defaultOptions.usePeakData</code> directly, for example - but if making changes <em>before</em> initialization, eg., at the time when you are setting <code>soundManager.flashVersion</code>, it is best to modify the source objects as they haven't yet been merged. ie., <code>soundManager.flash9Options.usePeakData = true;</code></p>
+
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div id="soundmanager2-dynamic-properties" class="columnar">
+ <div class="c1">
+ <h2>SoundManager Runtime Properties</h2>
+ <p>Elements of SoundManager which are set at runtime, intended as read-only.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block f-features f-supported f-waveformdata f-peakdata">
+
+ <h3 id="soundmanager-dynamic">SoundManager Dynamic (Runtime) Properties</h3>
+
+ <p class="in">Some properties are dynamic, determined at initialisation or later during runtime, and should be treated as read-only. Currently, <code><a href="#soundmanager-supported" onclick="resetFilter()">supported()</a></code> and <code>features</code> are the only properties that fall in this category.</p>
+
+ <h4 id="soundmanager-features">soundManager.features Object</h4>
+
+ <p class="in">As certain sound functionality is only available beginning with Flash 9, <code>soundManager.features</code> can provide a consistent way of checking for feature support.</p>
+
+ <p>The structure (intended as read-only) is currently as follows:</p>
+
+<pre class="block"><code>soundManager.features = {<span>
+ buffering: <span>[boolean]</span>,
+ peakData: <span>[boolean]</span>,
+ waveformData: <span>[boolean]</span>,
+ eqData: <span>[boolean]</span>,
+ movieStar: <span>[boolean]</span>
+</span>}</code></pre>
+
+ <p class="in">Example (checking for <code>peakData</code> support):</p>
+<pre class="block"><code>if (<span>soundManager.features.peakData</span>) {<span>
+ <span>// do peak data-related things here</span>
+</span>}</code></pre>
+
+ <p class="in">The features object is populated at initialisation time; the current feature support tests simply check the value of <code>soundManager.flashVersion</code> being >= 9. This object has been added in anticipation of additional features with future versions of Flash.</p>
+
+ </div>
+
+ </div>
+ </div>
+
+ <div id="soundmanager-events" class="columnar">
+ <div class="c1">
+ <h2>SoundManager Core Events</h2>
+ <p>Events fired by SoundManager at start-up</p>
+ </div>
+ <div class="c2">
+
+ <div class="f-block f-onload f-onerror f-oninitmovie">
+
+ <p class="in">The following events are attached to the <code>soundManager</code> global object and are useful for detecting the success/failure of the API's initialisation.</p>
+ <p>Keep in mind that these core events are effectively asynchronous (ie., they may fire long before or after <code class="in">window.onload()</code>) and therefore should not be relied on as the "ready" event for starting your application. Use the standard "DOM content loaded" or window load events for your own initialization routines.</p>
+ <p>For a more flexible queue-based, addListener-style approach to the onload event, see <code><a href="#soundmanager-onready" title="soundManager.onready() event queueing" onclick="resetFilter()">soundManager.onready()</a></code>.</p>
+
+ <dl>
+
+
+ <dt id="soundmanager-onerror" title="object:function">onerror()</dt>
+ <dd>Function called when SoundManager fails to successfully initialise after Flash attempts an init call via ExternalInterface.</dd>
+ <dd>Example: <code>soundManager.onerror = <span>function() { alert('SoundManager failed to load'); }</span></code></dd>
+ <dd>This handler should be called if there is an ExternalInterface problem or other exceptions that fire when the initialisation function is called.</dd>
+ <dd>If you want multiple listeners for this event, see <a href="#soundmanager-onready" onclick="resetFilter()">soundManager.onready()</a>.</dd>
+
+ <dt id="soundmanager-oninitmovie" title="object:function">oninitmovie()</dt>
+ <dd>Function called immediately after the SWF is either written to (or retrieved from) the DOM as part of the start-up process. This event can be useful if you wish to implement your own start-up time-out, eg. for handling flash blockers, start-up failures or other custom messaging.</dd>
+ <dd>Example: <code>soundManager.oninitmovie = <span>function(){ alert('SWF init.'); }</span></code></dd>
+
+ <dt id="soundmanager-onload" title="object:function">onload()</dt>
+ <dd>Function called when SoundManager has successfully loaded.</dd>
+ <dd>Example: <code>soundManager.onload = <span>function() { alert('SoundManager ready to use'); }</span></code></dd>
+ <dd>Once this function has been called, all core methods will be available to use.</dd>
+ <dd>Note that <code>onload()</code> is not called when SoundManager fails to load; instead, <code>onerror()</code> is called.</dd>
+ <dd>If you want multiple listeners for this event, see <a href="#soundmanager-onready" onclick="resetFilter()">soundManager.onready()</a>.</dd>
+
+ <dt title="method(object:function)">onready(<span>callback:function(status),[scope]</span>)</dt>
+ <dd title="callback:function">Queue <code>onload()</code>-style event listener(s), triggered when soundManager has either started or failed.</dd>
+ <dd>Example: <code>soundManager.onready(<span>myOnReadyHandler</span>); soundManager.onready(<span>myOtherHandler</span>);</code></dd>
+ <dd>For more detail and examples, see <a href="#soundmanager-onready" onclick="resetFilter()">soundManager.onready()</a>.</dd>
+
+ </dl>
+
+ </div>
+
+
+ </div>
+ </div>
+
+ <div class="columnar">
+ <div class="c1">
+ <h2>SoundManager Collections</h2>
+ <p>Object collections which SoundManager maintains during runtime.</p>
+ </div>
+ <div class="c2">
+
+ <div class="f-block">
+
+ <h3>SoundManager Object Collections</h3>
+
+ <dl>
+ <dt title="object:array">soundIDs[]</dt>
+ <dd>An array of sound ID strings, ordered by creation. Can be used to iterate through <code>sounds{}</code> by ID.</dd>
+ <dt title="object:array">sounds{}</dt>
+ <dd>An object literal/JSON-style instance of <code>SMSound</code> objects indexed by sound ID (as in <code>sounds['mySound']</code> or <code>sounds.mySound</code>), used internally by SoundManager. <code>soundManager.getSoundById()</code> may be used as an alternate to directly accessing this object.</dd>
+ </dl>
+
+ </div>
+
+ </div>
+ </div>
+
+ <div id="sound-options-object" class="columnar">
+
+ <div class="c1">
+ <h2>Sound Options Object Format</h2>
+ <p>Object Literal, JSON-style form passed to <code>createSound()</code> and <code>play()</code></p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block s-onload"> <!-- f-createsound s-sid s-url s-autoload s-autoplay s-onload -->
+
+ <h3 id="object-literal-format">Object Literal Format</h3>
+
+ <p>Sounds can be created with instance-specific parameters in an object literal (JSON) format, where omitted parameters inherit default values as defined in soundManager.</p>
+
+<pre class="block"><code>soundManager.createSound({<span>
+ id: 'mySound',
+ url: '/path/to/some.mp3',
+ autoLoad: true,
+ autoPlay: false,
+ onload: function() {
+ alert('The sound '+this.sID+' loaded!');
+ },
+ volume: 50
+</span>});</code></pre>
+
+ <p>This object can also be passed as an optional argument to the <code class="in">play</code> method, overriding options set at creation time.</p>
+
+ <p>For a full list of available options, see <a href="#sound-properties" title="SoundManager 2 API info: Sound Properties" onclick="resetFilter()">Sound Properties Object</a></p>
+
+ </div>
+
+
+ </div>
+
+ </div>
+
+ <div id="col3" class="c3">
+
+
+ <!--
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2" rel="nofollow">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ </div>
+ -->
+
+ <div id="shortcuts">
+
+<!--
+ <div class="box">
+
+ <h2>Shortcuts<span class="l"></span><span class="r"></span></h2>
+
+ <ul class="first">
+ <li onclick="setFilter(event,'c-')" class="ignore">
+
+ <ul>
+
+ <li>Demos</li>
+ <li>Getting Started</li>
+ <li>Basic Use</li>
+ <li>Download</li>
+ <li>Requirements</li>
+ <li>Limitations</li>
+
+ <li>Debug Output</li>
+ <li>Revision History</li>
+ <li>About</li>
+ </ul>
+
+ </li>
+ </ul>
+
+ </div>
+-->
+
+ <div class="box">
+
+ <h2>API Elements<span class="l"></span><span class="r"></span></h2>
+
+ <p>SoundManager and SMSound API</p>
+
+ <ul id="shortcuts-list" class="first">
+ <li onclick="return setFilter(event,'f-')" class="ignore">
+
+ <h3 class="wedge">SoundManager<span class="l"></span><span class="r"></span></h3>
+
+ <h4>Properties</h4>
+ <ul>
+
+ <li>allowPolling</li>
+ <li>allowScriptAccess</li>
+ <li><a href="#soundmanager-alturl">altURL</a></li>
+ <li>consoleOnly</li>
+ <li><a href="#soundmanager-debugflash">debugFlash</a></li>
+ <li><a href="#soundmanager-debugmode">debugMode</a></li>
+ <li><a href="#smdefaults">defaultOptions</a></li>
+ <li class="flash9" title="Flash 9-only"><a href="#sound-properties-flash9">flash9Options</a></li>
+ <li><a href="#soundmanager-features">features</a></li>
+ <li><a href="#soundmanager-flashloadtimeout">flashLoadTimeout</a></li>
+ <li><a href="#soundmanager-flashversion">flashVersion</a></li>
+ <li class="flash9" title="Flash 9.0r115+ only"><a href="#sound-properties-flash9">movieStarOptions</a></li>
+ <li>nullURL</li>
+ <li><a href="#soundmanager-url">url</a></li>
+ <li>useConsole</li>
+ <li class="flash9" title="Flash 9+ only"><a href="#soundmanager-usefastpolling">useFastPolling</a></li>
+ <li><a href="#soundmanager-useflashblock">useFlashBlock</a></li>
+ <li><a href="#soundmanager-highperformance">useHighPerformance</a></li>
+ <li class="recent" title="Recently-added, beta feature">useHTML5Audio</li>
+ <li class="flash9" title="Flash 9.0r115+ only">useMovieStar</li>
+ <li class="flash9" title="Flash 9.0r115+ only"><a href="#soundmanager-wmode">wmode</a></li>
+ <li>waitForWindowLoad</li>
+ </ul>
+
+ <h4>Methods</h4>
+
+ <ul>
+ <li class="recent"><a href="#soundmanager-canplaylink" title="Recently-added feature">canPlayLink()</a></li>
+ <li class="recent"><a href="#soundmanager-canplaymime" title="Recently-added feature">canPlayMIME()</a></li>
+ <li><a href="#soundmanager-canplayurl">canPlayURL()</a></li>
+ <li><a href="#soundmanager-createsound">createSound()</a></li>
+ <li><a href="#soundmanager-destroysound">destroySound()</a></li>
+ <li class="flash9" title="Flash 9.0+ only"><a href="#soundmanager-getmemoryuse">getMemoryUse()</a></li>
+ <li><a href="#soundmanager-getsoundbyid">getSoundById()</a></li>
+ <li><a href="#soundmanager-load">load()</a></li>
+ <li><a href="#soundmanager-loadfromxml">loadFromXML()</a></li>
+ <li><a href="#soundmanager-mute">mute()</a></li>
+ <li><a href="#soundmanager-pause">pause()</a></li>
+ <li><a href="#soundmanager-pauseall">pauseAll()</a></li>
+ <li><a href="#soundmanager-play">play()</a></li>
+ <li><a href="#soundmanager-reboot">reboot()</a></li>
+ <li><a href="#soundmanager-resume">resume()</a></li>
+ <li><a href="#soundmanager-resumeall">resumeAll()</a></li>
+ <li><a href="#soundmanager-setpan">setPan()</a></li>
+ <li><a href="#soundmanager-setposition">setPosition()</a></li>
+ <li><a href="#soundmanager-setvolume">setVolume()</a></li>
+ <li><a href="#soundmanager-supported">supported()</a></li>
+ <li><a href="#soundmanager-stop">stop()</a></li>
+
+ <li><a href="#soundmanager-stopall">stopAll()</a></li>
+ <li><a href="#soundmanager-togglemute">toggleMute()</a></li>
+ <li><a href="#soundmanager-togglepause">togglePause()</a></li>
+ <li><a href="#soundmanager-unload">unload()</a></li>
+ <li><a href="#soundmanager-unmute">unmute()</a></li>
+ </ul>
+
+ <h4>Events</h4>
+ <ul>
+ <li><a href="#soundmanager-onerror">onerror()</a></li>
+ <li><a href="#soundmanager-oninitmovie">oninitmovie()</a></li>
+ <li><a href="#soundmanager-onload">onload()</a></li>
+ <li><a href="#soundmanager-onready">onready()</a></li>
+ </ul>
+
+ </li>
+
+ <li onclick="setFilter(event,'s-')" class="ignore">
+
+ <h3 class="wedge">SMSound <span class="archive">(Sound Object)</span><span class="l"></span><span class="r"></span></h3>
+
+ <h4>Properties (Instance Options)</h4>
+ <ul>
+ <li>autoLoad</li>
+ <li>autoPlay</li>
+ <li title="Flash 9.0r115+ only" class="flash9">bufferTime</li>
+ <li title="Flash 9+ only" class="flash9"><a href="#smsound-eqdata">eqData</a></li>
+ <li title="Flash 9.0r115+ only" class="flash9">isMovieStar</li>
+ <li title="Recently-updated feature" class="recent">loops</li>
+ <li>multiShot</li>
+ <li>multiShotEvents</li>
+ <li>onbeforefinishtime</li>
+ <li>onjustbeforefinishtime</li>
+ <li>pan</li>
+ <li title="Flash 9+ only" class="flash9"><a href="#smsound-peakdata">peakData</a></li>
+ <li><a href="#smsound-position">position</a></li>
+ <li title="Flash 9+ only, new feature" class="flash9 new"><a href="#smsound-serverurl">serverURL</a></li>
+ <li><a href="#smsound-sid">sID</a></li>
+ <li>stream</li>
+ <li title="Recently-added feature" class="recent"><a href="#smsound-type">type</a></li>
+ <li><a href="#smsound-url">url</a></li>
+ <li title="New feature" class="new"><a href="#smsound-usepolicyfile">usePolicyFile</a></li>
+ <li>volume</li>
+ <li title="Flash 9+ only" class="flash9"><a href="#smsound-waveformdata">waveformData</a></li>
+ </ul>
+
+ <h4>Dynamic Properties</h4>
+ <ul>
+
+ <li><a href="#smsound-bytesloaded">bytesLoaded</a></li>
+ <li><a href="#smsound-bytestotal">bytesTotal</a></li>
+ <li title="Flash 9+" class="flash9"><a href="#smsound-isbuffering">isBuffering</a></li>
+ <li title="Flash 9+, new feature" class="flash9 new"><a href="#smsound-connected">connected</a></li>
+ <li><a href="#smsound-didbeforefinish">didBeforeFinish</a></li>
+ <li><a href="#smsound-didjustbeforefinish">didJustBeforeFinish</a></li>
+ <li><a href="#smsound-duration">duration</a></li>
+ <li><a href="#smsound-durationestimate">durationEstimate</a></li>
+ <li><a href="#smsound-loaded">loaded</a></li>
+ <li><a href="#smsound-muted">muted</a></li>
+ <li><a href="#smsound-paused">paused</a></li>
+ <li><a href="#smsound-playstate">playState</a></li>
+ <li><a href="#smsound-position">position</a></li>
+ <li><a href="#smsound-readystate">readyState</a></li>
+ </ul>
+
+ <h4>Events</h4>
+ <ul>
+ <li title="Flash 9+ required, recently-added feature" class="recent"><a href="#smsound-onbufferchange">onbufferchange()</a></li>
+ <li title="Flash 9+ required, new feature" class="new"><a href="#smsound-onconnect">onconnect()</a></li>
+ <li title="Flash 9.0.r115+" class="flash9"><a href="#smsound-ondataerror">ondataerror()</a></li>
+ <li><a href="#smsound-onfinish">onfinish()</a></li>
+ <li><a href="#smsound-onload">onload()</a></li>
+ <li><a href="#smsound-onpause">onpause()</a></li>
+ <li><a href="#smsound-onplay">onplay()</a></li>
+ <li class="new"><a href="#smsound-onposition">onposition()</a></li>
+ <li><a href="#smsound-onresume">onresume()</a></li>
+ <li><a href="#smsound-onstop">onstop()</a></li>
+ <li><a href="#smsound-onbeforefinishcomplete">onbeforefinishcomplete()</a></li>
+ <li><a href="#smsound-onbeforefinish">onbeforefinish()</a></li>
+ <li><a href="#smsound-onjustbeforefinish">onjustbeforefinish()</a></li>
+ <li><a href="#smsound-onid3">onid3()</a></li>
+ <li><a href="#smsound-whileloading">whileloading()</a></li>
+ <li><a href="#smsound-whileplaying">whileplaying()</a></li>
+ </ul>
+
+ <h4>Methods</h4>
+
+ <ul>
+ <li><a href="#smsound-destruct">destruct()</a></li>
+ <li><a href="#smsound-load">load()</a></li>
+ <li><a href="#smsound-mute">mute()</a></li>
+ <li><a href="#smsound-pause">pause()</a></li>
+ <li><a href="#smsound-resume">resume()</a></li>
+ <li><a href="#smsound-setpan">setPan()</a></li>
+ <li><a href="#smsound-setposition">setPosition()</a></li>
+ <li><a href="#smsound-setvolume">setVolume()</a></li>
+ <li><a href="#smsound-stop">stop()</a></li>
+ <li><a href="#smsound-togglemute">toggleMute()</a></li>
+ <li><a href="#smsound-togglepause">togglePause()</a></li>
+ <li><a href="#smsound-unload">unload()</a></li>
+ <li><a href="#smsound-unmute">unmute()</a></li>
+ </ul>
+
+ </li>
+ </ul>
+
+ <!-- /.box -->
+ </div>
+
+ </div>
+
+ </div>
+
+ <div class="clear"></div>
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+<script type="text/javascript">
+init();
+</script>
+
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/doc/resources/index.html b/docs/dymaxion/soundmanagerv297a-20101010/doc/resources/index.html new file mode 100755 index 0000000..a5b2c73 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/doc/resources/index.html @@ -0,0 +1,239 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Resources</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Sound and media web projects related to SoundManager 2." />
+<meta name="keywords" content="javascript sound, javascript audio, media web, embedded audio, embedded video" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../../demo/index.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="../../demo/index.js"></script>
+<script type="text/javascript">
+ soundManager.handleFlashBlock = false;
+ soundManager.debugMode = false;
+ soundManager.url = '../../swf/';
+ soundManager.onload = function() {
+ }
+</script>
+</head>
+
+<body>
+
+<div id="content">
+
+ <div id="top">
+
+ <h1>SoundManager 2: Resources</h1>
+
+ <div id="nav">
+ <ul>
+
+ <li>
+ <a href="../../">Home</a>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="../../demo/api/">API Examples</a></li>
+ <li><a href="../../demo/play-mp3-links/" class="exclude">Playable MP3 links</a></li>
+ <li><a href="../../demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="../../demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="../../demo/360-player/">360° Player UI</a></li>
+ <li><a href="../../demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="../../demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="../../demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="../../demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../getstarted/">Getting Started</a>
+ <ul>
+ <li><a href="../getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="../getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="../getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="..">Documentation</a>
+ <ul>
+ <li><a href="../#sm-config">SoundManager Properties</a></li>
+ <li><a href="../#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="../#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="../#api">SoundManager Core API</a></li>
+ <li><a href="../#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../download/">Download</a>
+ <ul>
+ <li><a href="../download/#latest">Get SoundManager 2</a></li>
+ <li><a href="../download/#revision-history">Revision History</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../technotes/">Technical Notes</a>
+ <ul>
+ <li><a href="../technotes/#requirements">System Requirements</a></li>
+ <li><a href="../technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <strong><a href="#">Resources</a></strong>
+ <ul>
+ <li><a href="#licensing">Licensing</a></li>
+ <li><a href="#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+
+ <div class="columnar">
+
+ <div class="c1">
+ <h2>Licensing</h2>
+ <p>BSD licensed.</p>
+ </div>
+
+ <div class="c2">
+ <h3>SoundManager 2 License</h3>
+ <p>SoundManager 2 is provided under a <a href="../../license.txt" title="SoundManager 2 BSD license" class="norewrite">BSD license</a>.</p>
+ </div>
+
+ </div>
+
+
+ <div id="related" class="columnar">
+ <div class="c1">
+ <h2>General + Related</h2>
+ <p>Other information about SoundManager 2.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block c-about">
+ <h3 id="general">General</h3>
+ <p>SoundManager was written to meet a desire to have Javascript-driven sound for interactive web-based projects, and "to make it easy to play MP3s in the browser." It is free for use in both personal and commercial projects (see <a href="#licensing" title="SoundManager 2 licensing information" onclick="resetFilter()">Licensing</a>.) It was originally developed for personal use and has been packaged with the hopes of being useful to others.</p>
+ </div>
+
+ <div class="f-block">
+
+ <h3 id="related-projects">Related Projects</h3>
+
+ <h4 id="html5-compatibility">HTML 5 Audio/Video Compatibility Wrappers, <audio> for HTML 4 etc.</h4>
+ <p><a href="http://gettingsoftware.posterous.com/html5flash-using-html5-video-and-audio-right">HTML5Flash</a> is a project that lets you use HTML 5's <code><audio></code> and <code><video></code> tags in HTML 4 browsers, making them compatible using SoundManager 2 behind the scenes.</p>
+ <p>Additionally, see the <a href="http://getsatisfaction.com/schillmania/topics/html5_audio">SM2 discussion thread on HTML 5 audio</a> support.</p>
+
+ <h4>JavaScript/DHTML/Flash MP3 and video players</h4>
+ <p>Searching for an included/embedded-type media player? These related projects might be of use.</p>
+ <ul>
+ <li><a href="http://www.happyworm.com/jquery/jplayer/" title="Happyworm jPlayer">jPlayer</a> is a HTML5/Flash player which jQuery fans should feel at home with; several different players and skins are provided.</li>
+ <li><a href="http://flowplayer.org" title="Flowplayer does video, with free and commercial versions available">Flowplayer</a> is a pretty solid GPL Flash-based video player with a JS API.</li>
+ <li><a href="http://www.longtailvideo.com/players/jw-flv-player/">JW FLV Player</a> is a general-purpose Flash-based player which can handle FLV, MP3, MP4 and a number of image formats.</li>
+ <li><a href="http://developer.yahoo.com/mediaplayer/" title="An embedded player that supports a number of sound formats">Yahoo! Media Player</a> supports a number of different formats depending on installed plugins (WMA etc.), can display artist / album information and so on.</li>
+ <li><a href="http://jssoundkit.sourceforge.net/" title="A Javascript/Flash MP3 player">JSSoundkit</a>, an MP3 player with a simple UI.</li>
+ </ul>
+
+ <h3 id="external-links">Links</h3>
+ <ul>
+ <li><a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 Web Home">SoundManager 2 Project Page</a> (schillmania.com)</li>
+ <li><a href="http://livedocs.adobe.com/flash/8/" title="Info on Flash 8's sound object">Flash 8 / AS2 documentation</a> (livedocs.macromedia.com) - download, open index.html under "main" subdirectory, use navigation: ActionScript 2.0 Language Reference -> ActionScript Classes -> Sound</li>
+ <li id="fpgss"><a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html" title="Configure Flash security settings">Flash Player Global Security Settings Panel</a> - Configure your Flash Player security, eg., allow SM2 .swf on your local filesystem to have internet access for testing by whitelisting its location eg. file://Users/Administrator/Desktop/soundmanager... etc. Alternately, view the page over HTTP and access internet resources that way.</li>
+ </ul>
+
+ </div>
+
+ <div class="f-block c-about">
+ <h3 id="sonundmanager-about">About</h3>
+ <p><a href="http://www.schillmania.com" title="Scott Schiller's experimental design site">Scott Schiller</a> (<a href="http://www.schillmania.com/content/react/contact/" title="Contact Info @ Schillmania.comrmation for Scott Schiller">contact</a>) is a Front-end Engineer (previously "Web Developer") who builds fun creative and technical stuff on the web - or failing that, tries - when he has free time. He likes building cool things which contribute to, yet enjoys mocking, the <a href="http://www.schillmania.com/content/opinion/2005/10/dont-believe-the-web-20-hype/" title="Web 2.0: Don't Believe The Hype!">Web 2.0 meme</a>. (See <a href="http://www.schillmania.com/content/entries/2006/08/how-web20-aware-are-you/" title="Take the Web 2.0 Awareness Test!">How Web 2.0-Aware Are You?</a>)</p>
+ </div>
+
+ </div>
+
+ </div>
+
+
+ <div id="col3" class="c3">
+
+
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ <!-- /.box -->
+
+ </div>
+
+ <div id="shortcuts">
+
+<!--
+ <div class="box">
+
+ <h2>Shortcuts<span class="l"></span><span class="r"></span></h2>
+
+ <ul class="first">
+ <li onclick="setFilter(event,'c-')" class="ignore">
+
+ <ul>
+
+ <li>Demos</li>
+ <li>Getting Started</li>
+ <li>Basic Use</li>
+ <li>Download</li>
+ <li>Requirements</li>
+ <li>Limitations</li>
+
+ <li>Debug Output</li>
+ <li>Revision History</li>
+ <li>About</li>
+ </ul>
+
+ </li>
+ </ul>
+
+ </div>
+-->
+
+ </div>
+
+
+
+ </div>
+
+ <div class="clear"></div>
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+<script type="text/javascript">
+init();
+</script>
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/doc/technotes/index.html b/docs/dymaxion/soundmanagerv297a-20101010/doc/technotes/index.html new file mode 100755 index 0000000..baec8e2 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/doc/technotes/index.html @@ -0,0 +1,305 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: Technical Notes</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Requirements and Specifications for SoundManager 2, the Javascript Sound API" />
+<meta name="keywords" content="javascript sound, javascript audio, technical specifications, requirements, licensing" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../../demo/index.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="../../demo/index.js"></script>
+<script type="text/javascript">
+ soundManager.debugMode = true;
+ soundManager.debugFlash = true;
+ soundManager.url = '../../swf/';
+ soundManager.onload = function() {
+ }
+</script>
+</head>
+
+<body>
+
+<div id="content">
+
+ <div id="top">
+
+ <h1>SoundManager 2: Technical Notes</h1>
+
+ <div id="nav">
+ <ul>
+
+ <li>
+ <a href="../../">Home</a>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="../../demo/api/">API Examples</a></li>
+ <li><a href="../../demo/play-mp3-links/" class="exclude">Playable MP3 links</a></li>
+ <li><a href="../../demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="../../demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="../../demo/360-player/">360° Player UI</a></li>
+ <li><a href="../../demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="../../demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="../../demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="../../demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../getstarted/">Getting Started</a>
+ <ul>
+ <li><a href="../getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="../getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="../getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="..">Documentation</a>
+ <ul>
+ <li><a href="../#sm-config">SoundManager Properties</a></li>
+ <li><a href="../#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="../#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="../#api">SoundManager Core API</a></li>
+ <li><a href="../#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../download/">Download</a>
+ <ul>
+ <li><a href="../download/#latest">Get SoundManager 2</a></li>
+ <li><a href="../download/#revision-history">Revision History</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <strong><a href="../technotes/">Technical Notes</a></strong>
+ <ul>
+ <li><a href="../technotes/#requirements">System Requirements</a></li>
+ <li><a href="../technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="../resources/">Resources</a>
+ <ul>
+ <li><a href="../resources/#licensing">Licensing</a></li>
+ <li><a href="../resources/#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+
+ <div id="filter-box" class="columnar">
+
+ <div class="c1">
+ <div id="reset-filter"></div>
+ </div>
+
+ <div class="c2">
+ <div id="search-results"><!-- search results for %s --></div>
+ </div>
+
+ </div>
+
+ <div class="columnar">
+
+ <div class="c1">
+ <h2>Requirements + Specifications</h2>
+ <p>What SM2 needs, and how it works.</p>
+ </div>
+
+ <div class="c2">
+
+ <div class="f-block c-requirements">
+
+ <h3>Requirements + Specifications</h3>
+
+ <h4 style="margin-top:1.5em">Prerequisites (client)</h4>
+
+ <ul>
+ <li>Flash plugin, version 8 or higher</li>
+ <li>Supported Browser</li>
+ </ul>
+
+ <h4>Supported Browsers/Platforms</h4>
+
+ <p>Javascript-to-flash communication is possible through Flash 8's ExternalInterface feature, which uses a standard browser plugin architecture implemented by each browser manufacturer (see <a href="http://www.mozilla.org/projects/plugins/npruntime.html" title="Mozilla plugin scripting reference">NPAPI</a>.) As a result, the following browsers should be supported:</p>
+
+ <ul>
+ <li>IE 5.0+, Windows</li>
+ <li>Netscape 8.0+, Windows/Mac</li>
+ <li>Mozilla 1.7.5+, Windows/Mac</li>
+ <li>Firefox 1.0+, Windows/Mac</li>
+ <li>Firefox 1.5+, Linux (Flash 9 beta)</li>
+ <li>Safari 1.3+, Mac / All Windows versions</li>
+ <li>Google Chrome (All versions/OSes)</li>
+ <li>Opera 9.10 (slightly buggy, 9.5+ ideal), Windows/Mac</li>
+ </ul>
+
+ <p>For reference, see Adobe's <a href="http://livedocs.macromedia.com/flash/8/" title="Adobe Flash 8 documentation">Flash 8 documentation</a>, under the "ExternalInterface support" page which details supported browsers.</p>
+
+ <p>At this time, not all combinations of browser/OS have been tested. Some unlisted configurations may be supported, but have not been explicitly verified to work.</p>
+
+ </div>
+
+ <div class="f-block c-limitations">
+
+ <h3 id="caveats">Caveats + Limitations / FAQ</h3>
+
+ </div>
+
+ <div class="f-block c-limitations">
+
+ <h4>Supported sound formats (MP3 via Flash 8 and MP4/M4A/AAC via Flash 9 "MovieStar", with caveats)</h4>
+ <p>SM2 uses Flash's native Sound object for loading and managing sound, so it is subject to the same limitations that Flash 8 is. Perhaps a design decision, the Flash 8 sound object only supports MP3 files through the <code class="in">loadSound()</code> ActionScript method. SM2 is not able to load other sound formats, including audio-only SWF files, due to this limitation. Refer to the <a href="http://livedocs.macromedia.com/flash/8/" title="Info on Flash 8's sound object">Flash 8 documentation</a> for details.</p>
+
+ <h4>MP3 Format Caveats</h4>
+ <p>Additionally, some very low and very high bitrate MP3s, and Variable Bitrate (VBR) MP3s may play either too quickly or too slowly (see <a href="http://www.boutell.com/newfaq/creating/chipmunk.html" title="Flash mp3 chipmunk problem description">"the chipmunk problem"</a>); if you are encountering this issue, try re-encoding at a different bitrate (between 64 kbps and 192 kbps, for example.) Using Constant Bitrate (CBR) encoding may also alleviate this problem.</p>
+ <p>It has been suggested that sample rates that are neither 22/44 KHz can also contribute to this issue. 44 KHz is the standard CD-spec sample rate, and is recommended for "hi-fi" recordings.</p>
+
+ <h4>Looping</h4>
+ <p class="in">Perhaps due to the way Flash dynamically loads and decodes MP3 data, seamless looping doesn't seem to be fully implemented. Loops have a noticeable gap between the finish and start. This has been an issue since the original version of SoundManager. Rather than have a broken feature, the funcionality has been omitted until a solid workaround is found.</p>
+
+ <h4>Flash 8 limitations with multiShot (overlaying/"chorus") effects</h4>
+ <p class="in">Regarding "layering" sounds (calling <code>play()</code> on a sound multiple times): Even though a multi-shot option can be specified, it does not work with Flash 8; a single instance of a sound can only have one timeline. The current behaviour is that when <code>multiShot</code> is specified and <code>play()</code> is called on a currently-playing sound, it will restart from the beginning without an overlay.</p>
+ <p>However, the API does provide some creative ways (<code class="in">onbeforefinish</code> for looping, multiple sound objects for multi-shot layering) of working around these Flash limitations.</p>
+ <p>It should be noted that sounds can loop seamlessly and be layered when linked and exported to SWF from within the Flash IDE, but SoundManager does not support SWF-based audio.</p>
+
+ <h4>Flash 9 multiShot capabilities</h4>
+ <p class="in">The Flash 9-based version of SoundManager2 can successfully layer sounds via "multiShot", truly playing a single sound multiple times on top of itself. However the API will only call certain timing-related methods such as <code>whileplaying()</code> for the first <code>play()</code> "instance" of the sound, to avoid confusion. By contrast, simpler methods such as <code>onfinish()</code> will be called multiple times, one for each instance of <code>play()</code>.</p>
+
+ <h4 id="id3-parsing">ID3 Parsing</h4>
+ <p>ID3 data can differ in formatting, version and subsequently be oddly-parsed by Flash. Values may sometimes be repeated across different fields.</p>
+ <p>ID3 info seems to fail to load for iTunes 7-edited files, perhaps due to the format or inclusion of album artwork (image data.)</p>
+
+ <h4>Performance Notes: Caching + RAM Obeservations</h4>
+ <p>Flash appears to use the browser cache (presumably the OS' native, or closest browser,) so the browser's cache size and other settings may affect Flash's cache behaviour. It is safe to assume a 100 MB MP3 will probably not be cached, for example, but a 16 MB one most likely will be.</p>
+ <p>MP3s appear to be loaded and stored in RAM while loading over HTTP, so memory use needs to be considered for both large MP3s and streaming radio-type applications.</p>
+
+ <h4>Timing/Latency (JS + Flash, ExternalInterface-related)</h4>
+ <p>Javascript-to-Flash communication is not instantaneous on slower systems, but can be much better on more modern systems. Latency (timing lag/delays) can be noted in some cases from function call to sound execution. It is possible some performance analysis can help to speed up this area for timing-critical applications involving animation etc., but this area has not been thoroughly investigated yet. Brad Neuberg has some notes on <a href="http://codinginparadise.org/weblog/2006/02/how-to-speed-up-flash-8s.html" title="Brad Neuberg - How To Speed Up ExternalInterface">speeding up ExternalInterface</a> which may be relevant.</p>
+ <p>Flash-to-OS/hardware latency (where flash reports progress, but no sound is heard for a number of milliseconds) may also be an unfortunate reality of Flash-based audio, varying between platform and OS version etc.</p>
+ <p>Additionally, MP3 files may contain audible gaps at the beginning or end by default when encoded, even if the source (eg. WAVE) file did not. Using optional "nogap" encoding options with programs such as LAME may help to remedy this.</p>
+ <p>Finally, the <code class="in">useHighPerformance</code> option may help with JS/flash lag. Using this option causes the flash movie to be placed with position:fixed on-screen at all times (though in a small, hidden box) and has been shown to notably improve performance on Mac OS X. As well, <code class="in">useFastPolling</code> will use a lower timer interval within Flash, making polling calls run as quickly as reasonably possible and increasing the frequency of calls to <code class="in">whileplaying()</code>, <code class="in">whileloading()</code> and other time-related events.</p>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div id="debug-output" class="columnar">
+ <div class="c1">
+ <h2>Debug + Console Output</h2>
+ <p>Console-style messaging, useful for troubleshooting start-up and runtime issues.</p>
+ </div>
+
+ <div class="c2">
+ <h3>Live Debug Output</h3>
+ <p class="in">With debug mode enabled via <code>soundManager.debugMode = true</code>, SM2 can write helpful troubleshooting information to javascript <code>console.log()</code>-style interfaces. Additionally, output can be written to an optional DIV element with the ID of "<code>soundmanager-debug</code>".</p>
+ <p class="in"><code>soundManager.consoleOnly</code> can be set to true to disable HTML output (using <code>console.log()</code>-only methods) as well.</p>
+ <p>Additionally, debugging within the Flash portion of SM2 is also available and set using <code>soundManager.debugFlash = true</code>. Debug messages are written to the flash movie itself.</p>
+ <p>For info on SoundManager 2 loading/initialization failures and how to fix them, see <a href="../getstarted/#troubleshooting">troubleshooting</a>.</p>
+
+ <p>Below is a live example of debug output from SM2:</p>
+
+ <div id="live-debug" class="block">
+ <div id="soundmanager-debug" class="code">
+ <!-- live debug goes here -->
+ </div>
+ </div>
+
+ <p>And, Flash debug output:</p>
+
+ <div id="sm2-container">
+ <!-- flash movie goes here -->
+ </div>
+
+ </div>
+
+ </div>
+
+
+ <div id="col3" class="c3">
+
+
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2" rel="nofollow">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ <!-- /.box -->
+
+ </div>
+
+ <div id="shortcuts">
+
+<!--
+ <div class="box">
+
+ <h2>Shortcuts<span class="l"></span><span class="r"></span></h2>
+
+ <ul class="first">
+ <li onclick="setFilter(event,'c-')" class="ignore">
+
+ <ul>
+
+ <li>Demos</li>
+ <li>Getting Started</li>
+ <li>Basic Use</li>
+ <li>Download</li>
+ <li>Requirements</li>
+ <li>Limitations</li>
+
+ <li>Debug Output</li>
+ <li>Revision History</li>
+ <li>About</li>
+ </ul>
+
+ </li>
+ </ul>
+
+ </div>
+-->
+
+ </div>
+
+
+
+ </div>
+
+ <div class="clear"></div>
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+<script type="text/javascript">
+init();
+</script>
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/index.html b/docs/dymaxion/soundmanagerv297a-20101010/index.html new file mode 100755 index 0000000..dd271ca --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/index.html @@ -0,0 +1,513 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2: JavaScript Sound For The Web</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="Play sound from JavaScript including MP3, MPEG-4 and HTML5-supported audio formats with SoundManager 2, a cross-browser/platform sound API. BSD licensed." />
+<meta name="keywords" content="javascript sound, html5 audio, html5 sound, javascript audio, javascript play mp3, javascript sound control, mp3, mp4, mpeg4, aac, Scott Schiller, Schill, Schillmania" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- base library + a bunch of demo components (yay, they all work together) -->
+<link rel="stylesheet" type="text/css" href="demo/play-mp3-links/css/inlineplayer.css" />
+<link rel="stylesheet" type="text/css" href="demo/page-player/css/page-player.css" />
+<link rel="stylesheet" type="text/css" href="demo/360-player/360player.css" />
+<link rel="stylesheet" type="text/css" href="demo/mp3-player-button/css/mp3-player-button.css" />
+<link rel="stylesheet" type="text/css" href="demo/flashblock/flashblock.css" />
+<link rel="stylesheet" type="text/css" media="screen" href="demo/index.css" />
+<script type="text/javascript" src="script/soundmanager2.js"></script>
+<script type="text/javascript">
+var PP_CONFIG = {
+ flashVersion: 9, // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.
+ usePeakData: true // L/R peak data
+}
+</script>
+<script type="text/javascript" src="demo/mp3-player-button/script/mp3-player-button.js"></script>
+<script type="text/javascript" src="demo/page-player/script/page-player.js"></script>
+<script type="text/javascript" src="demo/play-mp3-links/script/inlineplayer.js"></script>
+<!-- 360 UI demo, canvas magic for IE -->
+<!--[if IE]><script type="text/javascript" src="demo/360-player/script/excanvas.js"></script><![endif]-->
+<!-- 360 UI demo, Apache-licensed animation library -->
+<script type="text/javascript" src="demo/360-player/script/berniecode-animator.js"></script>
+<script type="text/javascript" src="demo/360-player/script/360player.js"></script>
+
+<script type="text/javascript">
+// <![CDATA[
+
+ var isHome = true;
+ if (!window.location.href.toString().match(/sm2-usehtml5audio/i)) {
+ soundManager.useHTML5Audio = true; // w00t.
+ }
+ soundManager.useFlashBlock = true;
+ soundManager.bgColor = '#ffffff';
+ soundManager.debugMode = false;
+ soundManager.url = 'swf/';
+ soundManager.wmode = 'transparent'; // hide initial flash of white on everything except firefox/win32
+ if (navigator.platform.match(/win32/i) && navigator.userAgent.match(/firefox/i)) {
+ // extra-special homepage case (you should never see this), prevent out-of-view SWF load failure WITH high performance AND flashblock AND SWF in a placed element
+ soundManager.useHighPerformance = false;
+ }
+ soundManager.useFastPolling = true;
+
+ if (!navigator.userAgent.match(/msie 6/i)) {
+ threeSixtyPlayer.config.imageRoot = 'demo/360-player/';
+ }
+
+ function checkBadSafari() {
+ var _ua = navigator.userAgent;
+ if (!window.location.toString().match(/sm2\-ignorebadua/i) && _ua.match(/safari/i) && !_ua.match(/chrome/i) && _ua.match(/OS X 10_6_(3|4)/i)) { // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" bug. https://bugs.webkit.org/show_bug.cgi?id=32159
+ var complaint = document.createElement('li');
+ complaint.innerHTML = '<b>Note</b>: HTML5 audio disabled for this browser/OS due to load/play failures in Safari 4 + 5 on Snow Leopard 10.6.3/4, caused by bugs in QuickTime X and/or underlying frameworks. See <a href="https://bugs.webkit.org/show_bug.cgi?id=32159#c9">bugs.webkit.org #32519</a>. (Safari on Leopard + Win32, and iPad OK, however.)<br>Try <a href="?sm2-ignorebadua">HTML5 anyway?</a> ("water drop" MP3 playback seems to fail most often.)';
+ _id('html5-audio-notes').appendChild(complaint);
+ }
+ }
+
+ soundManager.onready(function() {
+ if (soundManager.supported()) {
+ _id('sm2-support').style.display = 'none';
+ doChristmasLights();
+ // if using HTML5, show some additional format support info
+ // written while watching The Big Lebowski for the Nth time. Donny, you're out of your element!
+ var s = soundManager;
+ if (s.useHTML5Audio && s.hasHTML5) {
+ var li = document.createElement('li');
+ li.className = 'html5support';
+ var items = [];
+ var needsFlash = false;
+ for (item in s.audioFormats) {
+ if (s.audioFormats.hasOwnProperty(item)) {
+ needsFlash = (soundManager.filePattern.test('.'+item));
+ items.push('<span class="'+(s.html5[item]?'true':'false')+(!s.html5[item] && needsFlash?' partial':'')+'" title="'+(s.html5[item]?'Native HTML5 support found':'No HTML5 support found'+(needsFlash?', using Flash fallback':', no Flash support either'))+'">'+(s.html5[item]?'<':'')+item+(s.html5[item]?'>':'')+'</span>');
+ }
+ }
+ li.innerHTML = 'This browser\'s <em class="true"><HTML5></em> vs. <em class="partial">Flash</em> support (best guess):<b>'+items.join('')+'</b>'+(!soundManager._use_maybe?' (Try <a href="#sm2-useHTML5Maybe=1" onclick="window.location.href=this.href;window.location.reload()" title="Try using probably|maybe for HTML5 Audio().canPlayType(), more buggy but may get HTML5 support on Chrome/OS X and other browsers.">less-strict HTML5 checking</a>?)':' (allowing <b>maybe</b> for <code>canPlayType()</code>, less-strict HTML5 audio support tests)');
+ _id('html5-audio-notes').appendChild(li);
+ _id('without-html5').style.display = 'inline';
+ } else {
+ _id('without-html5').style.display = 'none';
+ }
+ checkBadSafari();
+ // check inline player / HTML 5 bits
+ var items = _id('muxtape-html5').getElementsByTagName('a');
+ for (var i=0, j=items.length; i<j; i++) {
+ if (!soundManager.canPlayLink(items[i])) {
+ items[i].className += ' not-supported';
+ items[i].title += ' \n\nNOTE: Format apparently not supported by this browser.';
+ }
+ }
+ } else {
+ checkBadSafari();
+ }
+ });
+
+ soundManager.onerror = function() {
+ // failed to load
+ var o = _id('sm2-support');
+ var smLoadFailWarning = '<div style="margin:0.5em;margin-top:-0.25em"><h3>Oh snap!</h3><p>'+(soundManager.hasHTML5?'The flash portion of ':'')+'SoundManager 2 was unable to start. '+(soundManager.useHTML5Audio?(soundManager.hasHTML5?'</p><p>Partial HTML5 Audio() is present, but flash is needed for MP3 and/or MP4 support.':'<br>(No HTML5 Audio() support found, either.)'):'')+'<br>All links to audio will degrade gracefully.</p><p id="flashblocker">If you have a flash blocker, try allowing the SWF to run - it should be visible above.</p><p id="flash-offline">'+(!soundManager._overHTTP?'<b>Viewing offline</b>? You may need to change a Flash security setting.':'Other possible causes: Missing .SWF, or no Flash?')+' Not to worry, as guided help is provided.</p><p><a href="doc/getstarted/index.html#troubleshooting" class="feature-hot">Troubleshooting</a></p></div>';
+ var hatesFlash = (navigator.userAgent.match(/(ipad|iphone)/i));
+ o.innerHTML = smLoadFailWarning;
+ if (hatesFlash || soundManager.getMoviePercent()) {
+ // movie loaded at least somewhat, so don't show flashblock things
+ _id('flashblocker').style.display = 'none';
+ if (hatesFlash) {
+ // none of that here.
+ _id('flash-offline').style.display = 'none';
+ }
+ }
+ o.style.marginBottom = '1.5em';
+ o.style.display = 'block';
+ }
+
+ // side note: If it's not december but you want to smash things, try #christmas=1 in the homepage URL.
+
+// ]]>
+</script>
+<script type="text/javascript" src="demo/index.js"></script>
+<script type="text/javascript">
+// <![CDATA[
+function doChristmasLights() {
+ if ((document.domain.match(/schillmania.com/i) && new Date().getMonth() == 11) || window.location.toString().match(/christmas/i)) {
+ loadScript('http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js',function(){
+ loadScript('../demo/christmas-lights/christmaslights-home.js',function(){
+ if (typeof smashInit != 'undefined') {
+ setTimeout(smashInit,20);
+ }
+ });
+ });
+ }
+}
+// ]]>
+</script>
+<style type="text/css">
+
+/* one small hack. */
+.ui360 a.sm2_link {
+ position:relative;
+}
+
+.ui360 {
+ /* Firefox 3 doesn't show links otherwise? */
+ width:100%;
+}
+
+body #sm2-container object,
+body #sm2-container embed {
+ /* otherwise, firefox on win32 barfs on homepage. */
+ left:0px;
+ top:0px;
+}
+
+</style>
+</head>
+
+<body class="home">
+
+<div id="content">
+
+ <div id="top">
+ <div id="lights"></div>
+
+ <h1>A JavaScript Sound API supporting MP3, MPEG4 and HTML5 Audio.</h1>
+
+ <div id="nav">
+ <div id="version"></div>
+ <ul>
+
+ <li>
+ <strong><a href="#home">Home</a></strong>
+ </li>
+
+ <li>
+ <a href="#">Demos</a>
+ <ul>
+ <li><a href="demo/api/">API Examples</a></li>
+ <li><a href="demo/play-mp3-links/">Playable MP3 links</a></li>
+ <li><a href="demo/mp3-player-button/" class="exclude">Basic MP3 Play Button</a></li>
+ <li><a href="demo/page-player/">Muxtape-style UI</a></li>
+ <li><a href="demo/360-player/">360° Player UI</a></li>
+ <li><a href="demo/mpc/">Drum Machine (MPC)</a></li>
+ <li><a href="demo/animation/">DOM/Animation Demos</a></li>
+ <li><a href="demo/flashblock/">FlashBlock Handling</a></li>
+ <li><a href="demo/template/">Basic Template</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="doc/getstarted/">Getting Started</a>
+ <ul>
+ <li><a href="doc/getstarted/#how-sm2-works">How SoundManager 2 works</a></li>
+ <li><a href="doc/getstarted/#basic-inclusion">Including SM2 on your site</a></li>
+ <li><a href="doc/getstarted/#troubleshooting">Troubleshooting</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="doc/">Documentation</a>
+ <ul>
+ <li><a href="doc/#sm-config">SoundManager Properties</a></li>
+ <li><a href="doc/#sound-object-properties">Sound Object Properties</a></li>
+ <li><a href="doc/#smdefaults">Global Sound Defaults</a></li>
+ <li><a href="doc/#api">SoundManager Core API</a></li>
+ <li><a href="doc/#smsoundmethods">Sound Object (SMSound) API</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="doc/download/">Download</a>
+ <ul>
+ <li><a href="doc/download/#latest">Get SoundManager 2</a></li>
+ <li><a href="doc/download/#revision-history">Revision History</a></li>
+ </ul>
+
+ </li>
+
+ <li>
+ <a href="doc/technotes/">Technical Notes</a>
+ <ul>
+ <li><a href="doc/technotes/#requirements">System Requirements</a></li>
+ <li><a href="doc/technotes/#debug-output">Debug + Console Output</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="doc/resources/">Resources</a>
+ <ul>
+ <li><a href="doc/resources/#licensing">Licensing</a></li>
+ <li><a href="doc/resources/#related">Related Projects</a></li>
+ <li><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/">SM2 support / discussion</a></li>
+ <li><a href="http://www.schillmania.com/content/react/contact/">Contact Info @ Schillmania.com</a></li>
+ </ul>
+ </li>
+
+ </ul>
+ <div class="clear"></div>
+ </div>
+
+ </div>
+
+ <div id="main" class="triple">
+
+ <div id="live-demos" class="columnar">
+
+ <div class="c1">
+ <h2>What SoundManager 2 does</h2>
+ <p>Audio features, accessible from JavaScript.</p>
+ </div>
+
+ <div class="c2">
+
+ <h3>About SoundManager 2, Features and Live Demos</h3>
+
+ <div style="position:relative;padding-top:0.5em;padding-bottom:0.75em">
+
+ <img src="demo/_image/speaker.png" alt="speaker icon" style="float:left;display:inline;width:68px;height:68px;margin:1em 1em 0px 0px" />
+
+ <h2 class="special" style="margin-top:0.33em">SoundManager 2 makes it easier to play audio using JavaScript.</h2>
+
+ <p style="margin-top:0.5em">By wrapping and extending HTML5 and Flash Audio APIs, SoundManager 2 brings reliable cross-platform audio to JavaScript. <a href="doc/getstarted/#intro" class="cta" style="white-space:nowrap">How it works <span>»</span></a></p>
+
+ <div class="clear"> </div>
+
+ </div>
+
+ <div id="demo-box">
+ <div id="sm2-container"><!-- SM2 flash component goes here --></div>
+ <div id="sm2-support" class="demo-block"></div>
+ <p id="demo-header"><strong style="font-size:1.1em;font-weight:bold;white-space:nowrap">Inline JavaScript Sound API Examples</strong></p>
+ <div id="demos">
+ <h3 class="wedge" style="border-bottom:none;margin-top:0px">Basic MP3 Buttons<span class="l"></span><span class="r"></span><a href="demo/mp3-player-button/" title="Basic MP3 Play Button demo" class="cta-more">More »</a></h3>
+ <div class="demo-block">
+ <p style="margin-bottom:0.25em;margin-left:0.25em">
+ Change <a href="demo/_mp3/coins.mp3" title="Play "Change"" class="sm2_button exclude inline-exclude norewrite" style="padding:0px">coins.mp3</a>
+ <span style="color:#999">|</span>
+ Glass 1 <a href="demo/christmas-lights/sound/glass0.mp3" class="sm2_button exclude inline-exclude norewrite" title="Play "Glass break 1"" style="padding:0px">glass0.mp3</a>
+ <span style="color:#999">|</span> 2 <a href="demo/christmas-lights/sound/glass1.mp3" class="sm2_button exclude inline-exclude threesixty-exclude norewrite" title="Play "Glass break 2"" style="padding:0px">glass1.mp3</a>
+ <span style="color:#999">|</span> 3 <a href="demo/christmas-lights/sound/glass2.mp3" class="sm2_button exclude inline-exclude threesixty-exclude norewrite" title="Play "Glass break 3"" style="padding:0px">glass2.mp3</a>
+ </p>
+ </div>
+ <h3 class="wedge" style="border-bottom:none;margin-top:0px">Playable MP3 links<span class="l"></span><span class="r"></span><a href="demo/play-mp3-links/" title="Playable MP3 links demo" class="cta-more">More »</a></h3>
+ <div class="demo-block">
+ <ul class="graphic" style="padding:0.5em 0px 0.25em 0.25em">
+ <li><a href="demo/_mp3/fancy-beer-bottle-pop.mp3" title="Demo audio: Popping a corked beer bottle. Slightly distorted." class="exclude button-exclude norewrite">A corked beer bottle</a></li>
+ </ul>
+ </div>
+ <h3 class="wedge" style="border-bottom:none;margin-top:0px">360° Player UI<span class="l"></span><span class="r"></span><a href="demo/360-player/" title="360° Player UI demo" class="cta-more">More »</a></h3>
+ <div class="demo-block" style="overflow:hidden">
+ <div style="margin-bottom:16px;margin-left:8px;margin-top:-4px">
+ <div class="ui360" style="float:left;display:inline;margin-right:16px"><a href="demo/_mp3/mak.mp3" title="360 demo: Angry Cow Sound" class="norewrite exclude button-exclude inline-exclude">Random</a></div>
+ <div class="ui360" style="position:absolute;left:50%"><a href="http://freshly-ground.com/data/audio/sm2/water-drop.mp3" title="360 Demo: Water Drop" class="exclude button-exclude inline-exclude">Water Drop</a></div>
+ <div class="clear"></div>
+ </div>
+ </div>
+
+ <h3 class="wedge" style="border-bottom:none;margin-top:0px">Muxtape-style UI <span class="sidenote">(+HTML5 tests)</span><span class="l"></span><span class="r"></span><a href="demo/page-player/" title="Muxtape-style UI demo (+HTML5 audio tests)" class="cta-more">More »</a></h3>
+ <div class="demo-block">
+ <ul class="playlist" style="margin-top:0.5em">
+ <li><a href="http://freshly-ground.com/data/audio/mpc/20060826 - Armstrong.mp3" class="button-exclude inline-exclude threesixty-exclude">Armstrong Beat</a></li>
+ <li><a href="http://freshly-ground.com/data/audio/mpc/20090119 - Untitled Groove.mp3" class="button-exclude inline-exclude threesixty-exclude">Untitled Groove</a></li>
+ <li><a href="http://freshly-ground.com/data/audio/sm2/quail-64kbps-he-aac-from-itunes-renamed-from-mp4.aac" title="48 kbps MPEG4 High-Efficiency AAC test sound: BC Quail" class="button-exclude inline-exclude threesixty-exclude">BC Quail <span class="sidenote">(HE-AAC)</span></a></li>
+ </ul>
+ <h4 style="margin:0.25em 0px 0px 0px;padding:0.5em 0px 0.5em 0.75em;font-size:0.9em;letter-spacing:0.01em;border:1px solid #eee;border-left:none;border-right:none;font-weight:normal;color:#333;border-top:none">HTML5 Audio()-only tests</h4>
+ <ul id="muxtape-html5" class="playlist" style="margin-top:0.5em">
+ <li><a href="http://freshly-ground.com/data/audio/sm2/20060924%20-%20Ghosts%20&%20Goblins%20Reconstructed.ogg" title="OGG sound format, requires HTML5 Audio() support to play" class="button-exclude inline-exclude threesixty-exclude" style="font-size:0.8em">Ghosts+Goblins Reconstructed <span class="sidenote">(OGG)</span></a></li>
+ <li><a href="http://freshly-ground.com/data/audio/sm2/bottle-pop.wav" title="WAV sound format, requires HTML5 Audio() support to play" class="button-exclude inline-exclude threesixty-exclude" style="font-size:0.8em">A corked beer bottle <span class="sidenote">(WAV)</span></a></li>
+ </ul>
+ <p class="note" style="margin-top:3px;margin-bottom:0px;margin-left:0.8em">More: <a href="demo/api/" title="SoundManager 2 API examples">API</a> | <a href="demo/mpc/" title="SoundManager 2 MPC/Drum Machine demo">Drum Machine</a> | <a href="demo/animation/" title="SoundManager 2 DOM / Animation demos" class="exclude">Animation</a></p>
+
+ </div>
+
+ <div class="clear"> </div>
+
+ <div style="position:relative;clear:both;margin-top:1em;text-align:right">
+ <span id="without-html5" style="display:none"><a href="#sm2-usehtml5audio=0" onclick="document.location.href=this.href;document.location.reload()" title="View this page without HTML5 Audio support">-html5</a> | </span>
+ <a href="#debug=1" id="with-debug" title="View this page with debug output mode enabled (console.log() or HTML-based)" onclick="document.location.href=this.href;document.location.reload()">+debug</a>
+ <script type="text/javascript">if (document.location.href.match(/debug=1/i)) document.getElementById('with-debug').style.display = 'none';</script>
+ </div>
+
+ </div>
+
+ </div>
+
+ <h4 style="clear:left;margin-top:0.5em">HTML5 Audio Support <span style="color:#888">(Beta-ish)</span></h4>
+ <ul id="html5-audio-notes" class="standard">
+ <li>100% Flash-free MP3 + MP4/AAC where supported. Works on iPad, iPhone iOS 4</li>
+ <li>Fallback to Flash for MP3/MP4 support, as needed</li>
+ <li>SM2 API is unchanged, transparent; HTML5/Flash switching handled internally</li>
+ <li>HTML5 API support approximates Flash 8 API features, minus ID3, plus buffering</li>
+ <li>Some other formats (WAV/OGG) supported via HTML5, depending on browser</li>
+ <li>See <a href="doc/#soundmanager-usehtml5audio" title="soundManager.useHTML5Audio HTML5 Audio() support feature documentation">soundManager<wbr>.useHTML5Audio</a> for implementation details</li>
+ </ul>
+
+ <h4>Basic API Features (Flash 8)</h4>
+ <ul class="standard">
+ <li>Load, stop, play, pause, mute, seek, pan, volume control from JavaScript</li>
+ <li>Events: onload(), whileloading(), whileplaying(), onfinish() and more</li>
+ <li>ID3V1 and ID3V2 tag support for MP3s (title, artist, genre etc.)</li>
+ </ul>
+
+ <h4>Shiny Flash 9-only Features</h4>
+
+ <div style="float:right;display:inline;margin:0px;text-align:center;font-size:x-small;white-space:nowrap">
+ <a href="demo/360-player/canvas-visualization.html" title="JavaScript + Canvas MP3 visualization demo" style="border:none;margin:0px;padding:0px"><img id="demo-360" src="demo/_image/360ui-screenshot3.png" alt="" style="margin:0px;padding:0px;border:none" /></a>
+ <div><a href="demo/360-player/canvas-visualization.html" title="JavaScript + Canvas MP3 visualization demo">360° UI + waveform/spectrum</a></div>
+ <div class="note" style="margin-top:0px">Beta-ish, somewhat experimental demo</div>
+ <script type="text/javascript">document.getElementById('demo-360').src='demo/_image/360ui-screenshot'+(1+parseInt(Math.random()*4))+'.png';</script>
+ </div>
+
+ <ul class="standard">
+ <li>RTMP / Flash Media Server streaming support (experimental) - see <a href="doc/#smsound-serverurl" title="SMSound.serverURL parameter">serverURL</a> for details</li>
+ <li>MPEG-4 (AAC, HE-AAC, H.264) audio support</li>
+ <li>"MultiShot" play (layered/chorusing effects)</li>
+ <li>Waveform/frequency spectrum data</li>
+ <li>Peak (L/R channel volume) data</li>
+ <li>Audio buffering state/event handling</li>
+ </ul>
+
+ <h4>General Tech Stuff</h4>
+ <ul class="standard">
+ <li>Full <a href="doc/" title="SoundManager 2 documentation">API Documentation</a> with examples and notes</li>
+ <li>console.log()-style <a href="doc/technotes/#debug-output" title="SoundManager 2 debug output">debug output</a> and <a href="doc/getstarted/#troubleshooting" title="SoundManager 2 troubleshooting tool">troubleshooting tools</a></li>
+ <li>Community-based <a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2" title="discussion/support for SoundManager 2 on Get Satisfaction">discussion/support</a></li>
+ </ul>
+
+ <h4>As Heard On <span class="scratched-out">TV</span> The Internets</h4>
+ <p class="tight compact">A few nifty places SoundManager 2 has been seen in use on the Wild World Web:</p>
+ <div class="inthewild">
+ <a href="http://muxtape.com/" title="Muxtape"><img src="demo/_image/muxtape-logo.png" alt="Muxtape logo" /></a>
+ <a id="soundcloud" href="http://thecloudplayer.com/" title="Soundcloud / The Cloud Player"><span>SoundCloud / The Cloud Player</span></a>
+ <a href="http://8tracks.com/" title="8tracks" style="background:#fff"><img src="demo/_image/8tracks-logo.png" alt="8tracks logo" /></a>
+ <a id="lastfm" href="http://www.last.fm/" title="last.fm"><span>last.fm</span></a>
+ <a id="opera" href="http://www.opera.com/" title="Opera Software ASA (Media Player component)"><span>Opera Software ASA</span></a>
+ <a id="discogs" href="http://www.discogs.com/" title="Discogs"><img src="demo/_image/discogs.gif" alt="Discogs logo" /></a>
+ <a id="mixcrate" href="http://www.mixcrate.com/" title="Mixcrate"><span>Mixcrate</span></a>
+ </div>
+
+ <h4>Download!</h4>
+ <p style="margin-top:1.5em"><a href="doc/download/" class="feature">Get SoundManager 2</a></p>
+
+ </div>
+
+ <div class="clear"> </div>
+
+ <div class="columnar">
+
+ <div class="c1">
+ <h2>Playing MP3s with JavaScript</h2>
+ <p>Play audio in one line, or get fancy with multiple options.</p>
+ </div>
+
+ <div class="c2">
+ <h3>How To Play Audio Using SoundManager 2</h3>
+ <p>Simple ID / URL method:</p>
+ <code>soundManager.play('<span>mySound</span>','<span>/path/to/an.mp3</span>');</code>
+ <p>And, setting the volume:</p>
+ <code>soundManager.setVolume('<span>mySound</span>',<span>50</span>);</code>
+ <p>More flexible method supporting option parameters as an object literal:</p>
+<pre class="block"><code>var mySound = soundManager.createSound({
+ id: '<span>someSound</span>',
+ url: '<span>/path/to/some.mp3</span>',
+ volume: <span>50</span>,
+ onload: <span>soundLoadedFunction</span>
+});
+mySound.play();</code></pre>
+ <p><a href="demo/api/">See API Demos</a></p>
+ </div>
+
+ </div>
+
+ <div class="columnar">
+
+ <div class="c1">
+ <h2>Using SM2 on your site</h2>
+ <p>How to include SoundManager 2 from HTML, and some basic event handlers.</p>
+ </div>
+
+ <div class="c2">
+ <p>Include the SoundManager 2 core script, tell it where to look for the flash .SWF and provide an onload() handler.</p>
+<pre class="block"><code><script type="text/javascript" src="<span>/path/to/soundmanager2.js</span>"></script>
+<script type="text/javascript">
+soundManager.url = '<span>/path/to/swfs/</span>';
+soundManager.onload = function() {
+ <span>// SM2 is ready to go!</span>
+ <span>// soundManager.createSound(...) calls can now be made, etc.</span>
+}
+</script></code></pre>
+
+ <p><a href="demo/template/">See a basic template demo</a></p>
+
+ </div>
+
+ </div>
+
+ <div id="licensing" class="columnar">
+
+ <div class="c1">
+ <h2>Licensing</h2>
+ <p>BSD licensed.</p>
+ </div>
+
+ <div class="c2">
+ <p>SoundManager 2 is provided under a <a href="license.txt" title="SoundManager 2 BSD license" class="norewrite">BSD license</a>.</p>
+ </div>
+
+ </div>
+
+ <!-- columnar -->
+ </div>
+
+ <div class="clear"></div>
+
+ <div id="col3" class="c3">
+
+ <div id="get-satisfaction" class="box">
+ <div id="gsfn_list_widget">
+ <h2><a href="http://getsatisfaction.com/schillmania/products/schillmania_soundmanager_2/" title="User discussion, FAQs and support for SoundManager 2" rel="nofollow">Discussion / Support</a><span class="l"></span><span class="r"></span></h2>
+ <div id="gsfn_content"></div>
+ <div class="powered_by"><a href="http://getsatisfaction.com/">Get Satisfaction support network</a></div>
+ </div>
+ <!-- /.box -->
+
+ </div>
+
+
+ <!-- /main -->
+ </div>
+
+ <!-- /content -->
+ </div>
+
+ <div id="control-template">
+ <!-- control markup inserted dynamically after each link -->
+ <div class="controls">
+ <div class="statusbar">
+ <div class="loading"></div>
+ <div class="position"></div>
+ </div>
+ </div>
+ <div class="timing">
+ <div id="sm2_timing" class="timing-data">
+ <span class="sm2_position">%s1</span> / <span class="sm2_total">%s2</span></div>
+ </div>
+ <div class="peak">
+ <div class="peak-box"><span class="l"></span><span class="r"></span>
+ </div>
+ </div>
+ </div>
+
+ <div id="spectrum-container" class="spectrum-container">
+ <div class="spectrum-box">
+ <div class="spectrum"></div>
+ </div>
+ </div>
+
+<script type="text/javascript">
+init();
+</script>
+
+</div>
+
+</body>
+
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/license.txt b/docs/dymaxion/soundmanagerv297a-20101010/license.txt new file mode 100755 index 0000000..1a17182 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/license.txt @@ -0,0 +1,29 @@ +Software License Agreement (BSD License)
+
+Copyright (c) 2007, Scott Schiller (schillmania.com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+* Neither the name of schillmania.com nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission from schillmania.com.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-jsmin.js b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-jsmin.js new file mode 100755 index 0000000..91c77ed --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-jsmin.js @@ -0,0 +1,96 @@ +/** @license + + SoundManager 2: Javascript Sound for the Web + -------------------------------------------- + http://schillmania.com/projects/soundmanager2/ + + Copyright (c) 2007, Scott Schiller. All rights reserved. + Code provided under the BSD License: + http://schillmania.com/projects/soundmanager2/license.txt + + V2.97a.20101010 +*/ +(function(W){function va(Ma,Na){function wa(){if(b.debugURLParam.test(G))b.debugMode=true;if(u(b.debugID))return false;var c,a,f,g;if(b.debugMode&&!u(b.debugID)&&(!fa||!b.useConsole||b.useConsole&&fa&&!b.consoleOnly)){c=l.createElement("div");c.id=b.debugID+"-toggle";a={position:"fixed",bottom:"0px",right:"0px",width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001};c.appendChild(l.createTextNode("-")); +c.onclick=xa;c.title="Toggle SM2 debug console";if(v.match(/msie 6/i)){c.style.position="absolute";c.style.cursor="hand"}for(g in a)if(a.hasOwnProperty(g))c.style[g]=a[g];a=l.createElement("div");a.id=b.debugID;a.style.display=b.debugMode?"block":"none";if(b.debugMode&&!u(c.id)){try{f=X();f.appendChild(c)}catch(e){throw Error(q("appXHTML"));}f.appendChild(a)}}}this.flashVersion=8;this.debugMode=true;this.debugFlash=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.nullURL= +"about:blank";this.allowPolling=true;this.useFastPolling=false;this.useMovieStar=true;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useHTML5Audio=this.useFlashBlock=false;this.html5Test=/^probably$/i;this.ondebuglog=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"', +"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:true},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,onbeforefinish:null,onbeforefinishtime:5E3,onbeforefinishcomplete:null, +onjustbeforefinish:null,onjustbeforefinishtime:200,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null,onstats:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,bufferTimes:null,duration:null};this.version=null;this.versionNumber="V2.97a.20101010";this.movieURL=null;this.url=Ma||null;this.altURL=null; +this.enabled=this.swfLoaded=false;this.o=null;this.movieID="sm2-container";this.id=Na||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.oMC=null;this.sounds={};this.soundIDs=[];this.muted=false;this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.didFlashBlock=this.specialWmodeCase=false;this.filePattern= +null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.baseMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamTypes=["aac","flv","mov","mp4","m4v","f4v","m4a","mp4v","3gp","3g2"];this.netStreamPattern=RegExp("\\.("+this.netStreamTypes.join("|")+")(\\?.*)?$","i");this.mimePattern=this.baseMimeTypes;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.hasHTML5=null;this.html5={usingFlash:null};this.ignoreFlash=false;var ga,b=this,u,v=navigator.userAgent,G=W.location.href.toString(),p=this.flashVersion,l=document,o=W,ya,Y,H=[],ha=true,x,I= +false,P=false,s=false,z=false,ia=false,n,Oa=0,Q,w,za,J,K,ja,Z,Aa,ka,F,Ba,$,R,L,la,X,aa,ma,na,Ca,Pa=["log","info","warn","error"],Da,S,Ea,T=null,oa=null,q,pa,M,xa,ba,ca,qa,r,da=false,ra=false,Fa,Ga,N=null,Ha,ea,C=false,U,D,sa,Ia,E,A,ta=Array.prototype.slice,Ja=v.match(/pre\//i),Qa=v.match(/(ipad|iphone)/i);v.match(/mobile/i);var B=v.match(/MSIE/i),V=v.match(/safari/i)&&!v.match(/chrome/i),fa=typeof console!=="undefined"&&typeof console.log!=="undefined",ua=typeof l.hasFocus!=="undefined"?l.hasFocus(): +null,O=typeof l.hasFocus==="undefined"&&V,Ka=!O;this._use_maybe=G.match(/sm2\-useHTML5Maybe\=1/i);this._overHTTP=l.location?l.location.protocol.match(/http/i):null;this.useAltURL=!this._overHTTP;if(Qa||Ja){b.useHTML5Audio=true;b.ignoreFlash=true}if(Ja||this._use_maybe)b.html5Test=/^(probably|maybe)$/i;(function(){var c=G,a=null;if(c.indexOf("#sm2-usehtml5audio=")!==-1){a=c.substr(c.indexOf("#sm2-usehtml5audio=")+19)==="1";if(typeof console!=="undefined"&&typeof console.log!=="undefined")console.log((a? +"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter");b.useHTML5Audio=a}})();this.supported=function(){return N?s&&!z:b.useHTML5Audio&&b.hasHTML5};this.getMovie=function(c){return B?o[c]:V?u(c)||l[c]:u(c)};this.loadFromXML=function(c){try{b.o._loadFromXML(c)}catch(a){S()}return true};this.createSound=function(c){function a(){f=ba(f);b.sounds[e.id]=new ga(e);b.soundIDs.push(e.id);return b.sounds[e.id]}var f=null,g=null,e=null;if(!s||!b.supported()){qa("soundManager.createSound(): "+q(!s?"notReady": +"notOK"));return false}if(arguments.length===2)c={id:arguments[0],url:arguments[1]};e=f=w(c);e.id.toString().charAt(0).match(/^[0-9]$/)&&b._wD("soundManager.createSound(): "+q("badID",e.id),2);b._wD("soundManager.createSound(): "+e.id+" ("+e.url+")",1);if(r(e.id,true)){b._wD("soundManager.createSound(): "+e.id+" exists",1);return b.sounds[e.id]}if(ea(e)){g=a();b._wD("Loading sound "+e.id+" from HTML5");g._setup_html5(e)}else{if(p>8&&b.useMovieStar){if(e.isMovieStar===null)e.isMovieStar=e.serverURL|| +(e.type?e.type.match(b.netStreamPattern):false)||e.url.match(b.netStreamPattern)?true:false;e.isMovieStar&&b._wD("soundManager.createSound(): using MovieStar handling");if(e.isMovieStar){if(e.usePeakData){n("noPeak");e.usePeakData=false}e.loops>1&&n("noNSLoop")}}e=ca(e,"soundManager.createSound(): ");g=a();if(p===8)b.o._createSound(e.id,e.onjustbeforefinishtime,e.loops||1,e.usePolicyFile);else{b.o._createSound(e.id,e.url,e.onjustbeforefinishtime,e.usePeakData,e.useWaveformData,e.useEQData,e.isMovieStar, +e.isMovieStar?e.bufferTime:false,e.loops||1,e.serverURL,e.duration||null,e.autoPlay,true,e.bufferTimes,e.onstats?true:false,e.autoLoad,e.usePolicyFile);if(!e.serverURL){g.connected=true;e.onconnect&&e.onconnect.apply(g)}}}if(e.autoLoad||e.autoPlay)if(g)if(b.isHTML5){g.autobuffer="auto";g.preload="auto"}else g.load(e);e.autoPlay&&g.play();return g};this.destroySound=function(c,a){if(!r(c))return false;var f=b.sounds[c],g;f._iO={};f.stop();f.unload();for(g=0;g<b.soundIDs.length;g++)if(b.soundIDs[g]=== +c){b.soundIDs.splice(g,1);break}a||f.destruct(true);delete b.sounds[c];return true};this.load=function(c,a){if(!r(c))return false;return b.sounds[c].load(a)};this.unload=function(c){if(!r(c))return false;return b.sounds[c].unload()};this.start=this.play=function(c,a){if(!s||!b.supported()){qa("soundManager.play(): "+q(!s?"notReady":"notOK"));return false}if(!r(c)){a instanceof Object||(a={url:a});if(a&&a.url){b._wD('soundManager.play(): attempting to create "'+c+'"',1);a.id=c;return b.createSound(a).play()}else return false}return b.sounds[c].play(a)}; +this.setPosition=function(c,a){if(!r(c))return false;return b.sounds[c].setPosition(a)};this.stop=function(c){if(!r(c))return false;b._wD("soundManager.stop("+c+")",1);return b.sounds[c].stop()};this.stopAll=function(){b._wD("soundManager.stopAll()",1);for(var c in b.sounds)b.sounds[c]instanceof ga&&b.sounds[c].stop()};this.pause=function(c){if(!r(c))return false;return b.sounds[c].pause()};this.pauseAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].pause()};this.resume=function(c){if(!r(c))return false; +return b.sounds[c].resume()};this.resumeAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].resume()};this.togglePause=function(c){if(!r(c))return false;return b.sounds[c].togglePause()};this.setPan=function(c,a){if(!r(c))return false;return b.sounds[c].setPan(a)};this.setVolume=function(c,a){if(!r(c))return false;return b.sounds[c].setVolume(a)};this.mute=function(c){var a=0;if(typeof c!=="string")c=null;if(c){if(!r(c))return false;b._wD('soundManager.mute(): Muting "'+c+'"'); +return b.sounds[c].mute()}else{b._wD("soundManager.mute(): Muting all sounds");for(a=b.soundIDs.length;a--;)b.sounds[b.soundIDs[a]].mute();b.muted=true}return true};this.muteAll=function(){b.mute()};this.unmute=function(c){if(typeof c!=="string")c=null;if(c){if(!r(c))return false;b._wD('soundManager.unmute(): Unmuting "'+c+'"');return b.sounds[c].unmute()}else{b._wD("soundManager.unmute(): Unmuting all sounds");for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].unmute();b.muted=false}return true}; +this.unmuteAll=function(){b.unmute()};this.toggleMute=function(c){if(!r(c))return false;return b.sounds[c].toggleMute()};this.getMemoryUse=function(){if(p===8)return 0;if(b.o)return parseInt(b.o._getMemoryUse(),10)};this.disable=function(c){if(typeof c==="undefined")c=false;if(z)return false;z=true;n("shutdown",1);for(var a=b.soundIDs.length;a--;)Da(b.sounds[b.soundIDs[a]]);Q(c);A(o,"load",K);return true};this.canPlayMIME=function(c){var a;if(b.hasHTML5)a=U({type:c});return!N||a?a:c?c.match(b.mimePattern)? +true:false:null};this.canPlayURL=function(c){var a;if(b.hasHTML5)a=U(c);return!N||a?a:c?c.match(b.filePattern)?true:false:null};this.canPlayLink=function(c){if(typeof c.type!=="undefined"&&c.type)if(b.canPlayMIME(c.type))return true;return b.canPlayURL(c.href)};this.getSoundById=function(c,a){if(!c)throw Error("SoundManager.getSoundById(): sID is null/undefined");var f=b.sounds[c];!f&&!a&&b._wD('"'+c+'" is an invalid sound ID.',2);return f};this.onready=function(c,a){if(c&&c instanceof Function){s&& +n("queue");a||(a=o);za(c,a);J();return true}else throw q("needFunction");};this.getMoviePercent=function(){return b.o&&typeof b.o.PercentLoaded!=="undefined"?b.o.PercentLoaded():null};this._wD=this._writeDebug=function(c,a,f){b.ondebuglog&&b.ondebuglog(c,a,f);var g,e;if(!b.debugMode)return false;if(typeof f!=="undefined"&&f)c=c+" | "+(new Date).getTime();if(fa&&b.useConsole){f=Pa[a];typeof console[f]!=="undefined"?console[f](c):console.log(c);if(b.useConsoleOnly)return true}try{g=u("soundmanager-debug"); +if(!g)return false;e=l.createElement("div");if(++Oa%2===0)e.className="sm2-alt";a=typeof a==="undefined"?0:parseInt(a,10);e.appendChild(l.createTextNode(c));if(a){if(a>=2)e.style.fontWeight="bold";if(a===3)e.style.color="#ff3333"}g.insertBefore(e,g.firstChild)}catch(k){}return true};this._debug=function(){n("currentObj",1);for(var c=0,a=b.soundIDs.length;c<a;c++)b.sounds[b.soundIDs[c]]._debug()};this.reboot=function(){b._wD("soundManager.reboot()");b.soundIDs.length&&b._wD("Destroying "+b.soundIDs.length+ +" SMSound objects...");for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].destruct();try{if(B)oa=b.o.innerHTML;T=b.o.parentNode.removeChild(b.o);b._wD("Flash movie removed.")}catch(a){n("badRemove",2)}oa=T=null;b.enabled=s=da=ra=I=P=z=b.swfLoaded=false;b.soundIDs=b.sounds=[];b.o=null;for(c=H.length;c--;)H[c].fired=false;b._wD("soundManager: Rebooting...");o.setTimeout(function(){b.beginDelayedInit()},20)};this.destruct=function(){b._wD("soundManager.destruct()");b.disable(true)};this.beginDelayedInit= +function(){ia=true;L();setTimeout(Ba,20);Z()};ga=function(c){var a=this,f,g,e,k,m,i;this.sID=c.id;this.url=c.url;this._iO=this.instanceOptions=this.options=w(c);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this.id3={};this._debug=function(){if(b.debugMode){var d=null,h=[],j,t;for(d in a.options)if(a.options[d]!==null)if(a.options[d]instanceof Function){j=a.options[d].toString();j=j.replace(/\s\s+/g," ");t=j.indexOf("{");h.push(" "+d+": {"+j.substr(t+ +1,Math.min(Math.max(j.indexOf("\n")-1,64),64)).replace(/\n/g,"")+"... }")}else h.push(" "+d+": "+a.options[d]);b._wD("SMSound() merged options: {\n"+h.join(", \n")+"\n}")}};this._debug();this.load=function(d){var h=null;if(typeof d!=="undefined"){a._iO=w(d);a.instanceOptions=a._iO}else{d=a.options;a._iO=d;a.instanceOptions=a._iO;if(a._lastURL&&a._lastURL!==a.url){n("manURL");a._iO.url=a.url;a.url=null}}b._wD("soundManager.load(): "+a._iO.url,1);if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!== +2){n("onURL",1);return a}a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(ea(a._iO)){b._wD("HTML 5 load: "+a._iO.url);h=a._setup_html5(a._iO);h.load();a._iO.autoPlay&&a.play()}else try{a.isHTML5=false;a._iO=ca(ba(a._iO));p===8?b.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,a._iO.usePolicyFile):b.o._load(a.sID,a._iO.url,a._iO.stream?true:false,a._iO.autoPlay?true:false,a._iO.loops||1,a._iO.autoLoad?true:false,a._iO.usePolicyFile)}catch(j){n("smError", +2);x("onload",false);ma()}return a};this.unload=function(){if(a.readyState!==0){b._wD('SMSound.unload(): "'+a.sID+'"');if(a.isHTML5){e();if(i){i.pause();i.src=b.nullURL;i.load();i=a._audio=null}}else p===8?b.o._unload(a.sID,b.nullURL):b.o._unload(a.sID);f()}return a};this.destruct=function(d){b._wD('SMSound.destruct(): "'+a.sID+'"');if(a.isHTML5){e();if(i){i.pause();i.src="about:blank";i.load();i=a._audio=null}}else{a._iO.onfailure=null;b.o._destroySound(a.sID)}d||b.destroySound(a.sID,true)};this.start= +this.play=function(d,h){var j;h=typeof h==="undefined"?true:h;d||(d={});a._iO=w(d,a._iO);a._iO=w(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL)if(!a.connected){if(!a.getAutoPlay()){b._wD("SMSound.play(): Netstream not connected yet - setting autoPlay");a.setAutoPlay(true)}return a}if(ea(a._iO)){a._setup_html5(a._iO);k()}if(a.playState===1&&!a.paused)if(j=a._iO.multiShot){b._wD('SMSound.play(): "'+a.sID+'" already playing (multi-shot)',1);a.isHTML5&&a.setPosition(a._iO.position)}else{b._wD('SMSound.play(): "'+ +a.sID+'" already playing (one-shot)',1);return a}if(a.loaded)b._wD('SMSound.play(): "'+a.sID+'"');else if(a.readyState===0){b._wD('SMSound.play(): Attempting to load "'+a.sID+'"',1);if(a.isHTML5){a.load(a._iO);a.readyState=1}else if(!a._iO.serverURL){a._iO.autoPlay=true;a.load(a._iO)}}else if(a.readyState===2){b._wD('SMSound.play(): Could not load "'+a.sID+'" - exiting',2);return a}else b._wD('SMSound.play(): "'+a.sID+'" is loading - attempting to play..',1);if(a.paused&&a.position&&a.position>0){b._wD('SMSound.play(): "'+ +a.sID+'" is resuming from paused state',1);a.resume()}else{b._wD('SMSound.play(): "'+a.sID+'" is starting to play');a.playState=1;a.paused=false;if(!a.instanceCount||a._iO.multiShotEvents||p>8&&!a.isHTML5&&!a.getAutoPlay())a.instanceCount++;a.position=typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;a._iO=ca(ba(a._iO));a._iO.onplay&&h&&a._iO.onplay.apply(a);a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);if(a.isHTML5){k();a._setup_html5().play()}else b.o._start(a.sID, +a._iO.loops||1,p===9?a.position:a.position/1E3)}return a};this.stop=function(d){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);if(!a.isHTML5)a.playState=0;a.paused=false;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(i){a.setPosition(0);i.pause();a.playState=0;a._onTimer();e();a.unload()}}else{b.o._stop(a.sID,d);a._iO.serverURL&&a.unload()}a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(d){b._wD("sound "+a.sID+" turned autoplay "+(d?"on":"off"));a._iO.autoPlay= +d;b.o._setAutoPlay(a.sID,d);if(d)if(!a.instanceCount&&a.readyState===1){a.instanceCount++;b._wD("sound "+a.sID+" incremented instance count to "+a.instanceCount)}};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(d){if(d===undefined)d=0;a.position=a.isHTML5?Math.max(d,0):Math.min(a.duration||a._iO.duration,Math.max(d,0));a.resetOnPosition(a.position);if(a.isHTML5){if(i){b._wD("setPosition(): setting position to "+a.position/1E3);if(a.playState)try{i.currentTime=a.position/ +1E3}catch(h){b._wD("setPosition("+a.position+"): WARN: Caught exception: "+h.message,2)}else b._wD("HTML 5 warning: cannot set position while playState == 0 (not playing)",2);if(a.paused){a._onTimer(true);a._iO.useMovieStar&&a.resume()}}}else{d=p===9?a.position:a.position/1E3;a.playState===0?a.play({position:d}):b.o._setPosition(a.sID,d,a.paused||!a.playState)}return a};this.pause=function(d){if(a.paused||a.playState===0&&a.readyState!==1)return a;b._wD("SMSound.pause()");a.paused=true;if(a.isHTML5){a._setup_html5().pause(); +e()}else if(d||d===undefined)b.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;b._wD("SMSound.resume()");a.paused=false;a.playState=1;if(a.isHTML5){a._setup_html5().play();k()}else b.o._pause(a.sID);a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){b._wD("SMSound.togglePause()");if(a.playState===0){a.play({position:p===9&&!a.isHTML5?a.position:a.position/1E3});return a}a.paused?a.resume():a.pause();return a}; +this.setPan=function(d,h){if(typeof d==="undefined")d=0;if(typeof h==="undefined")h=false;a.isHTML5||b.o._setPan(a.sID,d);a._iO.pan=d;if(!h)a.pan=d;return a};this.setVolume=function(d,h){if(typeof d==="undefined")d=100;if(typeof h==="undefined")h=false;if(a.isHTML5){if(i)i.volume=d/100}else b.o._setVolume(a.sID,b.muted&&!a.muted||a.muted?0:d);a._iO.volume=d;if(!h)a.volume=d;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(i)i.muted=true}else b.o._setVolume(a.sID,0);return a};this.unmute= +function(){a.muted=false;var d=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(i)i.muted=false}else b.o._setVolume(a.sID,d?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(d,h,j){a._onPositionItems.push({position:d,method:h,scope:typeof j!=="undefined"?j:a,fired:false});return a};this.processOnPosition=function(){var d,h;d=a._onPositionItems.length;if(!d||!a.playState||a._onPositionFired>=d)return false;for(d=d;d--;){h= +a._onPositionItems[d];if(!h.fired&&a.position>=h.position){h.method.apply(h.scope,[h.position]);h.fired=true;b._onPositionFired++}}return true};this.resetOnPosition=function(d){var h,j;h=a._onPositionItems.length;if(!h)return false;for(h=h;h--;){j=a._onPositionItems[h];if(j.fired&&d<=j.position){j.fired=false;b._onPositionFired--}}return true};this._onTimer=function(d){var h={};if(a._hasTimer||d)if(i&&(d||(a.playState>0||a.readyState===1)&&!a.paused)){a.duration=m();a.durationEstimate=a.duration; +d=i.currentTime?i.currentTime*1E3:0;a._whileplaying(d,h,h,h,h);return true}else{b._wD('_onTimer: Warn for "'+a.sID+'": '+(!i?"Could not find element. ":"")+(a.playState===0?"playState bad, 0?":"playState = "+a.playState+", OK"));return false}};m=function(){var d=i?i.duration*1E3:undefined;return d&&!isNaN(d)?d:null};k=function(){a.isHTML5&&Fa(a)};e=function(){a.isHTML5&&Ga(a)};f=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._added_events=null;i=a._audio=null;a.bytesLoaded= +null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.didBeforeFinish=false;a.didJustBeforeFinish=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=[];a.eqData.left=[];a.eqData.right=[]};f();this._setup_html5=function(d){d=w(a._iO,d);if(i){if(a.url!==d.url){b._wD("setting new URL on existing object: "+ +d.url);i.src=d.url}}else{b._wD("creating HTML 5 audio element with URL: "+d.url);a._audio=new Audio(d.url);i=a._audio;a.isHTML5=true;g()}i.loop=d.loops>1?"loop":"";return a._audio};g=function(){function d(h,j,t){return i?i.addEventListener(h,j,t||false):null}if(a._added_events)return false;a._added_events=true;d("load",function(){b._wD("HTML5::load: "+a.sID);if(i){a._onbufferchange(0);a._whileloading(a.bytesTotal,a.bytesTotal,m());a._onload(true)}},false);d("canplay",function(){b._wD("HTML5::canplay: "+ +a.sID);a._onbufferchange(0)},false);d("waiting",function(){b._wD("HTML5::waiting: "+a.sID);a._onbufferchange(1)},false);d("progress",function(h){b._wD("HTML5::progress: "+a.sID+": loaded/total: "+(h.loaded||0)+"/"+(h.total||1));if(!a.loaded&&i){a._onbufferchange(0);a._whileloading(h.loaded||0,h.total||1,m())}},false);d("error",function(){if(i){b._wD("HTML5::error: "+i.error.code);a._onload(false)}},false);d("loadstart",function(){b._wD("HTML5::loadstart: "+a.sID);a._onbufferchange(1)},false);d("play", +function(){b._wD("HTML5::play: "+a.sID);a._onbufferchange(0)},false);d("playing",function(){b._wD("HTML5::playing: "+a.sID);a._onbufferchange(0)},false);d("timeupdate",function(){a._onTimer()},false);setTimeout(function(){a&&i&&d("ended",function(){b._wD("HTML5::ended: "+a.sID);a._onfinish()},false)},250);return true};this._whileloading=function(d,h,j,t){a.bytesLoaded=d;a.bytesTotal=h;a.duration=Math.floor(j);a.bufferLength=t;if(a._iO.isMovieStar)a.durationEstimate=a.duration;else{a.durationEstimate= +a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10);if(a.durationEstimate===undefined)a.durationEstimate=a.duration;a.bufferLength=t}a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._onid3=function(d,h){b._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.');var j=[],t,y;t=0;for(y=d.length;t<y;t++)j[d[t]]=h[t];a.id3=w(a.id3,j);a._iO.onid3&&a._iO.onid3.apply(a)};this._whileplaying=function(d,h,j,t,y){if(isNaN(d)|| +d===null)return false;if(a.playState===0&&d>0)d=0;a.position=d;a.processOnPosition();if(p>8&&!a.isHTML5){if(a._iO.usePeakData&&typeof h!=="undefined"&&h)a.peakData={left:h.leftPeak,right:h.rightPeak};if(a._iO.useWaveformData&&typeof j!=="undefined"&&j)a.waveformData={left:j.split(","),right:t.split(",")};if(a._iO.useEQData)if(typeof y!=="undefined"&&y&&y.leftEQ){d=y.leftEQ.split(",");a.eqData=d;a.eqData.left=d;if(typeof y.rightEQ!=="undefined"&&y.rightEQ)a.eqData.right=y.rightEQ.split(",")}}if(a.playState=== +1){!a.isHTML5&&b.flashVersion===8&&!a.position&&a.isBuffering&&a._onbufferchange(0);a._iO.whileplaying&&a._iO.whileplaying.apply(a);if((a.loaded||!a.loaded&&a._iO.isMovieStar)&&a._iO.onbeforefinish&&a._iO.onbeforefinishtime&&!a.didBeforeFinish&&a.duration-a.position<=a._iO.onbeforefinishtime)a._onbeforefinish()}return true};this._onconnect=function(d){d=d===1;b._wD('SMSound._onconnect(): "'+a.sID+'"'+(d?" connected.":" failed to connect? - "+a.url),d?1:2);if(a.connected=d){a.failures=0;a._iO.onconnect&& +a._iO.onconnect.apply(a,[d]);if(r(a.sID)&&(a.options.autoLoad||a.getAutoPlay()))a.play(undefined,a.getAutoPlay())}};this._onload=function(d){d=d?true:false;b._wD('SMSound._onload(): "'+a.sID+'"'+(d?" loaded.":" failed to load? - "+a.url),d?1:2);if(!d&&!a.isHTML5){b.sandbox.noRemote===true&&b._wD("SMSound._onload(): "+q("noNet"),1);b.sandbox.noLocal===true&&b._wD("SMSound._onload(): "+q("noLocal"),1)}a.loaded=d;a.readyState=d?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[d]);return true}; +this._onfailure=function(d,h,j){a.failures++;b._wD('SMSound._onfailure(): "'+a.sID+'" count '+a.failures);a._iO.onfailure&&a.failures===1?a._iO.onfailure(a,d,h,j):b._wD("SMSound._onfailure(): ignoring")};this._onbeforefinish=function(){if(!a.didBeforeFinish){a.didBeforeFinish=true;if(a._iO.onbeforefinish){b._wD('SMSound._onbeforefinish(): "'+a.sID+'"');a._iO.onbeforefinish.apply(a)}}};this._onjustbeforefinish=function(){if(!a.didJustBeforeFinish){a.didJustBeforeFinish=true;if(a._iO.onjustbeforefinish){b._wD('SMSound._onjustbeforefinish(): "'+ +a.sID+'"');a._iO.onjustbeforefinish.apply(a)}}};this._onstats=function(d){a._iO.onstats&&a._iO.onstats(a,d)};this._onfinish=function(){a._onbufferchange(0);a.resetOnPosition(0);a._iO.onbeforefinishcomplete&&a._iO.onbeforefinishcomplete.apply(a);a.didBeforeFinish=false;a.didJustBeforeFinish=false;if(a.instanceCount){a.instanceCount--;if(!a.instanceCount){a.playState=0;a.paused=false;a.instanceCount=0;a.instanceOptions={};e()}if(!a.instanceCount||a._iO.multiShotEvents)if(a._iO.onfinish){b._wD('SMSound._onfinish(): "'+ +a.sID+'"');a._iO.onfinish.apply(a)}}};this._onbufferchange=function(d){if(a.playState===0)return false;if(d&&a.isBuffering||!d&&!a.isBuffering)return false;a.isBuffering=d===1;if(a._iO.onbufferchange){b._wD("SMSound._onbufferchange(): "+d);a._iO.onbufferchange.apply(a)}return true};this._ondataerror=function(d){if(a.playState>0){b._wD("SMSound._ondataerror(): "+d);a._iO.ondataerror&&a._iO.ondataerror.apply(a)}}};X=function(){return l.body?l.body:l._docElement?l.documentElement:l.getElementsByTagName("div")[0]}; +u=function(c){return l.getElementById(c)};w=function(c,a){var f={},g,e;for(g in c)if(c.hasOwnProperty(g))f[g]=c[g];g=typeof a==="undefined"?b.defaultOptions:a;for(e in g)if(g.hasOwnProperty(e)&&typeof f[e]==="undefined")f[e]=g[e];return f};(function(){function c(e){e=ta.call(e);var k=e.length;if(f){e[1]="on"+e[1];k>3&&e.pop()}else k===3&&e.push(false);return e}function a(e,k){var m=e.shift()[g[k]];f?m(e[0],e[1]):m.apply(this,e)}var f=o.attachEvent,g={add:f?"attachEvent":"addEventListener",remove:f? +"detachEvent":"removeEventListener"};E=function(){a(c(arguments),"add")};A=function(){a(c(arguments),"remove")}})();ea=function(c){return(c.type?U({type:c.type}):false)||U(c.url)};U=function(c){if(!b.useHTML5Audio||!b.hasHTML5)return false;var a,f=b.audioFormats;if(!D){D=[];for(a in f)if(f.hasOwnProperty(a)){D.push(a);if(f[a].related)D=D.concat(f[a].related)}D=RegExp("\\.("+D.join("|")+")","i")}a=typeof c.type!=="undefined"?c.type:null;c=typeof c==="string"?c.toLowerCase().match(D):null;if(!c||!c.length){if(!a)return false}else c= +c[0].substr(1);if(c&&typeof b.html5[c]!=="undefined")return b.html5[c];else{if(!a)if(c&&b.html5[c])return b.html5[c];else a="audio/"+c;a=b.html5.canPlayType(a);return b.html5[c]=a}};Ia=function(){function c(m){var i,d,h=false;if(!a||typeof a.canPlayType!=="function")return false;if(m instanceof Array){i=0;for(d=m.length;i<d&&!h;i++)if(b.html5[m[i]]||a.canPlayType(m[i]).match(b.html5Test)){h=true;b.html5[m[i]]=true}return h}else return(m=a&&typeof a.canPlayType==="function"?a.canPlayType(m):false)&& +(m.match(b.html5Test)?true:false)}if(!b.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?new Audio:null,f,g={},e,k;e=b.audioFormats;for(f in e)if(e.hasOwnProperty(f)){g[f]=c(e[f].type);if(e[f]&&e[f].related)for(k=0;k<e[f].related.length;k++)b.html5[e[f].related[k]]=g[f]}g.canPlayType=a?c:null;b.html5=w(b.html5,g);return true};$={notReady:"Not loaded yet - wait for soundManager.onload()/onready()",notOK:"Audio support is not available.",appXHTML:"soundManager::createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.", +spcWmode:"soundManager::createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue",swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+l.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/", +waitFocus:"soundManager: Special case: Waiting for focus-related event..",waitImpatient:"soundManager: Getting impatient, still waiting for Flash%s...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",needFunction:"soundManager.onready(): Function object expected",badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',noMS:"MovieStar mode not enabled. Exiting.",currentObj:"--- soundManager._debug(): Current sound objects ---", +waitEI:"soundManager::initMovie(): Waiting for ExternalInterface call from Flash..",waitOnload:"soundManager: Waiting for window.onload()",docLoaded:"soundManager: Document already loaded",onload:"soundManager::initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",init:"-- soundManager::init() --",didInit:"soundManager::init(): Already called?",flashJS:"soundManager: Attempting to call Flash from JS..",noPolling:"soundManager: Polling (whileloading()/whileplaying() support) is disabled.", +secNote:"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",badRemove:"Warning: Failed to remove flash movie.",noPeak:"Warning: peakData features unsupported for movieStar formats",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager.onready(): Queueing handler",smFail:"soundManager: Failed to initialise.", +smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+b.swfCSS.swfTimedout+" CSS..",fbLoaded:"Flash loaded",fbHandler:"soundManager::flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:"soundManager.load(): current URL already assigned.",badFV:'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats", +needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",mfOn:"mobileFlash::enabling on-screen flash repositioning",policy:"Enabling usePolicyFile for data access"};u=function(c){return l.getElementById(c)};q=function(){var c=ta.call(arguments),a=c.shift();a=$&&$[a]?$[a]:"";var f,g;if(a&&c&&c.length){f=0;for(g=c.length;f<g;f++)a=a.replace("%s",c[f])}return a};ba=function(c){if(p===8&&c.loops>1&&c.stream){n("as2loop"); +c.stream=false}return c};ca=function(c,a){if(c&&!c.usePolicyFile&&(c.onid3||c.usePeakData||c.useWaveformData||c.useEQData)){b._wD((a?a+":":"")+q("policy"));c.usePolicyFile=true}return c};qa=function(c){typeof console!=="undefined"&&typeof console.warn!=="undefined"?console.warn(c):b._wD(c)};ya=function(){return false};Da=function(c){for(var a in c)if(c.hasOwnProperty(a)&&typeof c[a]==="function")c[a]=ya};S=function(c){if(typeof c==="undefined")c=false;if(z||c){n("smFail",2);b.disable(c)}};Ea=function(c){var a= +null;if(c)if(c.match(/\.swf(\?\.*)?$/i)){if(a=c.substr(c.toLowerCase().lastIndexOf(".swf?")+4))return c}else if(c.lastIndexOf("/")!==c.length-1)c+="/";return(c&&c.lastIndexOf("/")!==-1?c.substr(0,c.lastIndexOf("/")+1):"./")+b.movieURL};ka=function(){if(p!==8&&p!==9){b._wD(q("badFV",p,8));b.flashVersion=8}var c=b.debugMode||b.debugFlash?"_debug.swf":".swf";if(b.flashVersion<9&&b.useHTML5Audio&&b.audioFormats.mp4.required){b._wD(q("needfl9"));b.flashVersion=9}p=b.flashVersion;b.version=b.versionNumber+ +(C?" (HTML5-only mode)":p===9?" (AS3/Flash 9)":" (AS2/Flash 8)");if(p>8){b.defaultOptions=w(b.defaultOptions,b.flash9Options);b.features.buffering=true}if(p>8&&b.useMovieStar){b.defaultOptions=w(b.defaultOptions,b.movieStarOptions);b.filePatterns.flash9=RegExp("\\.(mp3|"+b.netStreamTypes.join("|")+")(\\?.*)?$","i");b.mimePattern=b.netStreamMimeTypes;b.features.movieStar=true}else b.features.movieStar=false;b.filePattern=b.filePatterns[p!==8?"flash9":"flash8"];b.movieURL=(p===8?"soundmanager2.swf": +"soundmanager2_flash9.swf").replace(".swf",c);b.features.peakData=b.features.waveformData=b.features.eqData=p>8};Ca=function(c,a){if(!b.o||!b.allowPolling)return false;b.o._setPolling(c,a)};(function(){function c(e){e=ta.call(e);var k=e.length;if(f){e[1]="on"+e[1];k>3&&e.pop()}else k===3&&e.push(false);return e}function a(e,k){var m=e.shift()[g[k]];f?m(e[0],e[1]):m.apply(this,e)}var f=o.attachEvent,g={add:f?"attachEvent":"addEventListener",remove:f?"detachEvent":"removeEventListener"};E=function(){a(c(arguments), +"add")};A=function(){a(c(arguments),"remove")}})();na=function(){function c(){f.left=o.scrollX+"px";f.top=o.scrollY+"px"}function a(g){b._wD("mobileFlash::flash on-screen hack: "+(g?"ON":"OFF"));g=o[(g?"add":"remove")+"EventListener"];g("resize",c,false);g("scroll",c,false)}var f=null;return{check:function(g){f=b.oMC.style;if(v.match(/android/i)){if(g){if(b.flashLoadTimeout){b._wDS("mfTimeout");b.flashLoadTimeout=0}return false}b._wD("mfOn");f.position="absolute";f.left=f.top="0px";a(true);b.onready(function(){a(false); +if(f)f.left=f.top="-9999px"});c()}return true}}}();aa=function(c,a){function f(){b._wD("-- SoundManager 2 "+b.version+(!C&&b.useHTML5Audio?b.hasHTML5?" + HTML5 audio":", no HTML5 audio support":"")+(b.useMovieStar?", MovieStar mode":"")+(b.useHighPerformance?", high performance mode, ":", ")+((b.useFastPolling?"fast":"normal")+" polling")+(b.wmode?", wmode: "+b.wmode:"")+(b.debugFlash?", flash debug mode":"")+(b.useFlashBlock?", flashBlock mode":"")+" --",1)}var g=a?a:b.url,e=b.altURL?b.altURL:g, +k;k=X();var m,i,d=M(),h,j=null;j=(j=l.getElementsByTagName("html")[0])&&j.dir&&j.dir.match(/rtl/i);c=typeof c==="undefined"?b.id:c;if(I&&P)return false;if(C){ka();f();b.oMC=u(b.movieID);Y();P=I=true;return false}I=true;ka();b.url=Ea(this._overHTTP?g:e);a=b.url;b.wmode=!b.wmode&&b.useHighPerformance&&!b.useMovieStar?"transparent":b.wmode;if(b.wmode!==null&&!B&&!b.useHighPerformance&&navigator.platform.match(/win32/i)){b.specialWmodeCase=true;n("spcWmode");b.wmode=null}k={name:c,id:c,src:a,width:"100%", +height:"100%",quality:"high",allowScriptAccess:b.allowScriptAccess,bgcolor:b.bgColor,pluginspage:"http://www.macromedia.com/go/getflashplayer",type:"application/x-shockwave-flash",wmode:b.wmode};if(b.debugFlash)k.FlashVars="debug=1";b.wmode||delete k.wmode;if(B){g=l.createElement("div");i='<object id="'+c+'" data="'+a+'" type="'+k.type+'" width="'+k.width+'" height="'+k.height+'"><param name="movie" value="'+a+'" /><param name="AllowScriptAccess" value="'+b.allowScriptAccess+'" /><param name="quality" value="'+ +k.quality+'" />'+(b.wmode?'<param name="wmode" value="'+b.wmode+'" /> ':"")+'<param name="bgcolor" value="'+b.bgColor+'" />'+(b.debugFlash?'<param name="FlashVars" value="'+k.FlashVars+'" />':"")+"<!-- --\></object>"}else{g=l.createElement("embed");for(m in k)k.hasOwnProperty(m)&&g.setAttribute(m,k[m])}wa();d=M();if(k=X()){b.oMC=u(b.movieID)?u(b.movieID):l.createElement("div");if(b.oMC.id){h=b.oMC.className;b.oMC.className=(h?h+" ":b.swfCSS.swfDefault)+(d?" "+d:"");b.oMC.appendChild(g);if(B){m=b.oMC.appendChild(l.createElement("div")); +m.className=b.swfCSS.swfBox;m.innerHTML=i}P=true;na.check(true)}else{b.oMC.id=b.movieID;b.oMC.className=b.swfCSS.swfDefault+" "+d;m=d=null;if(!b.useFlashBlock)if(b.useHighPerformance)d={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else{d={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"};if(j)d.left=Math.abs(parseInt(d.left,10))+"px"}if(v.match(/webkit/i))b.oMC.style.zIndex=1E4;if(!b.debugFlash)for(h in d)if(d.hasOwnProperty(h))b.oMC.style[h]= +d[h];try{B||b.oMC.appendChild(g);k.appendChild(b.oMC);if(B){m=b.oMC.appendChild(l.createElement("div"));m.className=b.swfCSS.swfBox;m.innerHTML=i}P=true}catch(t){throw Error(q("appXHTML"));}na.check()}}f();b._wD("soundManager::createMovie(): Trying to load "+a+(!this._overHTTP&&b.altURL?" (alternate URL)":""),1);return true};r=this.getSoundById;R=function(){if(C){aa();return false}if(b.o)return false;b.o=b.getMovie(b.id);if(!b.o){if(T){if(B)b.oMC.innerHTML=oa;else b.oMC.appendChild(T);T=null;I=true}else aa(b.id, +b.url);b.o=b.getMovie(b.id)}if(b.o){b._wD("soundManager::initMovie(): Got "+b.o.nodeName+" element ("+(I?"created via JS":"static HTML")+")");n("waitEI")}b.oninitmovie instanceof Function&&setTimeout(b.oninitmovie,1);return true};ja=function(c){if(c)b.url=c;R()};Z=function(){setTimeout(Aa,500)};Aa=function(){if(da)return false;da=true;A(o,"load",Z);if(O&&!ua){n("waitFocus");return false}var c;if(!s){c=b.getMoviePercent();b._wD(q("waitImpatient",c===100?" (SWF loaded)":c>0?" (SWF "+c+"% loaded)":""))}setTimeout(function(){c= +b.getMoviePercent();if(!s){b._wD("soundManager: No Flash response within expected time.\nLikely causes: "+(c===0?"Loading "+b.movieURL+" may have failed (and/or Flash "+p+"+ not present?), ":"")+"Flash blocked or JS-Flash security error."+(b.debugFlash?" "+q("checkSWF"):""),2);if(!this._overHTTP&&c){n("localFail",2);b.debugFlash||n("tryDebug",2)}c===0&&b._wD(q("swf404",b.url));x("flashtojs",false,": Timed out"+this._overHTTP?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)")}if(!s&& +Ka)if(c===null)if(b.useFlashBlock||b.flashLoadTimeout===0){b.useFlashBlock&&pa();n("waitForever")}else S(true);else b.flashLoadTimeout===0?n("waitForever"):S(true)},b.flashLoadTimeout)};ja=function(c){if(c)b.url=c;R()};n=function(c,a){return c?b._wD(q(c),a):""};if(G.indexOf("debug=alert")+1&&b.debugMode)b._wD=function(c){alert(c)};xa=function(){var c=u(b.debugID),a=u(b.debugID+"-toggle");if(!c)return false;if(ha){a.innerHTML="+";c.style.display="none"}else{a.innerHTML="-";c.style.display="block"}ha= +!ha};x=function(c,a,f){if(typeof sm2Debugger!=="undefined")try{sm2Debugger.handleEvent(c,a,f)}catch(g){}return true};M=function(){var c=[];b.debugMode&&c.push(b.swfCSS.sm2Debug);b.debugFlash&&c.push(b.swfCSS.flashDebug);b.useHighPerformance&&c.push(b.swfCSS.highPerf);return c.join(" ")};pa=function(){var c=q("fbHandler"),a=b.getMoviePercent();if(b.supported()){b.didFlashBlock&&b._wD(c+": Unblocked");if(b.oMC)b.oMC.className=M()+" "+b.swfCSS.swfDefault+(" "+b.swfCSS.swfUnblocked)}else{if(N){b.oMC.className= +M()+" "+b.swfCSS.swfDefault+" "+(a===null?b.swfCSS.swfTimedout:b.swfCSS.swfError);b._wD(c+": "+q("fbTimeout")+(a?" ("+q("fbLoaded")+")":""))}b.didFlashBlock=true;J(true);b.onerror instanceof Function&&b.onerror.apply(o)}};F=function(){function c(){A(o,"focus",F);A(o,"load",F)}if(ua||!O){c();return true}ua=Ka=true;b._wD("soundManager::handleFocus()");V&&O&&A(o,"mousemove",F);da=false;c();return true};Q=function(c){if(s)return false;if(C){b._wD("-- SoundManager 2: loaded --");s=true;J();K();return true}b.useFlashBlock&& +b.flashLoadTimeout&&!b.getMoviePercent()||(s=true);b._wD("-- SoundManager 2 "+(z?"failed to load":"loaded")+" ("+(z?"security/load error":"OK")+") --",1);if(z||c){if(b.useFlashBlock)b.oMC.className=M()+" "+(b.getMoviePercent()===null?b.swfCSS.swfTimedout:b.swfCSS.swfError);J();x("onload",false);b.onerror instanceof Function&&b.onerror.apply(o);return false}else x("onload",true);if(b.waitForWindowLoad&&!ia){n("waitOnload");E(o,"load",K);return false}else{b.waitForWindowLoad&&ia&&n("docLoaded");K()}return true}; +za=function(c,a){H.push({method:c,scope:a||null,fired:false})};J=function(c){if(!s&&!c)return false;c={success:c?b.supported():!z};var a=[],f,g,e=!b.useFlashBlock||b.useFlashBlock&&!b.supported();f=0;for(g=H.length;f<g;f++)H[f].fired!==true&&a.push(H[f]);if(a.length){b._wD("soundManager: Firing "+a.length+" onready() item"+(a.length>1?"s":""));f=0;for(g=a.length;f<g;f++){a[f].scope?a[f].method.apply(a[f].scope,[c]):a[f].method(c);if(!e)a[f].fired=true}}return true};K=function(){o.setTimeout(function(){b.useFlashBlock&& +pa();J();n("onload",1);b.onload instanceof Function&&b.onload.apply(o);n("onloadOK",1);b.waitForWindowLoad&&E(o,"load",K)},1)};Ha=function(){var c,a,f=!G.match(/usehtml5audio/i)&&!G.match(/sm2\-ignorebadua/i)&&V&&v.match(/OS X 10_6_(3|4)/i);if(v.match(/iphone os (1|2|3_0|3_1)/i)?true:false){b.hasHTML5=false;C=true;if(b.oMC)b.oMC.style.display="none";return false}if(b.useHTML5Audio){if(!b.html5||!b.html5.canPlayType){b._wD("SoundManager: No HTML5 Audio() support detected.");b.hasHTML5=false;return true}else b.hasHTML5= +true;if(f){b._wD("SoundManager::Note: Buggy HTML5 Audio in Safari on OS X 10.6.[3|4], see https://bugs.webkit.org/show_bug.cgi?id=32159 - disabling HTML5 audio",1);b.useHTML5Audio=false;b.hasHTML5=false;return true}}else return true;for(a in b.audioFormats)if(b.audioFormats.hasOwnProperty(a)&&b.audioFormats[a].required&&!b.html5.canPlayType(b.audioFormats[a].type))c=true;if(b.ignoreFlash)c=false;C=b.useHTML5Audio&&b.hasHTML5&&!c;return c};Y=function(){var c,a=[];n("init");if(s){n("didInit");return false}if(b.hasHTML5){for(c in b.audioFormats)b.audioFormats.hasOwnProperty(c)&& +a.push(c+": "+b.html5[c]);b._wD("-- SoundManager 2: HTML5 support tests ("+b.html5Test+"): "+a.join(", ")+" --",1)}if(C){if(!s){A(o,"load",b.beginDelayedInit);b.enabled=true;Q()}return true}R();try{n("flashJS");b.o._externalInterfaceTest(false);b.allowPolling?Ca(true,b.useFastPolling?true:false):n("noPolling",1);b.debugMode||b.o._disableDebug();b.enabled=true;x("jstoflash",true)}catch(f){b._wD("js/flash exception: "+f.toString());x("jstoflash",false);S(true);Q();return false}Q();A(o,"load",b.beginDelayedInit); +return true};Ba=function(){if(ra)return false;aa();R();return ra=true};L=function(){if(la)return false;la=true;wa();Ia();b.html5.usingFlash=Ha();N=b.html5.usingFlash;la=true;l.removeEventListener&&l.removeEventListener("DOMContentLoaded",L,false);ja();return true};Fa=function(c){if(!c._hasTimer)c._hasTimer=true};Ga=function(c){if(c._hasTimer)c._hasTimer=false};ma=function(){b.onerror instanceof Function&&b.onerror();b.disable()};this._setSandboxType=function(c){var a=b.sandbox;a.type=c;a.description= +a.types[typeof a.types[c]!=="undefined"?c:"unknown"];b._wD("Flash security sandbox type: "+a.type);if(a.type==="localWithFile"){a.noRemote=true;a.noLocal=false;n("secNote",2)}else if(a.type==="localWithNetwork"){a.noRemote=false;a.noLocal=true}else if(a.type==="localTrusted"){a.noRemote=false;a.noLocal=false}};this._externalInterfaceOK=function(c){if(b.swfLoaded)return false;var a=(new Date).getTime();b._wD("soundManager::externalInterfaceOK()"+(c?" (~"+(a-c)+" ms)":""));x("swf",true);x("flashtojs", +true);b.swfLoaded=true;O=false;B?setTimeout(Y,100):Y()};sa=function(){if(l.readyState==="complete"){L();l.detachEvent("onreadystatechange",sa)}return true};if(!b.hasHTML5||N){E(o,"focus",F);E(o,"load",F);E(o,"load",Z);V&&O&&E(o,"mousemove",F)}if(l.addEventListener)l.addEventListener("DOMContentLoaded",L,false);else if(l.attachEvent)l.attachEvent("onreadystatechange",sa);else{x("onload",false);ma()}l.readyState==="complete"&&setTimeout(L,100)}var La=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)La= +new va;W.SoundManager=va;W.soundManager=La})(window); diff --git a/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug-jsmin.js b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug-jsmin.js new file mode 100755 index 0000000..fa3f21d --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug-jsmin.js @@ -0,0 +1,71 @@ +/** @license + + SoundManager 2: Javascript Sound for the Web + -------------------------------------------- + http://schillmania.com/projects/soundmanager2/ + + Copyright (c) 2007, Scott Schiller. All rights reserved. + Code provided under the BSD License: + http://schillmania.com/projects/soundmanager2/license.txt + + V2.97a.20101010 +*/ +(function(T){function oa(Ga,Ha){function pa(){if(b.debugURLParam.test(U))b.debugMode=true}this.flashVersion=8;this.debugFlash=this.debugMode=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.nullURL="about:blank";this.allowPolling=true;this.useFastPolling=false;this.useMovieStar=true;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useHTML5Audio=this.useFlashBlock=false;this.html5Test=/^probably$/i; +this.ondebuglog=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:true},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false, +loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,onbeforefinish:null,onbeforefinishtime:5E3,onbeforefinishcomplete:null,onjustbeforefinish:null,onjustbeforefinishtime:200,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null,onstats:null}; +this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,bufferTimes:null,duration:null};this.version=null;this.versionNumber="V2.97a.20101010";this.movieURL=null;this.url=Ga||null;this.altURL=null;this.enabled=this.swfLoaded=false;this.o=null;this.movieID="sm2-container";this.id=Ha||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"}; +this.oMC=null;this.sounds={};this.soundIDs=[];this.muted=false;this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.didFlashBlock=this.specialWmodeCase=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.baseMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamTypes=["aac","flv","mov","mp4","m4v","f4v","m4a","mp4v","3gp","3g2"];this.netStreamPattern= +RegExp("\\.("+this.netStreamTypes.join("|")+")(\\?.*)?$","i");this.mimePattern=this.baseMimeTypes;this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={};this.hasHTML5=null;this.html5={usingFlash:null};this.ignoreFlash=false;var ba,b=this,z,t=navigator.userAgent,U=T.location.href.toString(),o=this.flashVersion,k=document,l=T,qa,V,D=[],L=false,M=false,q=false,A=false,ra=false,N,s,sa,E,F,ca,W,ta,da,B,ua,O,G,ea,fa,X,ga,ha,va,wa,P,xa,Q=null,ia=null, +H,ja,I,Y,Z,ka,p,$=false,la=false,ya,za,J=null,Aa,aa,C=false,R,x,ma,Ba,y,v,Ca=Array.prototype.slice,Da=t.match(/pre\//i),Ia=t.match(/(ipad|iphone)/i);t.match(/mobile/i);var w=t.match(/MSIE/i),S=t.match(/safari/i)&&!t.match(/chrome/i),na=typeof k.hasFocus!=="undefined"?k.hasFocus():null,K=typeof k.hasFocus==="undefined"&&S,Ea=!K;this._use_maybe=U.match(/sm2\-useHTML5Maybe\=1/i);this._overHTTP=k.location?k.location.protocol.match(/http/i):null;this.useAltURL=!this._overHTTP;if(Ia||Da){b.useHTML5Audio= +true;b.ignoreFlash=true}if(Da||this._use_maybe)b.html5Test=/^(probably|maybe)$/i;this.supported=function(){return J?q&&!A:b.useHTML5Audio&&b.hasHTML5};this.getMovie=function(c){return w?l[c]:S?z(c)||k[c]:z(c)};this.loadFromXML=function(c){try{b.o._loadFromXML(c)}catch(a){P()}return true};this.createSound=function(c){function a(){f=Y(f);b.sounds[e.id]=new ba(e);b.soundIDs.push(e.id);return b.sounds[e.id]}var f=null,i=null,e=null;if(!q||!b.supported()){ka("soundManager.createSound(): "+H(!q?"notReady": +"notOK"));return false}if(arguments.length===2)c={id:arguments[0],url:arguments[1]};e=f=s(c);if(p(e.id,true))return b.sounds[e.id];if(aa(e)){i=a();i._setup_html5(e)}else{if(o>8&&b.useMovieStar){if(e.isMovieStar===null)e.isMovieStar=e.serverURL||(e.type?e.type.match(b.netStreamPattern):false)||e.url.match(b.netStreamPattern)?true:false;if(e.isMovieStar)if(e.usePeakData)e.usePeakData=false}e=Z(e,"soundManager.createSound(): ");i=a();if(o===8)b.o._createSound(e.id,e.onjustbeforefinishtime,e.loops||1, +e.usePolicyFile);else{b.o._createSound(e.id,e.url,e.onjustbeforefinishtime,e.usePeakData,e.useWaveformData,e.useEQData,e.isMovieStar,e.isMovieStar?e.bufferTime:false,e.loops||1,e.serverURL,e.duration||null,e.autoPlay,true,e.bufferTimes,e.onstats?true:false,e.autoLoad,e.usePolicyFile);if(!e.serverURL){i.connected=true;e.onconnect&&e.onconnect.apply(i)}}}if(e.autoLoad||e.autoPlay)if(i)if(b.isHTML5){i.autobuffer="auto";i.preload="auto"}else i.load(e);e.autoPlay&&i.play();return i};this.destroySound= +function(c,a){if(!p(c))return false;var f=b.sounds[c],i;f._iO={};f.stop();f.unload();for(i=0;i<b.soundIDs.length;i++)if(b.soundIDs[i]===c){b.soundIDs.splice(i,1);break}a||f.destruct(true);delete b.sounds[c];return true};this.load=function(c,a){if(!p(c))return false;return b.sounds[c].load(a)};this.unload=function(c){if(!p(c))return false;return b.sounds[c].unload()};this.start=this.play=function(c,a){if(!q||!b.supported()){ka("soundManager.play(): "+H(!q?"notReady":"notOK"));return false}if(!p(c)){a instanceof +Object||(a={url:a});if(a&&a.url){a.id=c;return b.createSound(a).play()}else return false}return b.sounds[c].play(a)};this.setPosition=function(c,a){if(!p(c))return false;return b.sounds[c].setPosition(a)};this.stop=function(c){if(!p(c))return false;return b.sounds[c].stop()};this.stopAll=function(){for(var c in b.sounds)b.sounds[c]instanceof ba&&b.sounds[c].stop()};this.pause=function(c){if(!p(c))return false;return b.sounds[c].pause()};this.pauseAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].pause()}; +this.resume=function(c){if(!p(c))return false;return b.sounds[c].resume()};this.resumeAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].resume()};this.togglePause=function(c){if(!p(c))return false;return b.sounds[c].togglePause()};this.setPan=function(c,a){if(!p(c))return false;return b.sounds[c].setPan(a)};this.setVolume=function(c,a){if(!p(c))return false;return b.sounds[c].setVolume(a)};this.mute=function(c){var a=0;if(typeof c!=="string")c=null;if(c){if(!p(c))return false; +return b.sounds[c].mute()}else{for(a=b.soundIDs.length;a--;)b.sounds[b.soundIDs[a]].mute();b.muted=true}return true};this.muteAll=function(){b.mute()};this.unmute=function(c){if(typeof c!=="string")c=null;if(c){if(!p(c))return false;return b.sounds[c].unmute()}else{for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].unmute();b.muted=false}return true};this.unmuteAll=function(){b.unmute()};this.toggleMute=function(c){if(!p(c))return false;return b.sounds[c].toggleMute()};this.getMemoryUse=function(){if(o=== +8)return 0;if(b.o)return parseInt(b.o._getMemoryUse(),10)};this.disable=function(c){if(typeof c==="undefined")c=false;if(A)return false;A=true;for(var a=b.soundIDs.length;a--;)wa(b.sounds[b.soundIDs[a]]);N(c);v(l,"load",F);return true};this.canPlayMIME=function(c){var a;if(b.hasHTML5)a=R({type:c});return!J||a?a:c?c.match(b.mimePattern)?true:false:null};this.canPlayURL=function(c){var a;if(b.hasHTML5)a=R(c);return!J||a?a:c?c.match(b.filePattern)?true:false:null};this.canPlayLink=function(c){if(typeof c.type!== +"undefined"&&c.type)if(b.canPlayMIME(c.type))return true;return b.canPlayURL(c.href)};this.getSoundById=function(c){if(!c)throw Error("SoundManager.getSoundById(): sID is null/undefined");return b.sounds[c]};this.onready=function(c,a){if(c&&c instanceof Function){a||(a=l);sa(c,a);E();return true}else throw H("needFunction");};this.getMoviePercent=function(){return b.o&&typeof b.o.PercentLoaded!=="undefined"?b.o.PercentLoaded():null};this._wD=this._writeDebug=function(c,a,f){b.ondebuglog&&b.ondebuglog(c, +a,f);return true};this._debug=function(){};this.reboot=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].destruct();try{if(w)ia=b.o.innerHTML;Q=b.o.parentNode.removeChild(b.o)}catch(a){}ia=Q=null;b.enabled=q=$=la=L=M=A=b.swfLoaded=false;b.soundIDs=b.sounds=[];b.o=null;for(c=D.length;c--;)D[c].fired=false;l.setTimeout(function(){b.beginDelayedInit()},20)};this.destruct=function(){b.disable(true)};this.beginDelayedInit=function(){ra=true;G();setTimeout(ua,20);W()};ba=function(c){var a= +this,f,i,e,j,n,h;this.sID=c.id;this.url=c.url;this._iO=this.instanceOptions=this.options=s(c);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this.id3={};this._debug=function(){};this._debug();this.load=function(d){var g=null;if(typeof d!=="undefined"){a._iO=s(d);a.instanceOptions=a._iO}else{d=a.options;a._iO=d;a.instanceOptions=a._iO;if(a._lastURL&&a._lastURL!==a.url){a._iO.url=a.url;a.url=null}}if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!== +2)return a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(aa(a._iO)){g=a._setup_html5(a._iO);g.load();a._iO.autoPlay&&a.play()}else try{a.isHTML5=false;a._iO=Z(Y(a._iO));o===8?b.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,a._iO.usePolicyFile):b.o._load(a.sID,a._iO.url,a._iO.stream?true:false,a._iO.autoPlay?true:false,a._iO.loops||1,a._iO.autoLoad?true:false,a._iO.usePolicyFile)}catch(m){ga()}return a};this.unload=function(){if(a.readyState!== +0){if(a.isHTML5){e();if(h){h.pause();h.src=b.nullURL;h.load();h=a._audio=null}}else o===8?b.o._unload(a.sID,b.nullURL):b.o._unload(a.sID);f()}return a};this.destruct=function(d){if(a.isHTML5){e();if(h){h.pause();h.src="about:blank";h.load();h=a._audio=null}}else{a._iO.onfailure=null;b.o._destroySound(a.sID)}d||b.destroySound(a.sID,true)};this.start=this.play=function(d,g){var m;g=typeof g==="undefined"?true:g;d||(d={});a._iO=s(d,a._iO);a._iO=s(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL)if(!a.connected){a.getAutoPlay()|| +a.setAutoPlay(true);return a}if(aa(a._iO)){a._setup_html5(a._iO);j()}if(a.playState===1&&!a.paused)if(m=a._iO.multiShot)a.isHTML5&&a.setPosition(a._iO.position);else return a;if(!a.loaded)if(a.readyState===0)if(a.isHTML5){a.load(a._iO);a.readyState=1}else{if(!a._iO.serverURL){a._iO.autoPlay=true;a.load(a._iO)}}else if(a.readyState===2)return a;if(a.paused&&a.position&&a.position>0)a.resume();else{a.playState=1;a.paused=false;if(!a.instanceCount||a._iO.multiShotEvents||o>8&&!a.isHTML5&&!a.getAutoPlay())a.instanceCount++; +a.position=typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;a._iO=Z(Y(a._iO));a._iO.onplay&&g&&a._iO.onplay.apply(a);a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);if(a.isHTML5){j();a._setup_html5().play()}else b.o._start(a.sID,a._iO.loops||1,o===9?a.position:a.position/1E3)}return a};this.stop=function(d){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);if(!a.isHTML5)a.playState=0;a.paused=false;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(h){a.setPosition(0); +h.pause();a.playState=0;a._onTimer();e();a.unload()}}else{b.o._stop(a.sID,d);a._iO.serverURL&&a.unload()}a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(d){a._iO.autoPlay=d;b.o._setAutoPlay(a.sID,d);d&&!a.instanceCount&&a.readyState===1&&a.instanceCount++};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(d){if(d===undefined)d=0;a.position=a.isHTML5?Math.max(d,0):Math.min(a.duration||a._iO.duration,Math.max(d,0));a.resetOnPosition(a.position);if(a.isHTML5){if(h){if(a.playState)try{h.currentTime= +a.position/1E3}catch(g){}if(a.paused){a._onTimer(true);a._iO.useMovieStar&&a.resume()}}}else{d=o===9?a.position:a.position/1E3;a.playState===0?a.play({position:d}):b.o._setPosition(a.sID,d,a.paused||!a.playState)}return a};this.pause=function(d){if(a.paused||a.playState===0&&a.readyState!==1)return a;a.paused=true;if(a.isHTML5){a._setup_html5().pause();e()}else if(d||d===undefined)b.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;a.paused= +false;a.playState=1;if(a.isHTML5){a._setup_html5().play();j()}else b.o._pause(a.sID);a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){if(a.playState===0){a.play({position:o===9&&!a.isHTML5?a.position:a.position/1E3});return a}a.paused?a.resume():a.pause();return a};this.setPan=function(d,g){if(typeof d==="undefined")d=0;if(typeof g==="undefined")g=false;a.isHTML5||b.o._setPan(a.sID,d);a._iO.pan=d;if(!g)a.pan=d;return a};this.setVolume=function(d,g){if(typeof d==="undefined")d= +100;if(typeof g==="undefined")g=false;if(a.isHTML5){if(h)h.volume=d/100}else b.o._setVolume(a.sID,b.muted&&!a.muted||a.muted?0:d);a._iO.volume=d;if(!g)a.volume=d;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(h)h.muted=true}else b.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var d=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(h)h.muted=false}else b.o._setVolume(a.sID,d?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute(): +a.mute()};this.onposition=function(d,g,m){a._onPositionItems.push({position:d,method:g,scope:typeof m!=="undefined"?m:a,fired:false});return a};this.processOnPosition=function(){var d,g;d=a._onPositionItems.length;if(!d||!a.playState||a._onPositionFired>=d)return false;for(d=d;d--;){g=a._onPositionItems[d];if(!g.fired&&a.position>=g.position){g.method.apply(g.scope,[g.position]);g.fired=true;b._onPositionFired++}}return true};this.resetOnPosition=function(d){var g,m;g=a._onPositionItems.length;if(!g)return false; +for(g=g;g--;){m=a._onPositionItems[g];if(m.fired&&d<=m.position){m.fired=false;b._onPositionFired--}}return true};this._onTimer=function(d){var g={};if(a._hasTimer||d)if(h&&(d||(a.playState>0||a.readyState===1)&&!a.paused)){a.duration=n();a.durationEstimate=a.duration;d=h.currentTime?h.currentTime*1E3:0;a._whileplaying(d,g,g,g,g);return true}else return false};n=function(){var d=h?h.duration*1E3:undefined;return d&&!isNaN(d)?d:null};j=function(){a.isHTML5&&ya(a)};e=function(){a.isHTML5&&za(a)};f= +function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._added_events=null;h=a._audio=null;a.bytesLoaded=null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.didBeforeFinish=false;a.didJustBeforeFinish=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData= +[];a.eqData.left=[];a.eqData.right=[]};f();this._setup_html5=function(d){d=s(a._iO,d);if(h){if(a.url!==d.url)h.src=d.url}else{a._audio=new Audio(d.url);h=a._audio;a.isHTML5=true;i()}h.loop=d.loops>1?"loop":"";return a._audio};i=function(){function d(g,m,r){return h?h.addEventListener(g,m,r||false):null}if(a._added_events)return false;a._added_events=true;d("load",function(){if(h){a._onbufferchange(0);a._whileloading(a.bytesTotal,a.bytesTotal,n());a._onload(true)}},false);d("canplay",function(){a._onbufferchange(0)}, +false);d("waiting",function(){a._onbufferchange(1)},false);d("progress",function(g){if(!a.loaded&&h){a._onbufferchange(0);a._whileloading(g.loaded||0,g.total||1,n())}},false);d("error",function(){h&&a._onload(false)},false);d("loadstart",function(){a._onbufferchange(1)},false);d("play",function(){a._onbufferchange(0)},false);d("playing",function(){a._onbufferchange(0)},false);d("timeupdate",function(){a._onTimer()},false);setTimeout(function(){a&&h&&d("ended",function(){a._onfinish()},false)},250); +return true};this._whileloading=function(d,g,m,r){a.bytesLoaded=d;a.bytesTotal=g;a.duration=Math.floor(m);a.bufferLength=r;if(a._iO.isMovieStar)a.durationEstimate=a.duration;else{a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10);if(a.durationEstimate===undefined)a.durationEstimate=a.duration;a.bufferLength=r}a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._onid3=function(d,g){var m=[],r, +u;r=0;for(u=d.length;r<u;r++)m[d[r]]=g[r];a.id3=s(a.id3,m);a._iO.onid3&&a._iO.onid3.apply(a)};this._whileplaying=function(d,g,m,r,u){if(isNaN(d)||d===null)return false;if(a.playState===0&&d>0)d=0;a.position=d;a.processOnPosition();if(o>8&&!a.isHTML5){if(a._iO.usePeakData&&typeof g!=="undefined"&&g)a.peakData={left:g.leftPeak,right:g.rightPeak};if(a._iO.useWaveformData&&typeof m!=="undefined"&&m)a.waveformData={left:m.split(","),right:r.split(",")};if(a._iO.useEQData)if(typeof u!=="undefined"&&u&& +u.leftEQ){d=u.leftEQ.split(",");a.eqData=d;a.eqData.left=d;if(typeof u.rightEQ!=="undefined"&&u.rightEQ)a.eqData.right=u.rightEQ.split(",")}}if(a.playState===1){!a.isHTML5&&b.flashVersion===8&&!a.position&&a.isBuffering&&a._onbufferchange(0);a._iO.whileplaying&&a._iO.whileplaying.apply(a);if((a.loaded||!a.loaded&&a._iO.isMovieStar)&&a._iO.onbeforefinish&&a._iO.onbeforefinishtime&&!a.didBeforeFinish&&a.duration-a.position<=a._iO.onbeforefinishtime)a._onbeforefinish()}return true};this._onconnect=function(d){d= +d===1;if(a.connected=d){a.failures=0;a._iO.onconnect&&a._iO.onconnect.apply(a,[d]);if(p(a.sID)&&(a.options.autoLoad||a.getAutoPlay()))a.play(undefined,a.getAutoPlay())}};this._onload=function(d){d=d?true:false;a.loaded=d;a.readyState=d?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[d]);return true};this._onfailure=function(d,g,m){a.failures++;a._iO.onfailure&&a.failures===1&&a._iO.onfailure(a,d,g,m)};this._onbeforefinish=function(){if(!a.didBeforeFinish){a.didBeforeFinish=true;a._iO.onbeforefinish&& +a._iO.onbeforefinish.apply(a)}};this._onjustbeforefinish=function(){if(!a.didJustBeforeFinish){a.didJustBeforeFinish=true;a._iO.onjustbeforefinish&&a._iO.onjustbeforefinish.apply(a)}};this._onstats=function(d){a._iO.onstats&&a._iO.onstats(a,d)};this._onfinish=function(){a._onbufferchange(0);a.resetOnPosition(0);a._iO.onbeforefinishcomplete&&a._iO.onbeforefinishcomplete.apply(a);a.didBeforeFinish=false;a.didJustBeforeFinish=false;if(a.instanceCount){a.instanceCount--;if(!a.instanceCount){a.playState= +0;a.paused=false;a.instanceCount=0;a.instanceOptions={};e()}if(!a.instanceCount||a._iO.multiShotEvents)a._iO.onfinish&&a._iO.onfinish.apply(a)}};this._onbufferchange=function(d){if(a.playState===0)return false;if(d&&a.isBuffering||!d&&!a.isBuffering)return false;a.isBuffering=d===1;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return true};this._ondataerror=function(){a.playState>0&&a._iO.ondataerror&&a._iO.ondataerror.apply(a)}};fa=function(){return k.body?k.body:k._docElement?k.documentElement: +k.getElementsByTagName("div")[0]};z=function(c){return k.getElementById(c)};s=function(c,a){var f={},i,e;for(i in c)if(c.hasOwnProperty(i))f[i]=c[i];i=typeof a==="undefined"?b.defaultOptions:a;for(e in i)if(i.hasOwnProperty(e)&&typeof f[e]==="undefined")f[e]=i[e];return f};(function(){function c(e){e=Ca.call(e);var j=e.length;if(f){e[1]="on"+e[1];j>3&&e.pop()}else j===3&&e.push(false);return e}function a(e,j){var n=e.shift()[i[j]];f?n(e[0],e[1]):n.apply(this,e)}var f=l.attachEvent,i={add:f?"attachEvent": +"addEventListener",remove:f?"detachEvent":"removeEventListener"};y=function(){a(c(arguments),"add")};v=function(){a(c(arguments),"remove")}})();aa=function(c){return(c.type?R({type:c.type}):false)||R(c.url)};R=function(c){if(!b.useHTML5Audio||!b.hasHTML5)return false;var a,f=b.audioFormats;if(!x){x=[];for(a in f)if(f.hasOwnProperty(a)){x.push(a);if(f[a].related)x=x.concat(f[a].related)}x=RegExp("\\.("+x.join("|")+")","i")}a=typeof c.type!=="undefined"?c.type:null;c=typeof c==="string"?c.toLowerCase().match(x): +null;if(!c||!c.length){if(!a)return false}else c=c[0].substr(1);if(c&&typeof b.html5[c]!=="undefined")return b.html5[c];else{if(!a)if(c&&b.html5[c])return b.html5[c];else a="audio/"+c;a=b.html5.canPlayType(a);return b.html5[c]=a}};Ba=function(){function c(n){var h,d,g=false;if(!a||typeof a.canPlayType!=="function")return false;if(n instanceof Array){h=0;for(d=n.length;h<d&&!g;h++)if(b.html5[n[h]]||a.canPlayType(n[h]).match(b.html5Test)){g=true;b.html5[n[h]]=true}return g}else return(n=a&&typeof a.canPlayType=== +"function"?a.canPlayType(n):false)&&(n.match(b.html5Test)?true:false)}if(!b.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?new Audio:null,f,i={},e,j;e=b.audioFormats;for(f in e)if(e.hasOwnProperty(f)){i[f]=c(e[f].type);if(e[f]&&e[f].related)for(j=0;j<e[f].related.length;j++)b.html5[e[f].related[j]]=i[f]}i.canPlayType=a?c:null;b.html5=s(b.html5,i);return true};z=function(c){return k.getElementById(c)};H=function(){};Y=function(c){if(o===8&&c.loops>1&&c.stream)c.stream= +false;return c};Z=function(c){if(c&&!c.usePolicyFile&&(c.onid3||c.usePeakData||c.useWaveformData||c.useEQData))c.usePolicyFile=true;return c};ka=function(c){typeof console!=="undefined"&&typeof console.warn!=="undefined"&&console.warn(c)};qa=function(){return false};wa=function(c){for(var a in c)if(c.hasOwnProperty(a)&&typeof c[a]==="function")c[a]=qa};P=function(c){if(typeof c==="undefined")c=false;if(A||c)b.disable(c)};xa=function(c){var a=null;if(c)if(c.match(/\.swf(\?\.*)?$/i)){if(a=c.substr(c.toLowerCase().lastIndexOf(".swf?")+ +4))return c}else if(c.lastIndexOf("/")!==c.length-1)c+="/";return(c&&c.lastIndexOf("/")!==-1?c.substr(0,c.lastIndexOf("/")+1):"./")+b.movieURL};da=function(){if(o!==8&&o!==9)b.flashVersion=8;var c=b.debugMode||b.debugFlash?"_debug.swf":".swf";if(b.flashVersion<9&&b.useHTML5Audio&&b.audioFormats.mp4.required)b.flashVersion=9;o=b.flashVersion;b.version=b.versionNumber+(C?" (HTML5-only mode)":o===9?" (AS3/Flash 9)":" (AS2/Flash 8)");if(o>8){b.defaultOptions=s(b.defaultOptions,b.flash9Options);b.features.buffering= +true}if(o>8&&b.useMovieStar){b.defaultOptions=s(b.defaultOptions,b.movieStarOptions);b.filePatterns.flash9=RegExp("\\.(mp3|"+b.netStreamTypes.join("|")+")(\\?.*)?$","i");b.mimePattern=b.netStreamMimeTypes;b.features.movieStar=true}else b.features.movieStar=false;b.filePattern=b.filePatterns[o!==8?"flash9":"flash8"];b.movieURL=(o===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",c);b.features.peakData=b.features.waveformData=b.features.eqData=o>8};va=function(c,a){if(!b.o||!b.allowPolling)return false; +b.o._setPolling(c,a)};(function(){function c(e){e=Ca.call(e);var j=e.length;if(f){e[1]="on"+e[1];j>3&&e.pop()}else j===3&&e.push(false);return e}function a(e,j){var n=e.shift()[i[j]];f?n(e[0],e[1]):n.apply(this,e)}var f=l.attachEvent,i={add:f?"attachEvent":"addEventListener",remove:f?"detachEvent":"removeEventListener"};y=function(){a(c(arguments),"add")};v=function(){a(c(arguments),"remove")}})();ha=function(){function c(){f.left=l.scrollX+"px";f.top=l.scrollY+"px"}function a(i){i=l[(i?"add":"remove")+ +"EventListener"];i("resize",c,false);i("scroll",c,false)}var f=null;return{check:function(i){f=b.oMC.style;if(t.match(/android/i)){if(i){if(b.flashLoadTimeout)b._s.flashLoadTimeout=0;return false}f.position="absolute";f.left=f.top="0px";a(true);b.onready(function(){a(false);if(f)f.left=f.top="-9999px"});c()}return true}}}();X=function(c,a){var f=a?a:b.url,i=b.altURL?b.altURL:f,e;e=fa();var j,n,h=I(),d,g=null;g=(g=k.getElementsByTagName("html")[0])&&g.dir&&g.dir.match(/rtl/i);c=typeof c==="undefined"? +b.id:c;if(L&&M)return false;if(C){da();b.oMC=z(b.movieID);V();M=L=true;return false}L=true;da();b.url=xa(this._overHTTP?f:i);a=b.url;b.wmode=!b.wmode&&b.useHighPerformance&&!b.useMovieStar?"transparent":b.wmode;if(b.wmode!==null&&!w&&!b.useHighPerformance&&navigator.platform.match(/win32/i)){b.specialWmodeCase=true;b.wmode=null}e={name:c,id:c,src:a,width:"100%",height:"100%",quality:"high",allowScriptAccess:b.allowScriptAccess,bgcolor:b.bgColor,pluginspage:"http://www.macromedia.com/go/getflashplayer", +type:"application/x-shockwave-flash",wmode:b.wmode};if(b.debugFlash)e.FlashVars="debug=1";b.wmode||delete e.wmode;if(w){f=k.createElement("div");n='<object id="'+c+'" data="'+a+'" type="'+e.type+'" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+a+'" /><param name="AllowScriptAccess" value="'+b.allowScriptAccess+'" /><param name="quality" value="'+e.quality+'" />'+(b.wmode?'<param name="wmode" value="'+b.wmode+'" /> ':"")+'<param name="bgcolor" value="'+b.bgColor+'" />'+(b.debugFlash? +'<param name="FlashVars" value="'+e.FlashVars+'" />':"")+"<!-- --\></object>"}else{f=k.createElement("embed");for(j in e)e.hasOwnProperty(j)&&f.setAttribute(j,e[j])}pa();h=I();if(e=fa()){b.oMC=z(b.movieID)?z(b.movieID):k.createElement("div");if(b.oMC.id){d=b.oMC.className;b.oMC.className=(d?d+" ":b.swfCSS.swfDefault)+(h?" "+h:"");b.oMC.appendChild(f);if(w){j=b.oMC.appendChild(k.createElement("div"));j.className=b.swfCSS.swfBox;j.innerHTML=n}M=true;ha.check(true)}else{b.oMC.id=b.movieID;b.oMC.className= +b.swfCSS.swfDefault+" "+h;j=h=null;if(!b.useFlashBlock)if(b.useHighPerformance)h={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else{h={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"};if(g)h.left=Math.abs(parseInt(h.left,10))+"px"}if(t.match(/webkit/i))b.oMC.style.zIndex=1E4;if(!b.debugFlash)for(d in h)if(h.hasOwnProperty(d))b.oMC.style[d]=h[d];try{w||b.oMC.appendChild(f);e.appendChild(b.oMC);if(w){j=b.oMC.appendChild(k.createElement("div")); +j.className=b.swfCSS.swfBox;j.innerHTML=n}M=true}catch(m){throw Error(H("appXHTML"));}ha.check()}}return true};p=this.getSoundById;O=function(){if(C){X();return false}if(b.o)return false;b.o=b.getMovie(b.id);if(!b.o){if(Q){if(w)b.oMC.innerHTML=ia;else b.oMC.appendChild(Q);Q=null;L=true}else X(b.id,b.url);b.o=b.getMovie(b.id)}b.oninitmovie instanceof Function&&setTimeout(b.oninitmovie,1);return true};ca=function(c){if(c)b.url=c;O()};W=function(){setTimeout(ta,500)};ta=function(){if($)return false; +$=true;v(l,"load",W);if(K&&!na)return false;var c;q||(c=b.getMoviePercent());setTimeout(function(){c=b.getMoviePercent();if(!q&&Ea)if(c===null)if(b.useFlashBlock||b.flashLoadTimeout===0)b.useFlashBlock&&ja();else P(true);else b.flashLoadTimeout!==0&&P(true)},b.flashLoadTimeout)};ca=function(c){if(c)b.url=c;O()};I=function(){var c=[];b.debugMode&&c.push(b.swfCSS.sm2Debug);b.debugFlash&&c.push(b.swfCSS.flashDebug);b.useHighPerformance&&c.push(b.swfCSS.highPerf);return c.join(" ")};ja=function(){H("fbHandler"); +var c=b.getMoviePercent();if(b.supported()){if(b.oMC)b.oMC.className=I()+" "+b.swfCSS.swfDefault+(" "+b.swfCSS.swfUnblocked)}else{if(J)b.oMC.className=I()+" "+b.swfCSS.swfDefault+" "+(c===null?b.swfCSS.swfTimedout:b.swfCSS.swfError);b.didFlashBlock=true;E(true);b.onerror instanceof Function&&b.onerror.apply(l)}};B=function(){function c(){v(l,"focus",B);v(l,"load",B)}if(na||!K){c();return true}na=Ea=true;S&&K&&v(l,"mousemove",B);$=false;c();return true};N=function(c){if(q)return false;if(C){q=true; +E();F();return true}b.useFlashBlock&&b.flashLoadTimeout&&!b.getMoviePercent()||(q=true);if(A||c){if(b.useFlashBlock)b.oMC.className=I()+" "+(b.getMoviePercent()===null?b.swfCSS.swfTimedout:b.swfCSS.swfError);E();b.onerror instanceof Function&&b.onerror.apply(l);return false}if(b.waitForWindowLoad&&!ra){y(l,"load",F);return false}else F();return true};sa=function(c,a){D.push({method:c,scope:a||null,fired:false})};E=function(c){if(!q&&!c)return false;c={success:c?b.supported():!A};var a=[],f,i,e=!b.useFlashBlock|| +b.useFlashBlock&&!b.supported();f=0;for(i=D.length;f<i;f++)D[f].fired!==true&&a.push(D[f]);if(a.length){f=0;for(i=a.length;f<i;f++){a[f].scope?a[f].method.apply(a[f].scope,[c]):a[f].method(c);if(!e)a[f].fired=true}}return true};F=function(){l.setTimeout(function(){b.useFlashBlock&&ja();E();b.onload instanceof Function&&b.onload.apply(l);b.waitForWindowLoad&&y(l,"load",F)},1)};Aa=function(){var c,a,f=!U.match(/usehtml5audio/i)&&!U.match(/sm2\-ignorebadua/i)&&S&&t.match(/OS X 10_6_(3|4)/i);if(t.match(/iphone os (1|2|3_0|3_1)/i)? +true:false){b.hasHTML5=false;C=true;if(b.oMC)b.oMC.style.display="none";return false}if(b.useHTML5Audio){if(!b.html5||!b.html5.canPlayType){b.hasHTML5=false;return true}else b.hasHTML5=true;if(f){b.useHTML5Audio=false;b.hasHTML5=false;return true}}else return true;for(a in b.audioFormats)if(b.audioFormats.hasOwnProperty(a)&&b.audioFormats[a].required&&!b.html5.canPlayType(b.audioFormats[a].type))c=true;if(b.ignoreFlash)c=false;C=b.useHTML5Audio&&b.hasHTML5&&!c;return c};V=function(){var c,a=[];if(q)return false; +if(b.hasHTML5)for(c in b.audioFormats)b.audioFormats.hasOwnProperty(c)&&a.push(c+": "+b.html5[c]);if(C){if(!q){v(l,"load",b.beginDelayedInit);b.enabled=true;N()}return true}O();try{b.o._externalInterfaceTest(false);if(b.allowPolling)va(true,b.useFastPolling?true:false);b.debugMode||b.o._disableDebug();b.enabled=true}catch(f){P(true);N();return false}N();v(l,"load",b.beginDelayedInit);return true};ua=function(){if(la)return false;X();O();return la=true};G=function(){if(ea)return false;ea=true;pa(); +Ba();b.html5.usingFlash=Aa();J=b.html5.usingFlash;ea=true;k.removeEventListener&&k.removeEventListener("DOMContentLoaded",G,false);ca();return true};ya=function(c){if(!c._hasTimer)c._hasTimer=true};za=function(c){if(c._hasTimer)c._hasTimer=false};ga=function(){b.onerror instanceof Function&&b.onerror();b.disable()};this._setSandboxType=function(){};this._externalInterfaceOK=function(){if(b.swfLoaded)return false;(new Date).getTime();b.swfLoaded=true;K=false;w?setTimeout(V,100):V()};ma=function(){if(k.readyState=== +"complete"){G();k.detachEvent("onreadystatechange",ma)}return true};if(!b.hasHTML5||J){y(l,"focus",B);y(l,"load",B);y(l,"load",W);S&&K&&y(l,"mousemove",B)}if(k.addEventListener)k.addEventListener("DOMContentLoaded",G,false);else k.attachEvent?k.attachEvent("onreadystatechange",ma):ga();k.readyState==="complete"&&setTimeout(G,100)}var Fa=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)Fa=new oa;T.SoundManager=oa;T.soundManager=Fa})(window); diff --git a/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug.js b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug.js new file mode 100755 index 0000000..9c1df6f --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2-nodebug.js @@ -0,0 +1,2838 @@ +/** @license + * SoundManager 2: Javascript Sound for the Web + * -------------------------------------------- + * http://schillmania.com/projects/soundmanager2/ + * + * Copyright (c) 2007, Scott Schiller. All rights reserved. + * Code provided under the BSD License: + * http://schillmania.com/projects/soundmanager2/license.txt + * + * V2.97a.20101010 + */ + +/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: true, newcap: true, immed: true, regexp: false */ +/*global window, SM2_DEFER, sm2Debugger, alert, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ + +(function(window) { + +var soundManager = null; + +function SoundManager(smURL, smID) { + + this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. + this.debugMode = false; // enable debugging output (div#soundmanager-debug, OR console if available+configured) + this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues + this.useConsole = true; // use firebug/safari console.log()-type debug console if available + this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug + this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() + this.nullURL = 'about:blank'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) + this.allowPolling = true; // allow flash to poll for status update (required for whileplaying() events, peak, sound spectrum functions to work.) + this.useFastPolling = false; // uses lower flash timer interval for higher callback frequency, best combined with useHighPerformance + this.useMovieStar = true; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio formats (AAC, M4V, FLV, MOV etc.) + this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000' + this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag + this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity) + this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top) + this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain' + this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable. + this.useHTML5Audio = false; // Beta feature: Use HTML 5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible. + this.html5Test = /^probably$/i; // HTML5 Audio().canPlayType() test. /^(probably|maybe)$/i if you want to be more liberal/risky. + this.ondebuglog = false; // callback made with each log message, regardless of debugMode + + this.audioFormats = { + // determines HTML5 support, flash requirements + // eg. if MP3 or MP4 required, Flash fallback is used if HTML5 can't play it + // shotgun approach to MIME testing due to browser variance + 'mp3': { + 'type': ['audio/mpeg; codecs="mp3"','audio/mpeg','audio/mp3','audio/MPA','audio/mpa-robust'], + 'required': true + }, + 'mp4': { + 'related': ['aac','m4a'], // additional formats under the MP4 container + 'type': ['audio/mp4; codecs="mp4a.40.2"','audio/aac','audio/x-m4a','audio/MP4A-LATM','audio/mpeg4-generic'], + 'required': true + }, + 'ogg': { + 'type': ['audio/ogg; codecs=vorbis'], + 'required': false + }, + 'wav': { + 'type': ['audio/wav; codecs="1"','audio/wav','audio/wave','audio/x-wav'], + 'required': false + } + }; + + this.defaultOptions = { + '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) + 'stream': true, // allows playing before entire file has loaded (recommended) + 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) + 'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0) + 'onid3': null, // callback function for "ID3 data is added/available" + 'onload': null, // callback function for "load finished" + 'whileloading': null, // callback function for "download progress update" (X of Y bytes received) + 'onplay': null, // callback for "play" start + 'onpause': null, // callback for "pause" + 'onresume': null, // callback for "resume" (pause toggle) + 'whileplaying': null, // callback during play (position update) + 'onstop': null, // callback for "user stop" + 'onfailure': null, // callback function for when playing fails + 'onfinish': null, // callback function for "sound finished playing" + 'onbeforefinish': null, // callback for "before sound finished playing (at [time])" + 'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) + 'onbeforefinishcomplete': null,// function to call when said sound finishes playing + 'onjustbeforefinish': null, // callback for [n] msec before end of current sound + 'onjustbeforefinishtime': 200, // [n] - if not using, set to 0 (or null handler) and event will not fire. + 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time + 'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled + 'position': null, // offset (milliseconds) to seek to within loaded sound data. + 'pan': 0, // "pan" settings, left-to-right, -100 to 100 + 'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3 + 'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access) + 'volume': 100 // self-explanatory. 0-100, the latter being the max. + }; + + this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used + 'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL + 'usePeakData': false, // enable left/right channel peak (level) data + 'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. + 'useEQData': false, // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. + 'onbufferchange': null, // callback for "isBuffering" property change + 'ondataerror': null, // callback for waveform/eq data access error (flash playing audio in other tabs/domains) + 'onstats': null // callback for when connection & play times have been measured + }; + + this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio options, merged into defaultOptions if flash 9+movieStar mode is enabled + 'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.) + 'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants + 'onconnect': null, // rtmp: callback for connection to flash media server + 'bufferTimes': null, // array of buffer sizes to use. Size increases as buffer fills up. + 'duration': null // rtmp: song duration (msec) + }; + + this.version = null; + this.versionNumber = 'V2.97a.20101010'; + this.movieURL = null; + this.url = (smURL || null); + this.altURL = null; + this.swfLoaded = false; + this.enabled = false; + this.o = null; + this.movieID = 'sm2-container'; + this.id = (smID || 'sm2movie'); + this.swfCSS = { + 'swfBox': 'sm2-object-box', + 'swfDefault': 'movieContainer', + 'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error) + 'swfTimedout': 'swf_timedout', + 'swfUnblocked': 'swf_unblocked', // or loaded OK + 'sm2Debug': 'sm2_debug', + 'highPerf': 'high_performance', + 'flashDebug': 'flash_debug' + }; + this.oMC = null; + this.sounds = {}; + this.soundIDs = []; + this.muted = false; + this.debugID = 'soundmanager-debug'; + this.debugURLParam = /([#?&])debug=1/i; + this.specialWmodeCase = false; + this.didFlashBlock = false; + + this.filePattern = null; + this.filePatterns = { + 'flash8': /\.mp3(\?.*)?$/i, + 'flash9': /\.mp3(\?.*)?$/i + }; + + this.baseMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3 + this.netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3, mp4, aac etc. + this.netStreamTypes = ['aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2']; // Flash v9.0r115+ "moviestar" formats + this.netStreamPattern = new RegExp('\\.(' + this.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + this.mimePattern = this.baseMimeTypes; + + 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.hasHTML5 = null; // switch for handling logic + this.html5 = { // stores canPlayType() results, etc. treat as read-only. + // mp3: boolean + // mp4: boolean + 'usingFlash': null // set if/when flash fallback is needed + }; + this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?) + + // --- private SM2 internals --- + + var SMSound, + _s = this, _sm = 'soundManager', _id, _ua = navigator.userAgent, _wl = window.location.href.toString(), _fV = this.flashVersion, _doc = document, _win = window, _doNothing, _init, _onready = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnReady, _processOnReady, _initUserOnload, _go, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _beginInit, _strings, _initMovie, _dcLoaded, _didDCLoaded, _getDocument, _createMovie, _die, _mobileFlash, _setPolling, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5Only = false, _html5CanPlay, _html5Ext, _dcIE, _testHTML5, _addEvt, _removeEvt, _slice = Array.prototype.slice, + _is_pre = _ua.match(/pre\//i), + _iPadOrPhone = _ua.match(/(ipad|iphone)/i), + _isMobile = (_ua.match(/mobile/i) || _is_pre || _iPadOrPhone), + _isIE = (_ua.match(/MSIE/i)), + _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), + _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), + _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), + _tryInitOnFocus = (typeof _doc.hasFocus === 'undefined' && _isSafari), + _okToDisable = !_tryInitOnFocus; + + this._use_maybe = (_wl.match(/sm2\-useHTML5Maybe\=1/i)); // temporary feature: #sm2-useHTML5Maybe=1 forces loose canPlay() check + this._overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null); + this.useAltURL = !this._overHTTP; // use altURL if not "online" + + if (_iPadOrPhone || _is_pre) { + // might as well force it on Apple + Palm, flash support unlikely + _s.useHTML5Audio = true; + _s.ignoreFlash = true; + } + + if (_is_pre || this._use_maybe) { + // less-strict canPlayType() checking option + _s.html5Test = /^(probably|maybe)$/i; + } + + // Temporary feature: allow force of HTML5 via URL: #sm2-usehtml5audio=0 or 1 + /* + (function(){ + var a = '#sm2-usehtml5audio=', l = _wl, b = null; + if (l.indexOf(a) !== -1) { + b = (l.substr(l.indexOf(a)+a.length) === '1'); + if (typeof console !== 'undefined' && typeof console.log !== 'undefined') { + console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); + } + _s.useHTML5Audio = b; + } + }()); + */ + + // --- public API methods --- + + this.supported = function() { + return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); + }; + + this.getMovie = function(smID) { + return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); + }; + + this.loadFromXML = function(sXmlUrl) { + try { + _s.o._loadFromXML(sXmlUrl); + } catch(e) { + _failSafely(); + } + return true; + }; + + this.createSound = function(oOptions) { + var _cs = 'soundManager.createSound(): ', + thisOptions = null, oSound = null, _tO = null; + if (!_didInit || !_s.supported()) { + _complain(_cs + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (arguments.length === 2) { + // function overloading in JS! :) ..assume simple createSound(id,url) use case + oOptions = { + 'id': arguments[0], + 'url': arguments[1] + }; + } + thisOptions = _mixin(oOptions); // inherit from defaultOptions + _tO = thisOptions; // alias + /* + if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { + //_s._wD(_cs + _str('badID', _tO.id), 2); + } + //_s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); + */ + if (_idCheck(_tO.id, true)) { + //_s._wD(_cs + _tO.id + ' exists', 1); + return _s.sounds[_tO.id]; + } + + function make() { + thisOptions = _loopFix(thisOptions); + _s.sounds[_tO.id] = new SMSound(_tO); + _s.soundIDs.push(_tO.id); + return _s.sounds[_tO.id]; + } + + if (_html5OK(_tO)) { + oSound = make(); + //_s._wD('Loading sound '+_tO.id+' from HTML5'); + oSound._setup_html5(_tO); + } else { + if (_fV > 8 && _s.useMovieStar) { + if (_tO.isMovieStar === null) { + _tO.isMovieStar = ((_tO.serverURL || (_tO.type?_tO.type.match(_s.netStreamPattern):false)||_tO.url.match(_s.netStreamPattern))?true:false); + } + if (_tO.isMovieStar) { + //_s._wD(_cs + 'using MovieStar handling'); + } + if (_tO.isMovieStar) { + if (_tO.usePeakData) { + //_wDS('noPeak'); + _tO.usePeakData = false; + } + if (_tO.loops > 1) { + //_wDS('noNSLoop'); + } + } + } + _tO = _policyFix(_tO, _cs); + oSound = make(); + if (_fV === 8) { + _s.o._createSound(_tO.id, _tO.onjustbeforefinishtime, _tO.loops||1, _tO.usePolicyFile); + } else { + _s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.bufferTimes, _tO.onstats ? true : false, _tO.autoLoad, _tO.usePolicyFile); + if (!_tO.serverURL) { + // We are connected immediately + oSound.connected = true; + if (_tO.onconnect) { + _tO.onconnect.apply(oSound); + } + } + } + } + if (_tO.autoLoad || _tO.autoPlay) { + if (oSound) { + if (_s.isHTML5) { + oSound.autobuffer = 'auto'; // early HTML5 implementation (non-standard) + oSound.preload = 'auto'; // standard + } else { + oSound.load(_tO); + } + } + } + if (_tO.autoPlay) { + oSound.play(); + } + return oSound; + }; + + this.destroySound = function(sID, _bFromSound) { + // explicitly destroy a sound before normal page unload, etc. + if (!_idCheck(sID)) { + return false; + } + var oS = _s.sounds[sID], i; + oS._iO = {}; // Disable all callbacks while the sound is being destroyed + oS.stop(); + oS.unload(); + for (i = 0; i < _s.soundIDs.length; i++) { + if (_s.soundIDs[i] === sID) { + _s.soundIDs.splice(i, 1); + break; + } + } + if (!_bFromSound) { + // ignore if being called from SMSound instance + oS.destruct(true); + } + oS = null; + delete _s.sounds[sID]; + return true; + }; + + this.load = function(sID, oOptions) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].load(oOptions); + }; + + this.unload = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].unload(); + }; + + this.play = function(sID, oOptions) { + var fN = 'soundManager.play(): '; + if (!_didInit || !_s.supported()) { + _complain(fN + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (!_idCheck(sID)) { + if (!(oOptions instanceof Object)) { + oOptions = { + url: oOptions + }; // overloading use case: play('mySound','/path/to/some.mp3'); + } + if (oOptions && oOptions.url) { + // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); + //_s._wD(fN + 'attempting to create "' + sID + '"', 1); + oOptions.id = sID; + return _s.createSound(oOptions).play(); + } else { + return false; + } + } + return _s.sounds[sID].play(oOptions); + }; + + this.start = this.play; // just for convenience + + this.setPosition = function(sID, nMsecOffset) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPosition(nMsecOffset); + }; + + this.stop = function(sID) { + if (!_idCheck(sID)) { + return false; + } + //_s._wD('soundManager.stop(' + sID + ')', 1); + return _s.sounds[sID].stop(); + }; + + this.stopAll = function() { + //_s._wD('soundManager.stopAll()', 1); + for (var oSound in _s.sounds) { + if (_s.sounds[oSound] instanceof SMSound) { + _s.sounds[oSound].stop(); // apply only to sound objects + } + } + }; + + this.pause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].pause(); + }; + + this.pauseAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].pause(); + } + }; + + this.resume = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].resume(); + }; + + this.resumeAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].resume(); + } + }; + + this.togglePause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].togglePause(); + }; + + this.setPan = function(sID, nPan) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPan(nPan); + }; + + this.setVolume = function(sID, nVol) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setVolume(nVol); + }; + + this.mute = function(sID) { + var fN = 'soundManager.mute(): ', + i = 0; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + //_s._wD(fN + 'Muting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].mute(); + } + _s.muted = true; + } else { + if (!_idCheck(sID)) { + return false; + } + //_s._wD(fN + 'Muting "' + sID + '"'); + return _s.sounds[sID].mute(); + } + return true; + }; + + this.muteAll = function() { + _s.mute(); + }; + + this.unmute = function(sID) { + var fN = 'soundManager.unmute(): ', i; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + //_s._wD(fN + 'Unmuting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].unmute(); + } + _s.muted = false; + } else { + if (!_idCheck(sID)) { + return false; + } + //_s._wD(fN + 'Unmuting "' + sID + '"'); + return _s.sounds[sID].unmute(); + } + return true; + }; + + this.unmuteAll = function() { + _s.unmute(); + }; + + this.toggleMute = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].toggleMute(); + }; + + this.getMemoryUse = function() { + if (_fV === 8) { + return 0; + } + if (_s.o) { + return parseInt(_s.o._getMemoryUse(), 10); + } + }; + + this.disable = function(bNoDisable) { + // destroy all functions + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled) { + return false; + } + _disabled = true; + //_wDS('shutdown', 1); + for (var i = _s.soundIDs.length; i--;) { + _disableObject(_s.sounds[_s.soundIDs[i]]); + } + _initComplete(bNoDisable); // fire "complete", despite fail + _removeEvt(_win, 'load', _initUserOnload); + return true; + }; + + this.canPlayMIME = function(sMIME) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay({type:sMIME}); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sMIME?(sMIME.match(_s.mimePattern)?true:false):null); + } + }; + + this.canPlayURL = function(sURL) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay(sURL); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sURL?(sURL.match(_s.filePattern)?true:false):null); + } + }; + + this.canPlayLink = function(oLink) { + if (typeof oLink.type !== 'undefined' && oLink.type) { + if (_s.canPlayMIME(oLink.type)) { + return true; + } + } + return _s.canPlayURL(oLink.href); + }; + + this.getSoundById = function(sID, suppressDebug) { + if (!sID) { + throw new Error('SoundManager.getSoundById(): sID is null/undefined'); + } + var result = _s.sounds[sID]; + if (!result && !suppressDebug) { + //_s._wD('"' + sID + '" is an invalid sound ID.', 2); + } + return result; + }; + + this.onready = function(oMethod, oScope) { + if (oMethod && oMethod instanceof Function) { + if (_didInit) { + //_wDS('queue'); + } + if (!oScope) { + oScope = _win; + } + _addOnReady(oMethod, oScope); + _processOnReady(); + return true; + } else { + throw _str('needFunction'); + } + }; + + this.getMoviePercent = function() { + return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); + }; + + this._writeDebug = function(sText, sType, bTimestamp) { + // If the debug log callback is set, always call it, regardless of debugMode + if (_s.ondebuglog) { + _s.ondebuglog(sText, sType, bTimestamp); + } + // pseudo-private console.log()-style output + /* + var sDID = 'soundmanager-debug', o, oItem, sMethod; + if (!_s.debugMode) { + return false; + } + if (typeof bTimestamp !== 'undefined' && bTimestamp) { + sText = sText + ' | ' + new Date().getTime(); + } + if (_hasConsole && _s.useConsole) { + sMethod = _debugLevels[sType]; + if (typeof console[sMethod] !== 'undefined') { + console[sMethod](sText); + } else { + console.log(sText); + } + if (_s.useConsoleOnly) { + return true; + } + } + try { + o = _id(sDID); + if (!o) { + return false; + } + oItem = _doc.createElement('div'); + if (++_wdCount % 2 === 0) { + oItem.className = 'sm2-alt'; + } + if (typeof sType === 'undefined') { + sType = 0; + } else { + sType = parseInt(sType, 10); + } + oItem.appendChild(_doc.createTextNode(sText)); + if (sType) { + if (sType >= 2) { + oItem.style.fontWeight = 'bold'; + } + if (sType === 3) { + oItem.style.color = '#ff3333'; + } + } + // o.appendChild(oItem); // top-to-bottom + o.insertBefore(oItem, o.firstChild); // bottom-to-top + } catch(e) { + // oh well + } + o = null; + */ + return true; + }; + this._wD = this._writeDebug; // alias + + this._debug = function() { + /* + //_wDS('currentObj', 1); + for (var i = 0, j = _s.soundIDs.length; i < j; i++) { + _s.sounds[_s.soundIDs[i]]._debug(); + } + */ + }; + + this.reboot = function() { + // attempt to reset and init SM2 + //_s._wD('soundManager.reboot()'); + if (_s.soundIDs.length) { + //_s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); + } + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].destruct(); + } + // trash ze flash + try { + if (_isIE) { + _oRemovedHTML = _s.o.innerHTML; + } + _oRemoved = _s.o.parentNode.removeChild(_s.o); + //_s._wD('Flash movie removed.'); + } catch(e) { + // uh-oh. + //_wDS('badRemove', 2); + } + // actually, force recreate of movie. + _oRemovedHTML = _oRemoved = null; + _s.enabled = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; + _s.soundIDs = _s.sounds = []; + _s.o = null; + for (i = _onready.length; i--;) { + _onready[i].fired = false; + } + //_s._wD(_sm + ': Rebooting...'); + _win.setTimeout(function() { + _s.beginDelayedInit(); + }, 20); + }; + + this.destruct = function() { + //_s._wD('soundManager.destruct()'); + _s.disable(true); + }; + + this.beginDelayedInit = function() { + // //_s._wD('soundManager.beginDelayedInit()'); + _windowLoaded = true; + _dcLoaded(); + setTimeout(_beginInit, 20); + _delayWaitForEI(); + }; + + // --- SMSound (sound object) instance --- + + SMSound = function(oOptions) { + var _t = this, _resetProperties, _add_html5_events, _stop_html5_timer, _start_html5_timer, _get_html5_duration, _a; + this.sID = oOptions.id; + this.url = oOptions.url; + this.options = _mixin(oOptions); + this.instanceOptions = this.options; // per-play-instance-specific options + this._iO = this.instanceOptions; // short alias + // assign property defaults + this.pan = this.options.pan; + this.volume = this.options.volume; + this._lastURL = null; + this.isHTML5 = false; + + // --- public methods --- + + this.id3 = {}; + + this._debug = function() { + /* + // pseudo-private console.log()-style output + if (_s.debugMode) { + var stuff = null, msg = [], sF, sfBracket, maxLength = 64; + for (stuff in _t.options) { + if (_t.options[stuff] !== null) { + if (_t.options[stuff] instanceof Function) { + // handle functions specially + sF = _t.options[stuff].toString(); + sF = sF.replace(/\s\s+/g, ' '); // normalize spaces + sfBracket = sF.indexOf('{'); + msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }'); + } else { + msg.push(' ' + stuff + ': ' + _t.options[stuff]); + } + } + } + //_s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}'); + } + */ + }; + + this._debug(); + + this.load = function(oOptions) { + var oS = null; + if (typeof oOptions !== 'undefined') { + _t._iO = _mixin(oOptions); + _t.instanceOptions = _t._iO; + } else { + oOptions = _t.options; + _t._iO = oOptions; + _t.instanceOptions = _t._iO; + if (_t._lastURL && _t._lastURL !== _t.url) { + //_wDS('manURL'); + _t._iO.url = _t.url; + _t.url = null; + } + } + //_s._wD('soundManager.load(): ' + _t._iO.url, 1); + if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { + //_wDS('onURL', 1); + return _t; + } + _t._lastURL = _t.url; + _t.loaded = false; + _t.readyState = 1; + _t.playState = 0; + if (_html5OK(_t._iO)) { + //_s._wD('HTML 5 load: '+_t._iO.url); + oS = _t._setup_html5(_t._iO); + oS.load(); + if (_t._iO.autoPlay) { + _t.play(); + } + } else { + try { + _t.isHTML5 = false; + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_fV === 8) { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile); + } else { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream?true:false, _t._iO.autoPlay?true:false, _t._iO.loops||1, _t._iO.autoLoad?true:false, _t._iO.usePolicyFile); + } + } catch(e) { + //_wDS('smError', 2); + //_debugTS('onload', false); + _die(); + } + } + return _t; + }; + + this.unload = function() { + // Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 + // Flash 9/AS3: Close stream, preventing further load + if (_t.readyState !== 0) { + //_s._wD('SMSound.unload(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + if (_fV === 8) { + _s.o._unload(_t.sID, _s.nullURL); + } else { + _s.o._unload(_t.sID); + } + } else { + _stop_html5_timer(); + if (_a) { + // abort()-style method here, stop loading? (doesn't exist?) + _a.pause(); + _a.src = _s.nullURL; // needed? does nulling object work? any better way to cancel/unload/abort? + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + // reset load/status flags + _resetProperties(); + } + return _t; + }; + + this.destruct = function(_bFromSM) { + //_s._wD('SMSound.destruct(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + // kill sound within Flash + // Disable the onfailure handler + _t._iO.onfailure = null; + _s.o._destroySound(_t.sID); + } else { + _stop_html5_timer(); + if (_a) { + _a.pause(); + _a.src = 'about:blank'; + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + if (!_bFromSM) { + _s.destroySound(_t.sID, true); // ensure deletion from controller + } + }; + + this.play = function(oOptions, _updatePlayState) { + var fN = 'SMSound.play(): ', allowMulti; + _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState); + if (!oOptions) { + oOptions = {}; + } + _t._iO = _mixin(oOptions, _t._iO); + _t._iO = _mixin(_t._iO, _t.options); + _t.instanceOptions = _t._iO; + if (_t._iO.serverURL) { + if (!_t.connected) { + if (!_t.getAutoPlay()) { + //_s._wD(fN+' Netstream not connected yet - setting autoPlay'); + _t.setAutoPlay(true); + } + return _t; + } + } + if (_html5OK(_t._iO)) { + _t._setup_html5(_t._iO); + _start_html5_timer(); + } + // KJV paused sounds have playState 1. We want these sounds to play. + if (_t.playState === 1 && !_t.paused) { + allowMulti = _t._iO.multiShot; + if (!allowMulti) { + //_s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1); + return _t; + } else { + //_s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1); + if (_t.isHTML5) { + // TODO: BUG? + _t.setPosition(_t._iO.position); + } + } + } + if (!_t.loaded) { + if (_t.readyState === 0) { + //_s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1); + // try to get this sound playing ASAP + if (!_t.isHTML5) { + if (!_t._iO.serverURL) { + _t._iO.autoPlay = true; + _t.load(_t._iO); + } + } else { + _t.load(_t._iO); + _t.readyState = 1; + } + } else if (_t.readyState === 2) { + //_s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2); + return _t; + } else { + //_s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1); + } + } else { + //_s._wD(fN + '"' + _t.sID + '"'); + } + // Streams will pause when their buffer is full if they are not auto-playing. + // In this case paused is true, but the song hasn't started playing yet. If + // we just call resume() the onplay() callback will never be called. + + // Also, if we just call resume() in this case and the sound has been muted + // (volume is 0), it will never have its volume set so sound will be heard + // when it shouldn't. + if (_t.paused && _t.position && _t.position > 0) { // https://gist.github.com/37b17df75cc4d7a90bf6 + //_s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1); + _t.resume(); + } else { + //_s._wD(fN+'"'+ _t.sID+'" is starting to play'); + _t.playState = 1; + _t.paused = false; + if (!_t.instanceCount || _t._iO.multiShotEvents || (_fV > 8 && !_t.isHTML5 && !_t.getAutoPlay())) { + _t.instanceCount++; + } + _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_t._iO.onplay && _updatePlayState) { + _t._iO.onplay.apply(_t); + } + _t.setVolume(_t._iO.volume, true); + _t.setPan(_t._iO.pan, true); + if (!_t.isHTML5) { + _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t.position:_t.position / 1000)); + } else { + _start_html5_timer(); + _t._setup_html5().play(); + } + } + return _t; + }; + + this.start = this.play; // just for convenience + + this.stop = function(bAll) { + if (_t.playState === 1) { + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (!_t.isHTML5) { + _t.playState = 0; + } + _t.paused = false; + if (_t._iO.onstop) { + _t._iO.onstop.apply(_t); + } + if (!_t.isHTML5) { + _s.o._stop(_t.sID, bAll); + // hack for netStream: just unload + if (_t._iO.serverURL) { + _t.unload(); + } + } else { + if (_a) { + _t.setPosition(0); // act like Flash, though + _a.pause(); // html5 has no stop() + _t.playState = 0; + _t._onTimer(); // and update UI + _stop_html5_timer(); + _t.unload(); + } + } + _t.instanceCount = 0; + _t._iO = {}; + } + return _t; + }; + + this.setAutoPlay = function(autoPlay) { + //_s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off')); + _t._iO.autoPlay = autoPlay; + _s.o._setAutoPlay(_t.sID, autoPlay); + if (autoPlay) { + // KJV Only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP) + if (!_t.instanceCount && _t.readyState === 1) { + _t.instanceCount++; + //_s._wD('sound '+_t.sID+' incremented instance count to '+_t.instanceCount); + } + } + }; + + this.getAutoPlay = function() { + return _t._iO.autoPlay; + }; + + this.setPosition = function(nMsecOffset, bNoDebug) { + if (nMsecOffset === undefined) { + nMsecOffset = 0; + } + // KJV Use the duration from the instance options, if we don't have a track duration yet. + // Auto-loading streams with a starting position in their options will start playing + // as soon as they connect. In the start() call we set the position on the stream, + // but because the stream hasn't played _t.duration won't have been set (that is + // done in whileloading()). So if we don't have a duration yet, use the duration + // from the instance options, if available. + var position, offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); // position >= 0 and <= current available (loaded) duration + _t.position = offset; + _t.resetOnPosition(_t.position); + if (!_t.isHTML5) { + position = _fV === 9 ? _t.position : _t.position / 1000; + // KJV We want our sounds to play on seek. A progressive download that + // is loaded has paused = false so resume() does nothing and the sound + // doesn't play. Handle that case here. + if (_t.playState === 0) { + _t.play({ position: position }); + } else { + _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) + // if (_t.paused) { + // _t.resume(); + // } + } + } else if (_a) { + //_s._wD('setPosition(): setting position to '+(_t.position / 1000)); + if (_t.playState) { + // DOM/JS errors/exceptions to watch out for: + // if seek is beyond (loaded?) position, "DOM exception 11" + // "INDEX_SIZE_ERR": DOM exception 1 + try { + _a.currentTime = _t.position / 1000; + } catch(e) { + //_s._wD('setPosition('+_t.position+'): WARN: Caught exception: '+e.message, 2); + } + } else { + //_s._wD('HTML 5 warning: cannot set position while playState == 0 (not playing)',2); + } + if (_t.paused) { // if paused, refresh UI right away + _t._onTimer(true); // force update + if (_t._iO.useMovieStar) { + _t.resume(); + } + } + } + return _t; + }; + + this.pause = function(bCallFlash) { + if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { + return _t; + } + //_s._wD('SMSound.pause()'); + _t.paused = true; + if (!_t.isHTML5) { + if (bCallFlash || bCallFlash === undefined) { + _s.o._pause(_t.sID); + } + } else { + _t._setup_html5().pause(); + _stop_html5_timer(); + } + if (_t._iO.onpause) { + _t._iO.onpause.apply(_t); + } + return _t; + }; + + this.resume = function() { + // When auto-loaded streams pause on buffer full they have a playState of 0. + // We need to make sure that the playState is set to 1 when these streams "resume". + if (!_t.paused) { + return _t; + } + //_s._wD('SMSound.resume()'); + _t.paused = false; + _t.playState = 1; // TODO: verify that this is needed. + if (!_t.isHTML5) { + _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) + } else { + _t._setup_html5().play(); + _start_html5_timer(); + } + if (_t._iO.onresume) { + _t._iO.onresume.apply(_t); + } + return _t; + }; + + this.togglePause = function() { + //_s._wD('SMSound.togglePause()'); + if (_t.playState === 0) { + _t.play({ + position: (_fV === 9 && !_t.isHTML5 ? _t.position:_t.position / 1000) + }); + return _t; + } + if (_t.paused) { + _t.resume(); + } else { + _t.pause(); + } + return _t; + }; + + this.setPan = function(nPan, bInstanceOnly) { + if (typeof nPan === 'undefined') { + nPan = 0; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setPan(_t.sID, nPan); + } // else { no HTML5 pan? } + _t._iO.pan = nPan; + if (!bInstanceOnly) { + _t.pan = nPan; + } + return _t; + }; + + this.setVolume = function(nVol, bInstanceOnly) { + if (typeof nVol === 'undefined') { + nVol = 100; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); + } else if (_a) { + _a.volume = nVol/100; + } + _t._iO.volume = nVol; + if (!bInstanceOnly) { + _t.volume = nVol; + } + return _t; + }; + + this.mute = function() { + _t.muted = true; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, 0); + } else if (_a) { + _a.muted = true; + } + return _t; + }; + + this.unmute = function() { + _t.muted = false; + var hasIO = typeof _t._iO.volume !== 'undefined'; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); + } else if (_a) { + _a.muted = false; + } + return _t; + }; + + this.toggleMute = function() { + return (_t.muted?_t.unmute():_t.mute()); + }; + + this.onposition = function(nPosition, oMethod, oScope) { + // TODO: allow for ranges, too? eg. (nPosition instanceof Array) + _t._onPositionItems.push({ + position: nPosition, + method: oMethod, + scope: (typeof oScope !== 'undefined'?oScope:_t), + fired: false + }); + return _t; + }; + + this.processOnPosition = function() { + var i, item, j = _t._onPositionItems.length; + if (!j || !_t.playState || _t._onPositionFired >= j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (!item.fired && _t.position >= item.position) { + item.method.apply(item.scope,[item.position]); + item.fired = true; + _s._onPositionFired++; + } + } + return true; + }; + + this.resetOnPosition = function(nPosition) { + // reset "fired" for items interested in this position + var i, item, j = _t._onPositionItems.length; + if (!j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (item.fired && nPosition <= item.position) { + item.fired = false; + _s._onPositionFired--; + } + } + return true; + }; + + // pseudo-private soundManager reference + + this._onTimer = function(bForce) { + // HTML 5-only _whileplaying() etc. + var time, x = {}; + if (_t._hasTimer || bForce) { + if (_a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { // TODO: May not need to track readyState (1 = loading) + _t.duration = _get_html5_duration(); + _t.durationEstimate = _t.duration; + time = _a.currentTime?_a.currentTime*1000:0; + _t._whileplaying(time,x,x,x,x); + return true; + } else { + //_s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); + return false; + } + } + }; + + // --- private internals --- + + _get_html5_duration = function() { + var d = (_a?_a.duration*1000:undefined); + return (d && !isNaN(d)?d:null); + }; + + _start_html5_timer = function() { + if (_t.isHTML5) { + _startTimer(_t); + } + }; + + _stop_html5_timer = function() { + if (_t.isHTML5) { + _stopTimer(_t); + } + }; + + _resetProperties = function(bLoaded) { + _t._onPositionItems = []; + _t._onPositionFired = 0; + _t._hasTimer = null; + _t._added_events = null; + _t._audio = null; + _a = null; + _t.bytesLoaded = null; + _t.bytesTotal = null; + _t.position = null; + _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null); + _t.durationEstimate = null; + _t.failures = 0; + _t.loaded = false; + _t.playState = 0; + _t.paused = false; + _t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success + _t.muted = false; + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + _t.isBuffering = false; + _t.instanceOptions = {}; + _t.instanceCount = 0; + _t.peakData = { + left: 0, + right: 0 + }; + _t.waveformData = { + left: [], + right: [] + }; + _t.eqData = []; // legacy: 1D array + _t.eqData.left = []; + _t.eqData.right = []; + }; + + _resetProperties(); + + // pseudo-private methods used by soundManager + + this._setup_html5 = function(oOptions) { + var _iO = _mixin(_t._iO, oOptions); + if (_a) { + if (_t.url !== _iO.url) { + //_s._wD('setting new URL on existing object: '+_iO.url); + _a.src = _iO.url; + } + } else { + //_s._wD('creating HTML 5 audio element with URL: '+_iO.url); + _t._audio = new Audio(_iO.url); + _a = _t._audio; + _t.isHTML5 = true; + _add_html5_events(); + } + _a.loop = (_iO.loops>1?'loop':''); + return _t._audio; + }; + + // related private methods + + _add_html5_events = function() { + if (_t._added_events) { + return false; + } + _t._added_events = true; + + function _add(oEvt, oFn, bCapture) { + return (_a ? _a.addEventListener(oEvt, oFn, bCapture||false) : null); + } + + _add('load', function(e) { + //_s._wD('HTML5::load: '+_t.sID); + if (_a) { + _t._onbufferchange(0); + _t._whileloading(_t.bytesTotal, _t.bytesTotal, _get_html5_duration()); + _t._onload(true); + } + }, false); + + _add('canplay', function(e) { + //_s._wD('HTML5::canplay: '+_t.sID); + // enough has loaded to play + _t._onbufferchange(0); + },false); + + _add('waiting', function(e) { + //_s._wD('HTML5::waiting: '+_t.sID); + // playback faster than download rate, etc. + _t._onbufferchange(1); + },false); + + _add('progress', function(e) { // not supported everywhere yet.. + //_s._wD('HTML5::progress: '+_t.sID+': loaded/total: '+(e.loaded||0)+'/'+(e.total||1)); + if (!_t.loaded && _a) { + _t._onbufferchange(0); // if progress, likely not buffering + _t._whileloading(e.loaded||0, e.total||1, _get_html5_duration()); + } + }, false); + + _add('error', function(e) { + if (_a) { + //_s._wD('HTML5::error: '+_a.error.code); + // call load with error state? + _t._onload(false); + } + }, false); + + _add('loadstart', function(e) { + //_s._wD('HTML5::loadstart: '+_t.sID); + // assume buffering at first + _t._onbufferchange(1); + }, false); + + _add('play', function(e) { + //_s._wD('HTML5::play: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + // TODO: verify if this is actually implemented anywhere yet. + _add('playing', function(e) { + //_s._wD('HTML5::playing: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + _add('timeupdate', function(e) { + _t._onTimer(); + }, false); + + // avoid stupid premature event-firing bug in Safari(?) + setTimeout(function(){ + if (_t && _a) { + _add('ended',function(e) { + //_s._wD('HTML5::ended: '+_t.sID); + _t._onfinish(); + }, false); + } + }, 250); + return true; + }; + + // --- "private" methods called by Flash --- + + this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { + _t.bytesLoaded = nBytesLoaded; + _t.bytesTotal = nBytesTotal; + _t.duration = Math.floor(nDuration); + _t.bufferLength = nBufferLength; + if (!_t._iO.isMovieStar) { + if (_t._iO.duration) { + // use options, if specified and larger + _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration; + } else { + _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); + } + if (_t.durationEstimate === undefined) { + _t.durationEstimate = _t.duration; + } + _t.bufferLength = nBufferLength; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } else { + _t.durationEstimate = _t.duration; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } + }; + + this._onid3 = function(oID3PropNames, oID3Data) { + // oID3PropNames: string array (names) + // ID3Data: string array (data) + //_s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.'); + var oData = [], i, j; + for (i = 0, j = oID3PropNames.length; i < j; i++) { + oData[oID3PropNames[i]] = oID3Data[i]; + } + _t.id3 = _mixin(_t.id3, oData); + if (_t._iO.onid3) { + _t._iO.onid3.apply(_t); + } + }; + + this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { + if (isNaN(nPosition) || nPosition === null) { + return false; // Flash may return NaN at times + } + if (_t.playState === 0 && nPosition > 0) { + // invalid position edge case for end/stop + nPosition = 0; + } + _t.position = nPosition; + _t.processOnPosition(); + if (_fV > 8 && !_t.isHTML5) { + if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { + _t.peakData = { + left: oPeakData.leftPeak, + right: oPeakData.rightPeak + }; + } + if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { + _t.waveformData = { + left: oWaveformDataLeft.split(','), + right: oWaveformDataRight.split(',') + }; + } + if (_t._iO.useEQData) { + if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { + var eqLeft = oEQData.leftEQ.split(','); + _t.eqData = eqLeft; + _t.eqData.left = eqLeft; + if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { + _t.eqData.right = oEQData.rightEQ.split(','); + } + } + } + } + if (_t.playState === 1) { + // special case/hack: ensure buffering is false if loading from cache (and not yet started) + if (!_t.isHTML5 && _s.flashVersion === 8 && !_t.position && _t.isBuffering) { + _t._onbufferchange(0); + } + if (_t._iO.whileplaying) { + _t._iO.whileplaying.apply(_t); // flash may call after actual finish + } + if ((_t.loaded || (!_t.loaded && _t._iO.isMovieStar)) && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { + _t._onbeforefinish(); + } + } + return true; + }; + + this._onconnect = function(bSuccess) { + var fN = 'SMSound._onconnect(): '; + bSuccess = (bSuccess === 1); + //_s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); + _t.connected = bSuccess; + if (bSuccess) { + _t.failures = 0; + if (_t._iO.onconnect) { + _t._iO.onconnect.apply(_t,[bSuccess]); + } + // don't play if the sound is being destroyed + if (_idCheck(_t.sID) && (_t.options.autoLoad || _t.getAutoPlay())) { + _t.play(undefined, _t.getAutoPlay()); // only update the play state if auto playing + } + } + }; + + this._onload = function(nSuccess) { + var fN = 'SMSound._onload(): ', loadOK = (nSuccess?true:false); + //_s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2)); + /* + if (!loadOK && !_t.isHTML5) { + if (_s.sandbox.noRemote === true) { + //_s._wD(fN + _str('noNet'), 1); + } + if (_s.sandbox.noLocal === true) { + //_s._wD(fN + _str('noLocal'), 1); + } + } + */ + _t.loaded = loadOK; + _t.readyState = loadOK?3:2; + _t._onbufferchange(0); + if (_t._iO.onload) { + _t._iO.onload.apply(_t, [loadOK]); + } + return true; + }; + + // fire onfailure() only once at most + // at this point we just recreate failed sounds rather than trying to reconnect. + this._onfailure = function(msg, level, code) { + _t.failures++; + //_s._wD('SMSound._onfailure(): "'+_t.sID+'" count '+_t.failures); + if (_t._iO.onfailure && _t.failures === 1) { + _t._iO.onfailure(_t, msg, level, code); + } else { + //_s._wD('SMSound._onfailure(): ignoring'); + } + }; + + this._onbeforefinish = function() { + if (!_t.didBeforeFinish) { + _t.didBeforeFinish = true; + if (_t._iO.onbeforefinish) { + //_s._wD('SMSound._onbeforefinish(): "' + _t.sID + '"'); + _t._iO.onbeforefinish.apply(_t); + } + } + }; + + this._onjustbeforefinish = function(msOffset) { + if (!_t.didJustBeforeFinish) { + _t.didJustBeforeFinish = true; + if (_t._iO.onjustbeforefinish) { + //_s._wD('SMSound._onjustbeforefinish(): "' + _t.sID + '"'); + _t._iO.onjustbeforefinish.apply(_t); + } + } + }; + + // KJV - connect & play time callback from Flash + this._onstats = function(stats) { + if (_t._iO.onstats) { + _t._iO.onstats(_t, stats); + } + }; + + this._onfinish = function() { + // //_s._wD('SMSound._onfinish(): "' + _t.sID + '" got instanceCount '+_t.instanceCount); + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (_t._iO.onbeforefinishcomplete) { + _t._iO.onbeforefinishcomplete.apply(_t); + } + // reset some state items + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + if (_t.instanceCount) { + _t.instanceCount--; + if (!_t.instanceCount) { + // reset instance options + _t.playState = 0; + _t.paused = false; + _t.instanceCount = 0; + _t.instanceOptions = {}; + _stop_html5_timer(); + } + if (!_t.instanceCount || _t._iO.multiShotEvents) { + // fire onfinish for last, or every instance + if (_t._iO.onfinish) { + //_s._wD('SMSound._onfinish(): "' + _t.sID + '"'); + _t._iO.onfinish.apply(_t); + } + } + } + }; + + this._onbufferchange = function(nIsBuffering) { + var fN = 'SMSound._onbufferchange()'; + if (_t.playState === 0) { + // ignore if not playing + return false; + } + if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { + return false; + } + _t.isBuffering = (nIsBuffering === 1); + if (_t._iO.onbufferchange) { + //_s._wD(fN + ': ' + nIsBuffering); + _t._iO.onbufferchange.apply(_t); + } + return true; + }; + + this._ondataerror = function(sError) { + // flash 9 wave/eq data handler + if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish() + //_s._wD('SMSound._ondataerror(): ' + sError); + if (_t._iO.ondataerror) { + _t._iO.ondataerror.apply(_t); + } + } + }; + + }; // SMSound() + + // --- private SM2 internals --- + + _getDocument = function() { + return (_doc.body?_doc.body:(_doc._docElement?_doc.documentElement:_doc.getElementsByTagName('div')[0])); + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _mixin = function(oMain, oAdd) { + // non-destructive merge + var o1 = {}, i, o2, o; + for (i in oMain) { // clone c1 + if (oMain.hasOwnProperty(i)) { + o1[i] = oMain[i]; + } + } + o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd); + for (o in o2) { + if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { + o1[o] = o2[o]; + } + } + return o1; + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + _html5OK = function(iO) { + return ((iO.type?_html5CanPlay({type:iO.type}):false)||_html5CanPlay(iO.url)); + }; + + _html5CanPlay = function(sURL) { + // try to find MIME, test and return truthiness + if (!_s.useHTML5Audio || !_s.hasHTML5) { + return false; + } + var result, mime, fileExt, item, aF = _s.audioFormats; + if (!_html5Ext) { + _html5Ext = []; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + _html5Ext.push(item); + if (aF[item].related) { + _html5Ext = _html5Ext.concat(aF[item].related); + } + } + } + _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')','i'); + } + mime = (typeof sURL.type !== 'undefined'?sURL.type:null); + fileExt = (typeof sURL === 'string'?sURL.toLowerCase().match(_html5Ext):null); // TODO: Strip URL queries, etc. + if (!fileExt || !fileExt.length) { + if (!mime) { + return false; + } + } else { + fileExt = fileExt[0].substr(1); // "mp3", for example + } + if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { + // result known + return _s.html5[fileExt]; + } else { + if (!mime) { + if (fileExt && _s.html5[fileExt]) { + return _s.html5[fileExt]; + } else { + // best-case guess, audio/whatever-dot-filename-format-you're-playing + mime = 'audio/'+fileExt; + } + } + result = _s.html5.canPlayType(mime); + _s.html5[fileExt] = result; + // //_s._wD('canPlayType, found result: '+result); + return result; + } + }; + + _testHTML5 = function() { + if (!_s.useHTML5Audio || typeof Audio === 'undefined') { + return false; + } + var a = (typeof Audio !== 'undefined' ? new Audio():null), item, support = {}, aF, i; + function _cp(m) { + var canPlay, i, j, isOK = false; + if (!a || typeof a.canPlayType !== 'function') { + return false; + } + if (m instanceof Array) { + // iterate through all mime types, return any successes + for (i=0, j=m.length; i<j && !isOK; i++) { + if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) { + isOK = true; + _s.html5[m[i]] = true; + } + } + return isOK; + } else { + canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false); + return (canPlay && (canPlay.match(_s.html5Test)?true:false)); + } + } + // test all registered formats + codecs + aF = _s.audioFormats; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + support[item] = _cp(aF[item].type); + // assign result to related formats, too + if (aF[item] && aF[item].related) { + for (i=0; i<aF[item].related.length; i++) { + _s.html5[aF[item].related[i]] = support[item]; + } + } + } + } + support.canPlayType = (a?_cp:null); + _s.html5 = _mixin(_s.html5, support); + return true; + }; + + _strings = { + /* + notReady: 'Not loaded yet - wait for soundManager.onload()/onready()', + notOK: 'Audio support is not available.', + appXHTML: _sm + '::createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', + spcWmode: _sm + '::createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue', + swf404: _sm + ': Verify that %s is a valid path.', + tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)', + checkSWF: 'See SWF output for more debug info.', + localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', + waitFocus: _sm + ': Special case: Waiting for focus-related event..', + waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', + waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', + needFunction: _sm + '.onready(): Function object expected', + badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', + noMS: 'MovieStar mode not enabled. Exiting.', + currentObj: '--- ' + _sm + '._debug(): Current sound objects ---', + waitEI: _sm + '::initMovie(): Waiting for ExternalInterface call from Flash..', + waitOnload: _sm + ': Waiting for window.onload()', + docLoaded: _sm + ': Document already loaded', + onload: _sm + '::initComplete(): calling soundManager.onload()', + onloadOK: _sm + '.onload() complete', + init: '-- ' + _sm + '::init() --', + didInit: _sm + '::init(): Already called?', + flashJS: _sm + ': Attempting to call Flash from JS..', + noPolling: _sm + ': Polling (whileloading()/whileplaying() support) is disabled.', + secNote: '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', + badRemove: 'Warning: Failed to remove flash movie.', + noPeak: 'Warning: peakData features unsupported for movieStar formats', + shutdown: _sm + '.disable(): Shutting down', + queue: _sm + '.onready(): Queueing handler', + smFail: _sm + ': Failed to initialise.', + smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', + fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..', + fbLoaded: 'Flash loaded', + fbHandler: 'soundManager::flashBlockHandler()', + manURL: 'SMSound.load(): Using manually-assigned URL', + onURL: _sm + '.load(): current URL already assigned.', + badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.', + as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)', + noNSLoop: 'Note: Looping not implemented for MovieStar formats', + needfl9: 'Note: Switching to flash 9, required for MP4 formats.', + mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case', + mfOn: 'mobileFlash::enabling on-screen flash repositioning', + policy: 'Enabling usePolicyFile for data access' + */ + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _str = function() { // o [,items to replace] + /* + var args = _slice.call(arguments), // real array, please + o = args.shift(), // first arg + str = (_strings && _strings[o]?_strings[o]:''), i, j; + if (str && args && args.length) { + for (i = 0, j = args.length; i < j; i++) { + str = str.replace('%s', args[i]); + } + } + return str; + */ + }; + + _loopFix = function(sOpt) { + // flash 8 requires stream = false for looping to work + if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { + //_wDS('as2loop'); + sOpt.stream = false; + } + return sOpt; + }; + + _policyFix = function(sOpt, sPre) { + if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { + //_s._wD((sPre?sPre+':':'') + _str('policy')); + sOpt.usePolicyFile = true; + } + return sOpt; + }; + + _complain = function(sMsg) { + if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + console.warn(sMsg); + } else { + //_s._wD(sMsg); + } + }; + + _doNothing = function() { + return false; + }; + + _disableObject = function(o) { + for (var oProp in o) { + if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { + o[oProp] = _doNothing; + } + } + oProp = null; + }; + + _failSafely = function(bNoDisable) { + // general failure exception handler + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled || bNoDisable) { + //_wDS('smFail', 2); + _s.disable(bNoDisable); + } + }; + + _normalizeMovieURL = function(smURL) { + var urlParams = null; + if (smURL) { + if (smURL.match(/\.swf(\?\.*)?$/i)) { + urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4); + if (urlParams) { + return smURL; // assume user knows what they're doing + } + } else if (smURL.lastIndexOf('/') !== smURL.length - 1) { + smURL = smURL + '/'; + } + } + return (smURL && smURL.lastIndexOf('/') !== - 1?smURL.substr(0, smURL.lastIndexOf('/') + 1):'./') + _s.movieURL; + }; + + _setVersionInfo = function() { + if (_fV !== 8 && _fV !== 9) { + //_s._wD(_str('badFV', _fV, _defaultFlashVersion)); + _s.flashVersion = _defaultFlashVersion; + } + var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); // debug flash movie, if applicable + if (_s.flashVersion < 9 && _s.useHTML5Audio && _s.audioFormats.mp4.required) { + //_s._wD(_str('needfl9')); + _s.flashVersion = 9; + } + _fV = _s.flashVersion; // short-hand for internal use + _s.version = _s.versionNumber + (_html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); + // set up default options + if (_fV > 8) { + _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); + _s.features.buffering = true; + } + if (_fV > 8 && _s.useMovieStar) { + // flash 9+ support for movieStar formats as well as MP3 + _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); + _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _s.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + _s.mimePattern = _s.netStreamMimeTypes; + _s.features.movieStar = true; + } else { + _s.features.movieStar = false; + } + _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; + _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf',isDebug); + _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); + }; + + _setPolling = function(bPolling, bHighPerformance) { + if (!_s.o || !_s.allowPolling) { + return false; + } + _s.o._setPolling(bPolling, bHighPerformance); + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + function _initDebug() { + if (_s.debugURLParam.test(_wl)) { + _s.debugMode = true; // allow force of debug mode via URL + } + /* + if (_id(_s.debugID)) { + return false; + } + var oD, oDebug, oTarget, oToggle, tmp; + if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) { + oD = _doc.createElement('div'); + oD.id = _s.debugID + '-toggle'; + oToggle = { + 'position': 'fixed', + 'bottom': '0px', + 'right': '0px', + 'width': '1.2em', + 'height': '1.2em', + 'lineHeight': '1.2em', + 'margin': '2px', + 'textAlign': 'center', + 'border': '1px solid #999', + 'cursor': 'pointer', + 'background': '#fff', + 'color': '#333', + 'zIndex': 10001 + }; + oD.appendChild(_doc.createTextNode('-')); + oD.onclick = _toggleDebug; + oD.title = 'Toggle SM2 debug console'; + if (_ua.match(/msie 6/i)) { + oD.style.position = 'absolute'; + oD.style.cursor = 'hand'; + } + for (tmp in oToggle) { + if (oToggle.hasOwnProperty(tmp)) { + oD.style[tmp] = oToggle[tmp]; + } + } + oDebug = _doc.createElement('div'); + oDebug.id = _s.debugID; + oDebug.style.display = (_s.debugMode?'block':'none'); + if (_s.debugMode && !_id(oD.id)) { + try { + oTarget = _getDocument(); + oTarget.appendChild(oD); + } catch(e2) { + throw new Error(_str('appXHTML')); + } + oTarget.appendChild(oDebug); + } + } + oTarget = null; + */ + } + + _mobileFlash = (function(){ + + var oM = null; + + function resetPosition() { + if (oM) { + oM.left = oM.top = '-9999px'; + } + } + + function reposition() { + oM.left = _win.scrollX+'px'; + oM.top = _win.scrollY+'px'; + } + + function setReposition(bOn) { + //_s._wD('mobileFlash::flash on-screen hack: '+(bOn?'ON':'OFF')); + var f = _win[(bOn?'add':'remove')+'EventListener']; + f('resize', reposition, false); + f('scroll', reposition, false); + } + + function check(inDoc) { + // mobile flash (Android for starters) check + oM = _s.oMC.style; + if (_ua.match(/android/i)) { + if (inDoc) { + if (_s.flashLoadTimeout) { + _s.//_wDS('mfTimeout'); + _s.flashLoadTimeout = 0; + } + return false; + } + //_s._wD('mfOn'); + oM.position = 'absolute'; + oM.left = oM.top = '0px'; + setReposition(true); + _s.onready(function(){ + setReposition(false); // detach + resetPosition(); // restore when OK/timed out + }); + reposition(); + } + return true; + } + + return { + 'check': check + }; + + }()); + + _createMovie = function(smID, smURL) { + + var specialCase = null, + remoteURL = (smURL?smURL:_s.url), + localURL = (_s.altURL?_s.altURL:remoteURL), + oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(), s, x, sClass, side = '100%', isRTL = null, html = _doc.getElementsByTagName('html')[0]; + isRTL = (html && html.dir && html.dir.match(/rtl/i)); + smID = (typeof smID === 'undefined'?_s.id:smID); + + if (_didAppend && _appendSuccess) { + return false; // ignore if already succeeded + } + + function _initMsg() { + //_s._wD('-- SoundManager 2 ' + _s.version + (!_html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (_s.useMovieStar?', MovieStar mode':'') + (_s.useHighPerformance?', high performance mode, ':', ') + ((_s.useFastPolling?'fast':'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') + ' --', 1); + } + + if (_html5Only) { + _setVersionInfo(); + _initMsg(); + _s.oMC = _id(_s.movieID); + _init(); + // prevent multiple init attempts + _didAppend = true; + _appendSuccess = true; + return false; + } + + _didAppend = true; + + // safety check for legacy (change to Flash 9 URL) + _setVersionInfo(); + _s.url = _normalizeMovieURL(this._overHTTP?remoteURL:localURL); + smURL = _s.url; + + _s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); + + if (_s.wmode !== null && !_isIE && !_s.useHighPerformance && navigator.platform.match(/win32/i)) { + _s.specialWmodeCase = true; + // extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here + // does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout + //_wDS('spcWmode'); + _s.wmode = null; + } + + oEmbed = { + 'name': smID, + 'id': smID, + 'src': smURL, + 'width': side, + 'height': side, + 'quality': 'high', + 'allowScriptAccess': _s.allowScriptAccess, + 'bgcolor': _s.bgColor, + 'pluginspage': 'http://www.macromedia.com/go/getflashplayer', + 'type': 'application/x-shockwave-flash', + 'wmode': _s.wmode + }; + + if (_s.debugFlash) { + oEmbed.FlashVars = 'debug=1'; + } + + if (!_s.wmode) { + delete oEmbed.wmode; // don't write empty attribute + } + + if (_isIE) { + // IE is "special". + oMovie = _doc.createElement('div'); + movieHTML = '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" width="' + oEmbed.width + '" height="' + oEmbed.height + '"><param name="movie" value="' + smURL + '" /><param name="AllowScriptAccess" value="' + _s.allowScriptAccess + '" /><param name="quality" value="' + oEmbed.quality + '" />' + (_s.wmode?'<param name="wmode" value="' + _s.wmode + '" /> ':'') + '<param name="bgcolor" value="' + _s.bgColor + '" />' + (_s.debugFlash?'<param name="FlashVars" value="' + oEmbed.FlashVars + '" />':'') + '<!-- --></object>'; + } else { + oMovie = _doc.createElement('embed'); + for (tmp in oEmbed) { + if (oEmbed.hasOwnProperty(tmp)) { + oMovie.setAttribute(tmp, oEmbed[tmp]); + } + } + } + + _initDebug(); + extraClass = _getSWFCSS(); + oTarget = _getDocument(); + + if (oTarget) { + _s.oMC = _id(_s.movieID)?_id(_s.movieID):_doc.createElement('div'); + if (!_s.oMC.id) { + _s.oMC.id = _s.movieID; + _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass; + // "hide" flash movie + s = null; + oEl = null; + if (!_s.useFlashBlock) { + if (_s.useHighPerformance) { + s = { + 'position': 'fixed', + 'width': '8px', + 'height': '8px', + // >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes. + 'bottom': '0px', + 'left': '0px', + 'overflow': 'hidden' + }; + } else { + s = { + 'position': 'absolute', + 'width': '6px', + 'height': '6px', + 'top': '-9999px', + 'left': '-9999px' + }; + if (isRTL) { + s.left = Math.abs(parseInt(s.left,10))+'px'; + } + } + } + if (_ua.match(/webkit/i)) { + _s.oMC.style.zIndex = 10000; // soundcloud-reported render/crash fix, safari 5 + } + if (!_s.debugFlash) { + for (x in s) { + if (s.hasOwnProperty(x)) { + _s.oMC.style[x] = s[x]; + } + } + } + try { + if (!_isIE) { + _s.oMC.appendChild(oMovie); + } + oTarget.appendChild(_s.oMC); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + } catch(e) { + throw new Error(_str('appXHTML')); + } + _mobileFlash.check(); + } else { + // it's already in the document. + sClass = _s.oMC.className; + _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:''); + _s.oMC.appendChild(oMovie); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + _mobileFlash.check(true); + } + } + + if (specialCase) { + //_s._wD(specialCase); + } + + _initMsg(); + //_s._wD('soundManager::createMovie(): Trying to load ' + smURL + (!this._overHTTP && _s.altURL?' (alternate URL)':''), 1); + + return true; + }; + + _idCheck = this.getSoundById; + + _initMovie = function() { + if (_html5Only) { + _createMovie(); + return false; + } + // attempt to get, or create, movie + if (_s.o) { + return false; // may already exist + } + _s.o = _s.getMovie(_s.id); // inline markup + if (!_s.o) { + if (!_oRemoved) { + // try to create + _createMovie(_s.id, _s.url); + } else { + // try to re-append removed movie after reboot() + if (!_isIE) { + _s.oMC.appendChild(_oRemoved); + } else { + _s.oMC.innerHTML = _oRemovedHTML; + } + _oRemoved = null; + _didAppend = true; + } + _s.o = _s.getMovie(_s.id); + } + if (_s.o) { + //_s._wD('soundManager::initMovie(): Got '+_s.o.nodeName+' element ('+(_didAppend?'created via JS':'static HTML')+')'); + //_wDS('waitEI'); + } + if (_s.oninitmovie instanceof Function) { + setTimeout(_s.oninitmovie, 1); + } + return true; + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + _delayWaitForEI = function() { + setTimeout(_waitForEI, 500); + }; + + _waitForEI = function() { + if (_waitingForEI) { + return false; + } + _waitingForEI = true; + _removeEvt(_win, 'load', _delayWaitForEI); + if (_tryInitOnFocus && !_isFocused) { + //_wDS('waitFocus'); + return false; + } + var p; + if (!_didInit) { + p = _s.getMoviePercent(); + //_s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':'')))); + } + setTimeout(function() { + p = _s.getMoviePercent(); + if (!_didInit) { + //_s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2); + if (!this._overHTTP && p) { + //_wDS('localFail', 2); + if (!_s.debugFlash) { + //_wDS('tryDebug', 2); + } + } + if (p === 0) { + // if 0 (not null), probably a 404. + //_s._wD(_str('swf404', _s.url)); + } + //_debugTS('flashtojs', false, ': Timed out' + this._overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); + } + // give up / time-out, depending + if (!_didInit && _okToDisable) { + if (p === null) { + // SWF failed. Maybe blocked. + if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + //_wDS('waitForever'); + } else { + // old SM2 behaviour, simply fail + _failSafely(true); + } + } else { + // flash loaded? Shouldn't be a blocking issue, then. + if (_s.flashLoadTimeout === 0) { + //_wDS('waitForever'); + } else { + _failSafely(true); + } + } + } + }, _s.flashLoadTimeout); + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + /* + _wDS = function(o, errorLevel) { + if (!o) { + return ''; + } else { + return //_s._wD(_str(o), errorLevel); + } + }; + + if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { + _s._wD = function(sText) {alert(sText);}; + } + + _toggleDebug = function() { + var o = _id(_s.debugID), + oT = _id(_s.debugID + '-toggle'); + if (!o) { + return false; + } + if (_debugOpen) { + // minimize + oT.innerHTML = '+'; + o.style.display = 'none'; + } else { + oT.innerHTML = '-'; + o.style.display = 'block'; + } + _debugOpen = !_debugOpen; + }; + + _debugTS = function(sEventType, bSuccess, sMessage) { + // troubleshooter debug hooks + if (typeof sm2Debugger !== 'undefined') { + try { + sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); + } catch(e) { + // oh well + } + } + return true; + }; + */ + + _getSWFCSS = function() { + var css = []; + if (_s.debugMode) { + css.push(_s.swfCSS.sm2Debug); + } + if (_s.debugFlash) { + css.push(_s.swfCSS.flashDebug); + } + if (_s.useHighPerformance) { + css.push(_s.swfCSS.highPerf); + } + return css.join(' '); + }; + + _flashBlockHandler = function() { + // *possible* flash block situation. + var name = _str('fbHandler'), p = _s.getMoviePercent(); + if (!_s.supported()) { + if (_needsFlash) { + // make the movie more visible, so user can fix + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + ' ' + (p === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + //_s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':'')); + } + _s.didFlashBlock = true; + _processOnReady(true); // fire onready(), complain lightly + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + } else { + // SM2 loaded OK (or recovered) + if (_s.didFlashBlock) { + //_s._wD(name+': Unblocked'); + } + if (_s.oMC) { + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + (' '+_s.swfCSS.swfUnblocked); + } + } + }; + + _handleFocus = function() { + function cleanup() { + _removeEvt(_win, 'focus', _handleFocus); + _removeEvt(_win, 'load', _handleFocus); + } + if (_isFocused || !_tryInitOnFocus) { + cleanup(); + return true; + } + _okToDisable = true; + _isFocused = true; + //_s._wD('soundManager::handleFocus()'); + if (_isSafari && _tryInitOnFocus) { + // giant Safari 3.1 hack - assume mousemove = focus given lack of focus event + _removeEvt(_win, 'mousemove', _handleFocus); + } + // allow init to restart + _waitingForEI = false; + cleanup(); + return true; + }; + + _initComplete = function(bNoDisable) { + if (_didInit) { + return false; + } + if (_html5Only) { + // all good. + //_s._wD('-- SoundManager 2: loaded --'); + _didInit = true; + _processOnReady(); + _initUserOnload(); + return true; + } + var sClass = _s.oMC.className, + wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()); + if (!wasTimeout) { + _didInit = true; + } + //_s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1); + if (_disabled || bNoDisable) { + if (_s.useFlashBlock) { + _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + } + _processOnReady(); + //_debugTS('onload', false); + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + return false; + } else { + //_debugTS('onload', true); + } + if (_s.waitForWindowLoad && !_windowLoaded) { + //_wDS('waitOnload'); + _addEvt(_win, 'load', _initUserOnload); + return false; + } else { + if (_s.waitForWindowLoad && _windowLoaded) { + //_wDS('docLoaded'); + } + _initUserOnload(); + } + return true; + }; + + _addOnReady = function(oMethod, oScope) { + _onready.push({ + 'method': oMethod, + 'scope': (oScope || null), + 'fired': false + }); + }; + + _processOnReady = function(ignoreInit) { + if (!_didInit && !ignoreInit) { + // not ready yet. + return false; + } + var status = { + success: (ignoreInit?_s.supported():!_disabled) + }, + queue = [], i, j, + canRetry = (!_s.useFlashBlock || (_s.useFlashBlock && !_s.supported())); + for (i = 0, j = _onready.length; i < j; i++) { + if (_onready[i].fired !== true) { + queue.push(_onready[i]); + } + } + if (queue.length) { + //_s._wD(_sm + ': Firing ' + queue.length + ' onready() item' + (queue.length > 1?'s':'')); + for (i = 0, j = queue.length; i < j; i++) { + if (queue[i].scope) { + queue[i].method.apply(queue[i].scope, [status]); + } else { + queue[i].method(status); + } + if (!canRetry) { // flashblock case doesn't count here + queue[i].fired = true; + } + } + } + return true; + }; + + _initUserOnload = function() { + _win.setTimeout(function() { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + _processOnReady(); + //_wDS('onload', 1); + // call user-defined "onload", scoped to window + if (_s.onload instanceof Function) { + _s.onload.apply(_win); + } + //_wDS('onloadOK', 1); + if (_s.waitForWindowLoad) { + _addEvt(_win, 'load', _initUserOnload); + } + },1); + }; + + _featureCheck = function() { + var needsFlash, item, + isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_(3|4)/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" bug. https://bugs.webkit.org/show_bug.cgi?id=32159 + isSpecial = (_ua.match(/iphone os (1|2|3_0|3_1)/i)?true:false); // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works. + if (isSpecial) { + _s.hasHTML5 = false; // has Audio(), but is broken; let it load links directly. + _html5Only = true; // ignore flash case, however + if (_s.oMC) { + _s.oMC.style.display = 'none'; + } + return false; + } + if (_s.useHTML5Audio) { + if (!_s.html5 || !_s.html5.canPlayType) { + //_s._wD('SoundManager: No HTML5 Audio() support detected.'); + _s.hasHTML5 = false; + return true; + } else { + _s.hasHTML5 = true; + } + if (isBadSafari) { + //_s._wD('SoundManager::Note: Buggy HTML5 Audio in Safari on OS X 10.6.[3|4], see https://bugs.webkit.org/show_bug.cgi?id=32159 - disabling HTML5 audio',1); + _s.useHTML5Audio = false; + _s.hasHTML5 = false; + return true; + } + } else { + // flash required. + return true; + } + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item) && _s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) { + // may need flash for this format? + needsFlash = true; + } + } + // sanity check.. + if (_s.ignoreFlash) { + needsFlash = false; + } + _html5Only = (_s.useHTML5Audio && _s.hasHTML5 && !needsFlash); + return needsFlash; + }; + + _init = function() { + var item, tests = []; + //_wDS('init'); + + // called after onload() + if (_didInit) { + //_wDS('didInit'); + return false; + } + + function _cleanup() { + _removeEvt(_win, 'load', _s.beginDelayedInit); + } + + if (_s.hasHTML5) { + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item)) { + tests.push(item+': '+_s.html5[item]); + } + } + //_s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); + } + + if (_html5Only) { + if (!_didInit) { + // we don't need no steenking flash! + _cleanup(); + _s.enabled = true; + _initComplete(); + } + return true; + } + + // flash path + _initMovie(); + try { + //_wDS('flashJS'); + _s.o._externalInterfaceTest(false); // attempt to talk to Flash + if (!_s.allowPolling) { + //_wDS('noPolling', 1); + } else { + _setPolling(true, _s.useFastPolling?true:false); + } + if (!_s.debugMode) { + _s.o._disableDebug(); + } + _s.enabled = true; + //_debugTS('jstoflash', true); + } catch(e) { + //_s._wD('js/flash exception: ' + e.toString()); + //_debugTS('jstoflash', false); + _failSafely(true); // don't disable, for reboot() + _initComplete(); + return false; + } + _initComplete(); + // event cleanup + _cleanup(); + return true; + }; + + _beginInit = function() { + if (_initPending) { + return false; + } + _createMovie(); + _initMovie(); + _initPending = true; + return true; + }; + + _dcLoaded = function() { + if (_didDCLoaded) { + return false; + } + _didDCLoaded = true; + _initDebug(); + _testHTML5(); + _s.html5.usingFlash = _featureCheck(); + _needsFlash = _s.html5.usingFlash; + _didDCLoaded = true; + if (_doc.removeEventListener) { + _doc.removeEventListener('DOMContentLoaded', _dcLoaded, false); + } + _go(); + return true; + }; + + _startTimer = function(oSound) { + if (!oSound._hasTimer) { + oSound._hasTimer = true; + } + }; + + _stopTimer = function(oSound) { + if (oSound._hasTimer) { + oSound._hasTimer = false; + } + }; + + _die = function() { + if (_s.onerror instanceof Function) { + _s.onerror(); + } + _s.disable(); + }; + + // pseudo-private methods called by Flash + + this._setSandboxType = function(sandboxType) { + /* + var sb = _s.sandbox; + sb.type = sandboxType; + sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')]; + //_s._wD('Flash security sandbox type: ' + sb.type); + if (sb.type === 'localWithFile') { + sb.noRemote = true; + sb.noLocal = false; + //_wDS('secNote', 2); + } else if (sb.type === 'localWithNetwork') { + sb.noRemote = false; + sb.noLocal = true; + } else if (sb.type === 'localTrusted') { + sb.noRemote = false; + sb.noLocal = false; + } + */ + }; + + this._externalInterfaceOK = function(flashDate) { + // flash callback confirming flash loaded, EI working etc. + // flashDate = approx. timing/delay info for JS/flash bridge + if (_s.swfLoaded) { + return false; + } + var eiTime = new Date().getTime(); + //_s._wD('soundManager::externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); + //_debugTS('swf', true); + //_debugTS('flashtojs', true); + _s.swfLoaded = true; + _tryInitOnFocus = false; + if (_isIE) { + // IE needs a timeout OR delay until window.onload - may need TODO: investigating + setTimeout(_init, 100); + } else { + _init(); + } + }; + + _dcIE = function() { + if (_doc.readyState === 'complete') { + _dcLoaded(); + _doc.detachEvent('onreadystatechange', _dcIE); + } + return true; + }; + + // focus and window load, init + if (!_s.hasHTML5 || _needsFlash) { + // only applies to Flash mode + _addEvt(_win, 'focus', _handleFocus); + _addEvt(_win, 'load', _handleFocus); + _addEvt(_win, 'load', _delayWaitForEI); + if (_isSafari && _tryInitOnFocus) { + _addEvt(_win, 'mousemove', _handleFocus); // massive Safari focus hack + } + } + + if (_doc.addEventListener) { + _doc.addEventListener('DOMContentLoaded', _dcLoaded, false); + } else if (_doc.attachEvent) { + _doc.attachEvent('onreadystatechange', _dcIE); + } else { + // no add/attachevent support - safe to assume no JS -> Flash either + //_debugTS('onload', false); + _die(); + } + + if (_doc.readyState === 'complete') { + setTimeout(_dcLoaded,100); + } + +} // SoundManager() + +// var SM2_DEFER = true; +// details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading + +if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { + soundManager = new SoundManager(); +} + +// public interfaces +window.SoundManager = SoundManager; // constructor +window.soundManager = soundManager; // public instance: API, Flash callbacks etc. + +}(window)); diff --git a/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2.js b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2.js new file mode 100755 index 0000000..46528c9 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/script/soundmanager2.js @@ -0,0 +1,2838 @@ +/** @license + * SoundManager 2: Javascript Sound for the Web + * -------------------------------------------- + * http://schillmania.com/projects/soundmanager2/ + * + * Copyright (c) 2007, Scott Schiller. All rights reserved. + * Code provided under the BSD License: + * http://schillmania.com/projects/soundmanager2/license.txt + * + * V2.97a.20101010 + */ + +/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: true, newcap: true, immed: true, regexp: false */ +/*global window, SM2_DEFER, sm2Debugger, alert, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ + +(function(window) { + +var soundManager = null; + +function SoundManager(smURL, smID) { + + this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. + this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available+configured) + this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues + this.useConsole = true; // use firebug/safari console.log()-type debug console if available + this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug + this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() + this.nullURL = 'about:blank'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) + this.allowPolling = true; // allow flash to poll for status update (required for whileplaying() events, peak, sound spectrum functions to work.) + this.useFastPolling = false; // uses lower flash timer interval for higher callback frequency, best combined with useHighPerformance + this.useMovieStar = true; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio formats (AAC, M4V, FLV, MOV etc.) + this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000' + this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag + this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity) + this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top) + this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain' + this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable. + this.useHTML5Audio = false; // Beta feature: Use HTML 5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible. + this.html5Test = /^probably$/i; // HTML5 Audio().canPlayType() test. /^(probably|maybe)$/i if you want to be more liberal/risky. + this.ondebuglog = false; // callback made with each log message, regardless of debugMode + + this.audioFormats = { + // determines HTML5 support, flash requirements + // eg. if MP3 or MP4 required, Flash fallback is used if HTML5 can't play it + // shotgun approach to MIME testing due to browser variance + 'mp3': { + 'type': ['audio/mpeg; codecs="mp3"','audio/mpeg','audio/mp3','audio/MPA','audio/mpa-robust'], + 'required': true + }, + 'mp4': { + 'related': ['aac','m4a'], // additional formats under the MP4 container + 'type': ['audio/mp4; codecs="mp4a.40.2"','audio/aac','audio/x-m4a','audio/MP4A-LATM','audio/mpeg4-generic'], + 'required': true + }, + 'ogg': { + 'type': ['audio/ogg; codecs=vorbis'], + 'required': false + }, + 'wav': { + 'type': ['audio/wav; codecs="1"','audio/wav','audio/wave','audio/x-wav'], + 'required': false + } + }; + + this.defaultOptions = { + '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) + 'stream': true, // allows playing before entire file has loaded (recommended) + 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) + 'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0) + 'onid3': null, // callback function for "ID3 data is added/available" + 'onload': null, // callback function for "load finished" + 'whileloading': null, // callback function for "download progress update" (X of Y bytes received) + 'onplay': null, // callback for "play" start + 'onpause': null, // callback for "pause" + 'onresume': null, // callback for "resume" (pause toggle) + 'whileplaying': null, // callback during play (position update) + 'onstop': null, // callback for "user stop" + 'onfailure': null, // callback function for when playing fails + 'onfinish': null, // callback function for "sound finished playing" + 'onbeforefinish': null, // callback for "before sound finished playing (at [time])" + 'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) + 'onbeforefinishcomplete': null,// function to call when said sound finishes playing + 'onjustbeforefinish': null, // callback for [n] msec before end of current sound + 'onjustbeforefinishtime': 200, // [n] - if not using, set to 0 (or null handler) and event will not fire. + 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time + 'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled + 'position': null, // offset (milliseconds) to seek to within loaded sound data. + 'pan': 0, // "pan" settings, left-to-right, -100 to 100 + 'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3 + 'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access) + 'volume': 100 // self-explanatory. 0-100, the latter being the max. + }; + + this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used + 'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL + 'usePeakData': false, // enable left/right channel peak (level) data + 'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. + 'useEQData': false, // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. + 'onbufferchange': null, // callback for "isBuffering" property change + 'ondataerror': null, // callback for waveform/eq data access error (flash playing audio in other tabs/domains) + 'onstats': null // callback for when connection & play times have been measured + }; + + this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio options, merged into defaultOptions if flash 9+movieStar mode is enabled + 'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.) + 'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants + 'onconnect': null, // rtmp: callback for connection to flash media server + 'bufferTimes': null, // array of buffer sizes to use. Size increases as buffer fills up. + 'duration': null // rtmp: song duration (msec) + }; + + this.version = null; + this.versionNumber = 'V2.97a.20101010'; + this.movieURL = null; + this.url = (smURL || null); + this.altURL = null; + this.swfLoaded = false; + this.enabled = false; + this.o = null; + this.movieID = 'sm2-container'; + this.id = (smID || 'sm2movie'); + this.swfCSS = { + 'swfBox': 'sm2-object-box', + 'swfDefault': 'movieContainer', + 'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error) + 'swfTimedout': 'swf_timedout', + 'swfUnblocked': 'swf_unblocked', // or loaded OK + 'sm2Debug': 'sm2_debug', + 'highPerf': 'high_performance', + 'flashDebug': 'flash_debug' + }; + this.oMC = null; + this.sounds = {}; + this.soundIDs = []; + this.muted = false; + this.debugID = 'soundmanager-debug'; + this.debugURLParam = /([#?&])debug=1/i; + this.specialWmodeCase = false; + this.didFlashBlock = false; + + this.filePattern = null; + this.filePatterns = { + 'flash8': /\.mp3(\?.*)?$/i, + 'flash9': /\.mp3(\?.*)?$/i + }; + + this.baseMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3 + this.netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3, mp4, aac etc. + this.netStreamTypes = ['aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2']; // Flash v9.0r115+ "moviestar" formats + this.netStreamPattern = new RegExp('\\.(' + this.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + this.mimePattern = this.baseMimeTypes; + + this.features = { + 'buffering': false, + 'peakData': false, + 'waveformData': false, + 'eqData': false, + 'movieStar': false + }; + + this.sandbox = { + // <d> + '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 + // </d> + }; + + this.hasHTML5 = null; // switch for handling logic + this.html5 = { // stores canPlayType() results, etc. treat as read-only. + // mp3: boolean + // mp4: boolean + 'usingFlash': null // set if/when flash fallback is needed + }; + this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?) + + // --- private SM2 internals --- + + var SMSound, + _s = this, _sm = 'soundManager', _id, _ua = navigator.userAgent, _wl = window.location.href.toString(), _fV = this.flashVersion, _doc = document, _win = window, _doNothing, _init, _onready = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnReady, _processOnReady, _initUserOnload, _go, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _beginInit, _strings, _initMovie, _dcLoaded, _didDCLoaded, _getDocument, _createMovie, _die, _mobileFlash, _setPolling, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5Only = false, _html5CanPlay, _html5Ext, _dcIE, _testHTML5, _addEvt, _removeEvt, _slice = Array.prototype.slice, + _is_pre = _ua.match(/pre\//i), + _iPadOrPhone = _ua.match(/(ipad|iphone)/i), + _isMobile = (_ua.match(/mobile/i) || _is_pre || _iPadOrPhone), + _isIE = (_ua.match(/MSIE/i)), + _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), + _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), + _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), + _tryInitOnFocus = (typeof _doc.hasFocus === 'undefined' && _isSafari), + _okToDisable = !_tryInitOnFocus; + + this._use_maybe = (_wl.match(/sm2\-useHTML5Maybe\=1/i)); // temporary feature: #sm2-useHTML5Maybe=1 forces loose canPlay() check + this._overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null); + this.useAltURL = !this._overHTTP; // use altURL if not "online" + + if (_iPadOrPhone || _is_pre) { + // might as well force it on Apple + Palm, flash support unlikely + _s.useHTML5Audio = true; + _s.ignoreFlash = true; + } + + if (_is_pre || this._use_maybe) { + // less-strict canPlayType() checking option + _s.html5Test = /^(probably|maybe)$/i; + } + + // Temporary feature: allow force of HTML5 via URL: #sm2-usehtml5audio=0 or 1 + // <d> + (function(){ + var a = '#sm2-usehtml5audio=', l = _wl, b = null; + if (l.indexOf(a) !== -1) { + b = (l.substr(l.indexOf(a)+a.length) === '1'); + if (typeof console !== 'undefined' && typeof console.log !== 'undefined') { + console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); + } + _s.useHTML5Audio = b; + } + }()); + // </d> + + // --- public API methods --- + + this.supported = function() { + return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); + }; + + this.getMovie = function(smID) { + return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); + }; + + this.loadFromXML = function(sXmlUrl) { + try { + _s.o._loadFromXML(sXmlUrl); + } catch(e) { + _failSafely(); + } + return true; + }; + + this.createSound = function(oOptions) { + var _cs = 'soundManager.createSound(): ', + thisOptions = null, oSound = null, _tO = null; + if (!_didInit || !_s.supported()) { + _complain(_cs + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (arguments.length === 2) { + // function overloading in JS! :) ..assume simple createSound(id,url) use case + oOptions = { + 'id': arguments[0], + 'url': arguments[1] + }; + } + thisOptions = _mixin(oOptions); // inherit from defaultOptions + _tO = thisOptions; // alias + // <d> + if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { + _s._wD(_cs + _str('badID', _tO.id), 2); + } + _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); + // </d> + if (_idCheck(_tO.id, true)) { + _s._wD(_cs + _tO.id + ' exists', 1); + return _s.sounds[_tO.id]; + } + + function make() { + thisOptions = _loopFix(thisOptions); + _s.sounds[_tO.id] = new SMSound(_tO); + _s.soundIDs.push(_tO.id); + return _s.sounds[_tO.id]; + } + + if (_html5OK(_tO)) { + oSound = make(); + _s._wD('Loading sound '+_tO.id+' from HTML5'); + oSound._setup_html5(_tO); + } else { + if (_fV > 8 && _s.useMovieStar) { + if (_tO.isMovieStar === null) { + _tO.isMovieStar = ((_tO.serverURL || (_tO.type?_tO.type.match(_s.netStreamPattern):false)||_tO.url.match(_s.netStreamPattern))?true:false); + } + if (_tO.isMovieStar) { + _s._wD(_cs + 'using MovieStar handling'); + } + if (_tO.isMovieStar) { + if (_tO.usePeakData) { + _wDS('noPeak'); + _tO.usePeakData = false; + } + if (_tO.loops > 1) { + _wDS('noNSLoop'); + } + } + } + _tO = _policyFix(_tO, _cs); + oSound = make(); + if (_fV === 8) { + _s.o._createSound(_tO.id, _tO.onjustbeforefinishtime, _tO.loops||1, _tO.usePolicyFile); + } else { + _s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.bufferTimes, _tO.onstats ? true : false, _tO.autoLoad, _tO.usePolicyFile); + if (!_tO.serverURL) { + // We are connected immediately + oSound.connected = true; + if (_tO.onconnect) { + _tO.onconnect.apply(oSound); + } + } + } + } + if (_tO.autoLoad || _tO.autoPlay) { + if (oSound) { + if (_s.isHTML5) { + oSound.autobuffer = 'auto'; // early HTML5 implementation (non-standard) + oSound.preload = 'auto'; // standard + } else { + oSound.load(_tO); + } + } + } + if (_tO.autoPlay) { + oSound.play(); + } + return oSound; + }; + + this.destroySound = function(sID, _bFromSound) { + // explicitly destroy a sound before normal page unload, etc. + if (!_idCheck(sID)) { + return false; + } + var oS = _s.sounds[sID], i; + oS._iO = {}; // Disable all callbacks while the sound is being destroyed + oS.stop(); + oS.unload(); + for (i = 0; i < _s.soundIDs.length; i++) { + if (_s.soundIDs[i] === sID) { + _s.soundIDs.splice(i, 1); + break; + } + } + if (!_bFromSound) { + // ignore if being called from SMSound instance + oS.destruct(true); + } + oS = null; + delete _s.sounds[sID]; + return true; + }; + + this.load = function(sID, oOptions) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].load(oOptions); + }; + + this.unload = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].unload(); + }; + + this.play = function(sID, oOptions) { + var fN = 'soundManager.play(): '; + if (!_didInit || !_s.supported()) { + _complain(fN + _str(!_didInit?'notReady':'notOK')); + return false; + } + if (!_idCheck(sID)) { + if (!(oOptions instanceof Object)) { + oOptions = { + url: oOptions + }; // overloading use case: play('mySound','/path/to/some.mp3'); + } + if (oOptions && oOptions.url) { + // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); + _s._wD(fN + 'attempting to create "' + sID + '"', 1); + oOptions.id = sID; + return _s.createSound(oOptions).play(); + } else { + return false; + } + } + return _s.sounds[sID].play(oOptions); + }; + + this.start = this.play; // just for convenience + + this.setPosition = function(sID, nMsecOffset) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPosition(nMsecOffset); + }; + + this.stop = function(sID) { + if (!_idCheck(sID)) { + return false; + } + _s._wD('soundManager.stop(' + sID + ')', 1); + return _s.sounds[sID].stop(); + }; + + this.stopAll = function() { + _s._wD('soundManager.stopAll()', 1); + for (var oSound in _s.sounds) { + if (_s.sounds[oSound] instanceof SMSound) { + _s.sounds[oSound].stop(); // apply only to sound objects + } + } + }; + + this.pause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].pause(); + }; + + this.pauseAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].pause(); + } + }; + + this.resume = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].resume(); + }; + + this.resumeAll = function() { + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].resume(); + } + }; + + this.togglePause = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].togglePause(); + }; + + this.setPan = function(sID, nPan) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPan(nPan); + }; + + this.setVolume = function(sID, nVol) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setVolume(nVol); + }; + + this.mute = function(sID) { + var fN = 'soundManager.mute(): ', + i = 0; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + _s._wD(fN + 'Muting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].mute(); + } + _s.muted = true; + } else { + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Muting "' + sID + '"'); + return _s.sounds[sID].mute(); + } + return true; + }; + + this.muteAll = function() { + _s.mute(); + }; + + this.unmute = function(sID) { + var fN = 'soundManager.unmute(): ', i; + if (typeof sID !== 'string') { + sID = null; + } + if (!sID) { + _s._wD(fN + 'Unmuting all sounds'); + for (i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].unmute(); + } + _s.muted = false; + } else { + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Unmuting "' + sID + '"'); + return _s.sounds[sID].unmute(); + } + return true; + }; + + this.unmuteAll = function() { + _s.unmute(); + }; + + this.toggleMute = function(sID) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].toggleMute(); + }; + + this.getMemoryUse = function() { + if (_fV === 8) { + return 0; + } + if (_s.o) { + return parseInt(_s.o._getMemoryUse(), 10); + } + }; + + this.disable = function(bNoDisable) { + // destroy all functions + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled) { + return false; + } + _disabled = true; + _wDS('shutdown', 1); + for (var i = _s.soundIDs.length; i--;) { + _disableObject(_s.sounds[_s.soundIDs[i]]); + } + _initComplete(bNoDisable); // fire "complete", despite fail + _removeEvt(_win, 'load', _initUserOnload); + return true; + }; + + this.canPlayMIME = function(sMIME) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay({type:sMIME}); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sMIME?(sMIME.match(_s.mimePattern)?true:false):null); + } + }; + + this.canPlayURL = function(sURL) { + var result; + if (_s.hasHTML5) { + result = _html5CanPlay(sURL); + } + if (!_needsFlash || result) { + // no flash, or OK + return result; + } else { + return (sURL?(sURL.match(_s.filePattern)?true:false):null); + } + }; + + this.canPlayLink = function(oLink) { + if (typeof oLink.type !== 'undefined' && oLink.type) { + if (_s.canPlayMIME(oLink.type)) { + return true; + } + } + return _s.canPlayURL(oLink.href); + }; + + this.getSoundById = function(sID, suppressDebug) { + if (!sID) { + throw new Error('SoundManager.getSoundById(): sID is null/undefined'); + } + var result = _s.sounds[sID]; + if (!result && !suppressDebug) { + _s._wD('"' + sID + '" is an invalid sound ID.', 2); + } + return result; + }; + + this.onready = function(oMethod, oScope) { + if (oMethod && oMethod instanceof Function) { + if (_didInit) { + _wDS('queue'); + } + if (!oScope) { + oScope = _win; + } + _addOnReady(oMethod, oScope); + _processOnReady(); + return true; + } else { + throw _str('needFunction'); + } + }; + + this.getMoviePercent = function() { + return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); + }; + + this._writeDebug = function(sText, sType, bTimestamp) { + // If the debug log callback is set, always call it, regardless of debugMode + if (_s.ondebuglog) { + _s.ondebuglog(sText, sType, bTimestamp); + } + // pseudo-private console.log()-style output + // <d> + var sDID = 'soundmanager-debug', o, oItem, sMethod; + if (!_s.debugMode) { + return false; + } + if (typeof bTimestamp !== 'undefined' && bTimestamp) { + sText = sText + ' | ' + new Date().getTime(); + } + if (_hasConsole && _s.useConsole) { + sMethod = _debugLevels[sType]; + if (typeof console[sMethod] !== 'undefined') { + console[sMethod](sText); + } else { + console.log(sText); + } + if (_s.useConsoleOnly) { + return true; + } + } + try { + o = _id(sDID); + if (!o) { + return false; + } + oItem = _doc.createElement('div'); + if (++_wdCount % 2 === 0) { + oItem.className = 'sm2-alt'; + } + if (typeof sType === 'undefined') { + sType = 0; + } else { + sType = parseInt(sType, 10); + } + oItem.appendChild(_doc.createTextNode(sText)); + if (sType) { + if (sType >= 2) { + oItem.style.fontWeight = 'bold'; + } + if (sType === 3) { + oItem.style.color = '#ff3333'; + } + } + // o.appendChild(oItem); // top-to-bottom + o.insertBefore(oItem, o.firstChild); // bottom-to-top + } catch(e) { + // oh well + } + o = null; + // </d> + return true; + }; + this._wD = this._writeDebug; // alias + + this._debug = function() { + // <d> + _wDS('currentObj', 1); + for (var i = 0, j = _s.soundIDs.length; i < j; i++) { + _s.sounds[_s.soundIDs[i]]._debug(); + } + // </d> + }; + + this.reboot = function() { + // attempt to reset and init SM2 + _s._wD('soundManager.reboot()'); + if (_s.soundIDs.length) { + _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); + } + for (var i = _s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].destruct(); + } + // trash ze flash + try { + if (_isIE) { + _oRemovedHTML = _s.o.innerHTML; + } + _oRemoved = _s.o.parentNode.removeChild(_s.o); + _s._wD('Flash movie removed.'); + } catch(e) { + // uh-oh. + _wDS('badRemove', 2); + } + // actually, force recreate of movie. + _oRemovedHTML = _oRemoved = null; + _s.enabled = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; + _s.soundIDs = _s.sounds = []; + _s.o = null; + for (i = _onready.length; i--;) { + _onready[i].fired = false; + } + _s._wD(_sm + ': Rebooting...'); + _win.setTimeout(function() { + _s.beginDelayedInit(); + }, 20); + }; + + this.destruct = function() { + _s._wD('soundManager.destruct()'); + _s.disable(true); + }; + + this.beginDelayedInit = function() { + // _s._wD('soundManager.beginDelayedInit()'); + _windowLoaded = true; + _dcLoaded(); + setTimeout(_beginInit, 20); + _delayWaitForEI(); + }; + + // --- SMSound (sound object) instance --- + + SMSound = function(oOptions) { + var _t = this, _resetProperties, _add_html5_events, _stop_html5_timer, _start_html5_timer, _get_html5_duration, _a; + this.sID = oOptions.id; + this.url = oOptions.url; + this.options = _mixin(oOptions); + this.instanceOptions = this.options; // per-play-instance-specific options + this._iO = this.instanceOptions; // short alias + // assign property defaults + this.pan = this.options.pan; + this.volume = this.options.volume; + this._lastURL = null; + this.isHTML5 = false; + + // --- public methods --- + + this.id3 = {}; + + this._debug = function() { + // <d> + // pseudo-private console.log()-style output + if (_s.debugMode) { + var stuff = null, msg = [], sF, sfBracket, maxLength = 64; + for (stuff in _t.options) { + if (_t.options[stuff] !== null) { + if (_t.options[stuff] instanceof Function) { + // handle functions specially + sF = _t.options[stuff].toString(); + sF = sF.replace(/\s\s+/g, ' '); // normalize spaces + sfBracket = sF.indexOf('{'); + msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }'); + } else { + msg.push(' ' + stuff + ': ' + _t.options[stuff]); + } + } + } + _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}'); + } + // </d> + }; + + this._debug(); + + this.load = function(oOptions) { + var oS = null; + if (typeof oOptions !== 'undefined') { + _t._iO = _mixin(oOptions); + _t.instanceOptions = _t._iO; + } else { + oOptions = _t.options; + _t._iO = oOptions; + _t.instanceOptions = _t._iO; + if (_t._lastURL && _t._lastURL !== _t.url) { + _wDS('manURL'); + _t._iO.url = _t.url; + _t.url = null; + } + } + _s._wD('soundManager.load(): ' + _t._iO.url, 1); + if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { + _wDS('onURL', 1); + return _t; + } + _t._lastURL = _t.url; + _t.loaded = false; + _t.readyState = 1; + _t.playState = 0; + if (_html5OK(_t._iO)) { + _s._wD('HTML 5 load: '+_t._iO.url); + oS = _t._setup_html5(_t._iO); + oS.load(); + if (_t._iO.autoPlay) { + _t.play(); + } + } else { + try { + _t.isHTML5 = false; + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_fV === 8) { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile); + } else { + _s.o._load(_t.sID, _t._iO.url, _t._iO.stream?true:false, _t._iO.autoPlay?true:false, _t._iO.loops||1, _t._iO.autoLoad?true:false, _t._iO.usePolicyFile); + } + } catch(e) { + _wDS('smError', 2); + _debugTS('onload', false); + _die(); + } + } + return _t; + }; + + this.unload = function() { + // Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 + // Flash 9/AS3: Close stream, preventing further load + if (_t.readyState !== 0) { + _s._wD('SMSound.unload(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + if (_fV === 8) { + _s.o._unload(_t.sID, _s.nullURL); + } else { + _s.o._unload(_t.sID); + } + } else { + _stop_html5_timer(); + if (_a) { + // abort()-style method here, stop loading? (doesn't exist?) + _a.pause(); + _a.src = _s.nullURL; // needed? does nulling object work? any better way to cancel/unload/abort? + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + // reset load/status flags + _resetProperties(); + } + return _t; + }; + + this.destruct = function(_bFromSM) { + _s._wD('SMSound.destruct(): "' + _t.sID + '"'); + if (!_t.isHTML5) { + // kill sound within Flash + // Disable the onfailure handler + _t._iO.onfailure = null; + _s.o._destroySound(_t.sID); + } else { + _stop_html5_timer(); + if (_a) { + _a.pause(); + _a.src = 'about:blank'; + _a.load(); + _t._audio = null; + _a = null; + // delete _t._audio; + } + } + if (!_bFromSM) { + _s.destroySound(_t.sID, true); // ensure deletion from controller + } + }; + + this.play = function(oOptions, _updatePlayState) { + var fN = 'SMSound.play(): ', allowMulti; + _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState); + if (!oOptions) { + oOptions = {}; + } + _t._iO = _mixin(oOptions, _t._iO); + _t._iO = _mixin(_t._iO, _t.options); + _t.instanceOptions = _t._iO; + if (_t._iO.serverURL) { + if (!_t.connected) { + if (!_t.getAutoPlay()) { + _s._wD(fN+' Netstream not connected yet - setting autoPlay'); + _t.setAutoPlay(true); + } + return _t; + } + } + if (_html5OK(_t._iO)) { + _t._setup_html5(_t._iO); + _start_html5_timer(); + } + // KJV paused sounds have playState 1. We want these sounds to play. + if (_t.playState === 1 && !_t.paused) { + allowMulti = _t._iO.multiShot; + if (!allowMulti) { + _s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1); + return _t; + } else { + _s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1); + if (_t.isHTML5) { + // TODO: BUG? + _t.setPosition(_t._iO.position); + } + } + } + if (!_t.loaded) { + if (_t.readyState === 0) { + _s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1); + // try to get this sound playing ASAP + if (!_t.isHTML5) { + if (!_t._iO.serverURL) { + _t._iO.autoPlay = true; + _t.load(_t._iO); + } + } else { + _t.load(_t._iO); + _t.readyState = 1; + } + } else if (_t.readyState === 2) { + _s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2); + return _t; + } else { + _s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1); + } + } else { + _s._wD(fN + '"' + _t.sID + '"'); + } + // Streams will pause when their buffer is full if they are not auto-playing. + // In this case paused is true, but the song hasn't started playing yet. If + // we just call resume() the onplay() callback will never be called. + + // Also, if we just call resume() in this case and the sound has been muted + // (volume is 0), it will never have its volume set so sound will be heard + // when it shouldn't. + if (_t.paused && _t.position && _t.position > 0) { // https://gist.github.com/37b17df75cc4d7a90bf6 + _s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1); + _t.resume(); + } else { + _s._wD(fN+'"'+ _t.sID+'" is starting to play'); + _t.playState = 1; + _t.paused = false; + if (!_t.instanceCount || _t._iO.multiShotEvents || (_fV > 8 && !_t.isHTML5 && !_t.getAutoPlay())) { + _t.instanceCount++; + } + _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); + _t._iO = _policyFix(_loopFix(_t._iO)); + if (_t._iO.onplay && _updatePlayState) { + _t._iO.onplay.apply(_t); + } + _t.setVolume(_t._iO.volume, true); + _t.setPan(_t._iO.pan, true); + if (!_t.isHTML5) { + _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t.position:_t.position / 1000)); + } else { + _start_html5_timer(); + _t._setup_html5().play(); + } + } + return _t; + }; + + this.start = this.play; // just for convenience + + this.stop = function(bAll) { + if (_t.playState === 1) { + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (!_t.isHTML5) { + _t.playState = 0; + } + _t.paused = false; + if (_t._iO.onstop) { + _t._iO.onstop.apply(_t); + } + if (!_t.isHTML5) { + _s.o._stop(_t.sID, bAll); + // hack for netStream: just unload + if (_t._iO.serverURL) { + _t.unload(); + } + } else { + if (_a) { + _t.setPosition(0); // act like Flash, though + _a.pause(); // html5 has no stop() + _t.playState = 0; + _t._onTimer(); // and update UI + _stop_html5_timer(); + _t.unload(); + } + } + _t.instanceCount = 0; + _t._iO = {}; + } + return _t; + }; + + this.setAutoPlay = function(autoPlay) { + _s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off')); + _t._iO.autoPlay = autoPlay; + _s.o._setAutoPlay(_t.sID, autoPlay); + if (autoPlay) { + // KJV Only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP) + if (!_t.instanceCount && _t.readyState === 1) { + _t.instanceCount++; + _s._wD('sound '+_t.sID+' incremented instance count to '+_t.instanceCount); + } + } + }; + + this.getAutoPlay = function() { + return _t._iO.autoPlay; + }; + + this.setPosition = function(nMsecOffset, bNoDebug) { + if (nMsecOffset === undefined) { + nMsecOffset = 0; + } + // KJV Use the duration from the instance options, if we don't have a track duration yet. + // Auto-loading streams with a starting position in their options will start playing + // as soon as they connect. In the start() call we set the position on the stream, + // but because the stream hasn't played _t.duration won't have been set (that is + // done in whileloading()). So if we don't have a duration yet, use the duration + // from the instance options, if available. + var position, offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); // position >= 0 and <= current available (loaded) duration + _t.position = offset; + _t.resetOnPosition(_t.position); + if (!_t.isHTML5) { + position = _fV === 9 ? _t.position : _t.position / 1000; + // KJV We want our sounds to play on seek. A progressive download that + // is loaded has paused = false so resume() does nothing and the sound + // doesn't play. Handle that case here. + if (_t.playState === 0) { + _t.play({ position: position }); + } else { + _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) + // if (_t.paused) { + // _t.resume(); + // } + } + } else if (_a) { + _s._wD('setPosition(): setting position to '+(_t.position / 1000)); + if (_t.playState) { + // DOM/JS errors/exceptions to watch out for: + // if seek is beyond (loaded?) position, "DOM exception 11" + // "INDEX_SIZE_ERR": DOM exception 1 + try { + _a.currentTime = _t.position / 1000; + } catch(e) { + _s._wD('setPosition('+_t.position+'): WARN: Caught exception: '+e.message, 2); + } + } else { + _s._wD('HTML 5 warning: cannot set position while playState == 0 (not playing)',2); + } + if (_t.paused) { // if paused, refresh UI right away + _t._onTimer(true); // force update + if (_t._iO.useMovieStar) { + _t.resume(); + } + } + } + return _t; + }; + + this.pause = function(bCallFlash) { + if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { + return _t; + } + _s._wD('SMSound.pause()'); + _t.paused = true; + if (!_t.isHTML5) { + if (bCallFlash || bCallFlash === undefined) { + _s.o._pause(_t.sID); + } + } else { + _t._setup_html5().pause(); + _stop_html5_timer(); + } + if (_t._iO.onpause) { + _t._iO.onpause.apply(_t); + } + return _t; + }; + + this.resume = function() { + // When auto-loaded streams pause on buffer full they have a playState of 0. + // We need to make sure that the playState is set to 1 when these streams "resume". + if (!_t.paused) { + return _t; + } + _s._wD('SMSound.resume()'); + _t.paused = false; + _t.playState = 1; // TODO: verify that this is needed. + if (!_t.isHTML5) { + _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) + } else { + _t._setup_html5().play(); + _start_html5_timer(); + } + if (_t._iO.onresume) { + _t._iO.onresume.apply(_t); + } + return _t; + }; + + this.togglePause = function() { + _s._wD('SMSound.togglePause()'); + if (_t.playState === 0) { + _t.play({ + position: (_fV === 9 && !_t.isHTML5 ? _t.position:_t.position / 1000) + }); + return _t; + } + if (_t.paused) { + _t.resume(); + } else { + _t.pause(); + } + return _t; + }; + + this.setPan = function(nPan, bInstanceOnly) { + if (typeof nPan === 'undefined') { + nPan = 0; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setPan(_t.sID, nPan); + } // else { no HTML5 pan? } + _t._iO.pan = nPan; + if (!bInstanceOnly) { + _t.pan = nPan; + } + return _t; + }; + + this.setVolume = function(nVol, bInstanceOnly) { + if (typeof nVol === 'undefined') { + nVol = 100; + } + if (typeof bInstanceOnly === 'undefined') { + bInstanceOnly = false; + } + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); + } else if (_a) { + _a.volume = nVol/100; + } + _t._iO.volume = nVol; + if (!bInstanceOnly) { + _t.volume = nVol; + } + return _t; + }; + + this.mute = function() { + _t.muted = true; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, 0); + } else if (_a) { + _a.muted = true; + } + return _t; + }; + + this.unmute = function() { + _t.muted = false; + var hasIO = typeof _t._iO.volume !== 'undefined'; + if (!_t.isHTML5) { + _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); + } else if (_a) { + _a.muted = false; + } + return _t; + }; + + this.toggleMute = function() { + return (_t.muted?_t.unmute():_t.mute()); + }; + + this.onposition = function(nPosition, oMethod, oScope) { + // TODO: allow for ranges, too? eg. (nPosition instanceof Array) + _t._onPositionItems.push({ + position: nPosition, + method: oMethod, + scope: (typeof oScope !== 'undefined'?oScope:_t), + fired: false + }); + return _t; + }; + + this.processOnPosition = function() { + var i, item, j = _t._onPositionItems.length; + if (!j || !_t.playState || _t._onPositionFired >= j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (!item.fired && _t.position >= item.position) { + item.method.apply(item.scope,[item.position]); + item.fired = true; + _s._onPositionFired++; + } + } + return true; + }; + + this.resetOnPosition = function(nPosition) { + // reset "fired" for items interested in this position + var i, item, j = _t._onPositionItems.length; + if (!j) { + return false; + } + for (i=j; i--;) { + item = _t._onPositionItems[i]; + if (item.fired && nPosition <= item.position) { + item.fired = false; + _s._onPositionFired--; + } + } + return true; + }; + + // pseudo-private soundManager reference + + this._onTimer = function(bForce) { + // HTML 5-only _whileplaying() etc. + var time, x = {}; + if (_t._hasTimer || bForce) { + if (_a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { // TODO: May not need to track readyState (1 = loading) + _t.duration = _get_html5_duration(); + _t.durationEstimate = _t.duration; + time = _a.currentTime?_a.currentTime*1000:0; + _t._whileplaying(time,x,x,x,x); + return true; + } else { + _s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); + return false; + } + } + }; + + // --- private internals --- + + _get_html5_duration = function() { + var d = (_a?_a.duration*1000:undefined); + return (d && !isNaN(d)?d:null); + }; + + _start_html5_timer = function() { + if (_t.isHTML5) { + _startTimer(_t); + } + }; + + _stop_html5_timer = function() { + if (_t.isHTML5) { + _stopTimer(_t); + } + }; + + _resetProperties = function(bLoaded) { + _t._onPositionItems = []; + _t._onPositionFired = 0; + _t._hasTimer = null; + _t._added_events = null; + _t._audio = null; + _a = null; + _t.bytesLoaded = null; + _t.bytesTotal = null; + _t.position = null; + _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null); + _t.durationEstimate = null; + _t.failures = 0; + _t.loaded = false; + _t.playState = 0; + _t.paused = false; + _t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success + _t.muted = false; + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + _t.isBuffering = false; + _t.instanceOptions = {}; + _t.instanceCount = 0; + _t.peakData = { + left: 0, + right: 0 + }; + _t.waveformData = { + left: [], + right: [] + }; + _t.eqData = []; // legacy: 1D array + _t.eqData.left = []; + _t.eqData.right = []; + }; + + _resetProperties(); + + // pseudo-private methods used by soundManager + + this._setup_html5 = function(oOptions) { + var _iO = _mixin(_t._iO, oOptions); + if (_a) { + if (_t.url !== _iO.url) { + _s._wD('setting new URL on existing object: '+_iO.url); + _a.src = _iO.url; + } + } else { + _s._wD('creating HTML 5 audio element with URL: '+_iO.url); + _t._audio = new Audio(_iO.url); + _a = _t._audio; + _t.isHTML5 = true; + _add_html5_events(); + } + _a.loop = (_iO.loops>1?'loop':''); + return _t._audio; + }; + + // related private methods + + _add_html5_events = function() { + if (_t._added_events) { + return false; + } + _t._added_events = true; + + function _add(oEvt, oFn, bCapture) { + return (_a ? _a.addEventListener(oEvt, oFn, bCapture||false) : null); + } + + _add('load', function(e) { + _s._wD('HTML5::load: '+_t.sID); + if (_a) { + _t._onbufferchange(0); + _t._whileloading(_t.bytesTotal, _t.bytesTotal, _get_html5_duration()); + _t._onload(true); + } + }, false); + + _add('canplay', function(e) { + _s._wD('HTML5::canplay: '+_t.sID); + // enough has loaded to play + _t._onbufferchange(0); + },false); + + _add('waiting', function(e) { + _s._wD('HTML5::waiting: '+_t.sID); + // playback faster than download rate, etc. + _t._onbufferchange(1); + },false); + + _add('progress', function(e) { // not supported everywhere yet.. + _s._wD('HTML5::progress: '+_t.sID+': loaded/total: '+(e.loaded||0)+'/'+(e.total||1)); + if (!_t.loaded && _a) { + _t._onbufferchange(0); // if progress, likely not buffering + _t._whileloading(e.loaded||0, e.total||1, _get_html5_duration()); + } + }, false); + + _add('error', function(e) { + if (_a) { + _s._wD('HTML5::error: '+_a.error.code); + // call load with error state? + _t._onload(false); + } + }, false); + + _add('loadstart', function(e) { + _s._wD('HTML5::loadstart: '+_t.sID); + // assume buffering at first + _t._onbufferchange(1); + }, false); + + _add('play', function(e) { + _s._wD('HTML5::play: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + // TODO: verify if this is actually implemented anywhere yet. + _add('playing', function(e) { + _s._wD('HTML5::playing: '+_t.sID); + // once play starts, no buffering + _t._onbufferchange(0); + }, false); + + _add('timeupdate', function(e) { + _t._onTimer(); + }, false); + + // avoid stupid premature event-firing bug in Safari(?) + setTimeout(function(){ + if (_t && _a) { + _add('ended',function(e) { + _s._wD('HTML5::ended: '+_t.sID); + _t._onfinish(); + }, false); + } + }, 250); + return true; + }; + + // --- "private" methods called by Flash --- + + this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { + _t.bytesLoaded = nBytesLoaded; + _t.bytesTotal = nBytesTotal; + _t.duration = Math.floor(nDuration); + _t.bufferLength = nBufferLength; + if (!_t._iO.isMovieStar) { + if (_t._iO.duration) { + // use options, if specified and larger + _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration; + } else { + _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); + } + if (_t.durationEstimate === undefined) { + _t.durationEstimate = _t.duration; + } + _t.bufferLength = nBufferLength; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } else { + _t.durationEstimate = _t.duration; + if (_t.readyState !== 3 && _t._iO.whileloading) { + _t._iO.whileloading.apply(_t); + } + } + }; + + this._onid3 = function(oID3PropNames, oID3Data) { + // oID3PropNames: string array (names) + // ID3Data: string array (data) + _s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.'); + var oData = [], i, j; + for (i = 0, j = oID3PropNames.length; i < j; i++) { + oData[oID3PropNames[i]] = oID3Data[i]; + } + _t.id3 = _mixin(_t.id3, oData); + if (_t._iO.onid3) { + _t._iO.onid3.apply(_t); + } + }; + + this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { + if (isNaN(nPosition) || nPosition === null) { + return false; // Flash may return NaN at times + } + if (_t.playState === 0 && nPosition > 0) { + // invalid position edge case for end/stop + nPosition = 0; + } + _t.position = nPosition; + _t.processOnPosition(); + if (_fV > 8 && !_t.isHTML5) { + if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { + _t.peakData = { + left: oPeakData.leftPeak, + right: oPeakData.rightPeak + }; + } + if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { + _t.waveformData = { + left: oWaveformDataLeft.split(','), + right: oWaveformDataRight.split(',') + }; + } + if (_t._iO.useEQData) { + if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { + var eqLeft = oEQData.leftEQ.split(','); + _t.eqData = eqLeft; + _t.eqData.left = eqLeft; + if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { + _t.eqData.right = oEQData.rightEQ.split(','); + } + } + } + } + if (_t.playState === 1) { + // special case/hack: ensure buffering is false if loading from cache (and not yet started) + if (!_t.isHTML5 && _s.flashVersion === 8 && !_t.position && _t.isBuffering) { + _t._onbufferchange(0); + } + if (_t._iO.whileplaying) { + _t._iO.whileplaying.apply(_t); // flash may call after actual finish + } + if ((_t.loaded || (!_t.loaded && _t._iO.isMovieStar)) && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { + _t._onbeforefinish(); + } + } + return true; + }; + + this._onconnect = function(bSuccess) { + var fN = 'SMSound._onconnect(): '; + bSuccess = (bSuccess === 1); + _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); + _t.connected = bSuccess; + if (bSuccess) { + _t.failures = 0; + if (_t._iO.onconnect) { + _t._iO.onconnect.apply(_t,[bSuccess]); + } + // don't play if the sound is being destroyed + if (_idCheck(_t.sID) && (_t.options.autoLoad || _t.getAutoPlay())) { + _t.play(undefined, _t.getAutoPlay()); // only update the play state if auto playing + } + } + }; + + this._onload = function(nSuccess) { + var fN = 'SMSound._onload(): ', loadOK = (nSuccess?true:false); + _s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2)); + // <d> + if (!loadOK && !_t.isHTML5) { + if (_s.sandbox.noRemote === true) { + _s._wD(fN + _str('noNet'), 1); + } + if (_s.sandbox.noLocal === true) { + _s._wD(fN + _str('noLocal'), 1); + } + } + // </d> + _t.loaded = loadOK; + _t.readyState = loadOK?3:2; + _t._onbufferchange(0); + if (_t._iO.onload) { + _t._iO.onload.apply(_t, [loadOK]); + } + return true; + }; + + // fire onfailure() only once at most + // at this point we just recreate failed sounds rather than trying to reconnect. + this._onfailure = function(msg, level, code) { + _t.failures++; + _s._wD('SMSound._onfailure(): "'+_t.sID+'" count '+_t.failures); + if (_t._iO.onfailure && _t.failures === 1) { + _t._iO.onfailure(_t, msg, level, code); + } else { + _s._wD('SMSound._onfailure(): ignoring'); + } + }; + + this._onbeforefinish = function() { + if (!_t.didBeforeFinish) { + _t.didBeforeFinish = true; + if (_t._iO.onbeforefinish) { + _s._wD('SMSound._onbeforefinish(): "' + _t.sID + '"'); + _t._iO.onbeforefinish.apply(_t); + } + } + }; + + this._onjustbeforefinish = function(msOffset) { + if (!_t.didJustBeforeFinish) { + _t.didJustBeforeFinish = true; + if (_t._iO.onjustbeforefinish) { + _s._wD('SMSound._onjustbeforefinish(): "' + _t.sID + '"'); + _t._iO.onjustbeforefinish.apply(_t); + } + } + }; + + // KJV - connect & play time callback from Flash + this._onstats = function(stats) { + if (_t._iO.onstats) { + _t._iO.onstats(_t, stats); + } + }; + + this._onfinish = function() { + // _s._wD('SMSound._onfinish(): "' + _t.sID + '" got instanceCount '+_t.instanceCount); + _t._onbufferchange(0); + _t.resetOnPosition(0); + if (_t._iO.onbeforefinishcomplete) { + _t._iO.onbeforefinishcomplete.apply(_t); + } + // reset some state items + _t.didBeforeFinish = false; + _t.didJustBeforeFinish = false; + if (_t.instanceCount) { + _t.instanceCount--; + if (!_t.instanceCount) { + // reset instance options + _t.playState = 0; + _t.paused = false; + _t.instanceCount = 0; + _t.instanceOptions = {}; + _stop_html5_timer(); + } + if (!_t.instanceCount || _t._iO.multiShotEvents) { + // fire onfinish for last, or every instance + if (_t._iO.onfinish) { + _s._wD('SMSound._onfinish(): "' + _t.sID + '"'); + _t._iO.onfinish.apply(_t); + } + } + } + }; + + this._onbufferchange = function(nIsBuffering) { + var fN = 'SMSound._onbufferchange()'; + if (_t.playState === 0) { + // ignore if not playing + return false; + } + if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { + return false; + } + _t.isBuffering = (nIsBuffering === 1); + if (_t._iO.onbufferchange) { + _s._wD(fN + ': ' + nIsBuffering); + _t._iO.onbufferchange.apply(_t); + } + return true; + }; + + this._ondataerror = function(sError) { + // flash 9 wave/eq data handler + if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish() + _s._wD('SMSound._ondataerror(): ' + sError); + if (_t._iO.ondataerror) { + _t._iO.ondataerror.apply(_t); + } + } + }; + + }; // SMSound() + + // --- private SM2 internals --- + + _getDocument = function() { + return (_doc.body?_doc.body:(_doc._docElement?_doc.documentElement:_doc.getElementsByTagName('div')[0])); + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _mixin = function(oMain, oAdd) { + // non-destructive merge + var o1 = {}, i, o2, o; + for (i in oMain) { // clone c1 + if (oMain.hasOwnProperty(i)) { + o1[i] = oMain[i]; + } + } + o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd); + for (o in o2) { + if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { + o1[o] = o2[o]; + } + } + return o1; + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + _html5OK = function(iO) { + return ((iO.type?_html5CanPlay({type:iO.type}):false)||_html5CanPlay(iO.url)); + }; + + _html5CanPlay = function(sURL) { + // try to find MIME, test and return truthiness + if (!_s.useHTML5Audio || !_s.hasHTML5) { + return false; + } + var result, mime, fileExt, item, aF = _s.audioFormats; + if (!_html5Ext) { + _html5Ext = []; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + _html5Ext.push(item); + if (aF[item].related) { + _html5Ext = _html5Ext.concat(aF[item].related); + } + } + } + _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')','i'); + } + mime = (typeof sURL.type !== 'undefined'?sURL.type:null); + fileExt = (typeof sURL === 'string'?sURL.toLowerCase().match(_html5Ext):null); // TODO: Strip URL queries, etc. + if (!fileExt || !fileExt.length) { + if (!mime) { + return false; + } + } else { + fileExt = fileExt[0].substr(1); // "mp3", for example + } + if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { + // result known + return _s.html5[fileExt]; + } else { + if (!mime) { + if (fileExt && _s.html5[fileExt]) { + return _s.html5[fileExt]; + } else { + // best-case guess, audio/whatever-dot-filename-format-you're-playing + mime = 'audio/'+fileExt; + } + } + result = _s.html5.canPlayType(mime); + _s.html5[fileExt] = result; + // _s._wD('canPlayType, found result: '+result); + return result; + } + }; + + _testHTML5 = function() { + if (!_s.useHTML5Audio || typeof Audio === 'undefined') { + return false; + } + var a = (typeof Audio !== 'undefined' ? new Audio():null), item, support = {}, aF, i; + function _cp(m) { + var canPlay, i, j, isOK = false; + if (!a || typeof a.canPlayType !== 'function') { + return false; + } + if (m instanceof Array) { + // iterate through all mime types, return any successes + for (i=0, j=m.length; i<j && !isOK; i++) { + if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) { + isOK = true; + _s.html5[m[i]] = true; + } + } + return isOK; + } else { + canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false); + return (canPlay && (canPlay.match(_s.html5Test)?true:false)); + } + } + // test all registered formats + codecs + aF = _s.audioFormats; + for (item in aF) { + if (aF.hasOwnProperty(item)) { + support[item] = _cp(aF[item].type); + // assign result to related formats, too + if (aF[item] && aF[item].related) { + for (i=0; i<aF[item].related.length; i++) { + _s.html5[aF[item].related[i]] = support[item]; + } + } + } + } + support.canPlayType = (a?_cp:null); + _s.html5 = _mixin(_s.html5, support); + return true; + }; + + _strings = { + // <d> + notReady: 'Not loaded yet - wait for soundManager.onload()/onready()', + notOK: 'Audio support is not available.', + appXHTML: _sm + '::createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', + spcWmode: _sm + '::createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue', + swf404: _sm + ': Verify that %s is a valid path.', + tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)', + checkSWF: 'See SWF output for more debug info.', + localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', + waitFocus: _sm + ': Special case: Waiting for focus-related event..', + waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', + waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', + needFunction: _sm + '.onready(): Function object expected', + badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', + noMS: 'MovieStar mode not enabled. Exiting.', + currentObj: '--- ' + _sm + '._debug(): Current sound objects ---', + waitEI: _sm + '::initMovie(): Waiting for ExternalInterface call from Flash..', + waitOnload: _sm + ': Waiting for window.onload()', + docLoaded: _sm + ': Document already loaded', + onload: _sm + '::initComplete(): calling soundManager.onload()', + onloadOK: _sm + '.onload() complete', + init: '-- ' + _sm + '::init() --', + didInit: _sm + '::init(): Already called?', + flashJS: _sm + ': Attempting to call Flash from JS..', + noPolling: _sm + ': Polling (whileloading()/whileplaying() support) is disabled.', + secNote: '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', + badRemove: 'Warning: Failed to remove flash movie.', + noPeak: 'Warning: peakData features unsupported for movieStar formats', + shutdown: _sm + '.disable(): Shutting down', + queue: _sm + '.onready(): Queueing handler', + smFail: _sm + ': Failed to initialise.', + smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', + fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..', + fbLoaded: 'Flash loaded', + fbHandler: 'soundManager::flashBlockHandler()', + manURL: 'SMSound.load(): Using manually-assigned URL', + onURL: _sm + '.load(): current URL already assigned.', + badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.', + as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)', + noNSLoop: 'Note: Looping not implemented for MovieStar formats', + needfl9: 'Note: Switching to flash 9, required for MP4 formats.', + mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case', + mfOn: 'mobileFlash::enabling on-screen flash repositioning', + policy: 'Enabling usePolicyFile for data access' + // </d> + }; + + _id = function(sID) { + return _doc.getElementById(sID); + }; + + _str = function() { // o [,items to replace] + // <d> + var args = _slice.call(arguments), // real array, please + o = args.shift(), // first arg + str = (_strings && _strings[o]?_strings[o]:''), i, j; + if (str && args && args.length) { + for (i = 0, j = args.length; i < j; i++) { + str = str.replace('%s', args[i]); + } + } + return str; + // </d> + }; + + _loopFix = function(sOpt) { + // flash 8 requires stream = false for looping to work + if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { + _wDS('as2loop'); + sOpt.stream = false; + } + return sOpt; + }; + + _policyFix = function(sOpt, sPre) { + if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { + _s._wD((sPre?sPre+':':'') + _str('policy')); + sOpt.usePolicyFile = true; + } + return sOpt; + }; + + _complain = function(sMsg) { + if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + console.warn(sMsg); + } else { + _s._wD(sMsg); + } + }; + + _doNothing = function() { + return false; + }; + + _disableObject = function(o) { + for (var oProp in o) { + if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { + o[oProp] = _doNothing; + } + } + oProp = null; + }; + + _failSafely = function(bNoDisable) { + // general failure exception handler + if (typeof bNoDisable === 'undefined') { + bNoDisable = false; + } + if (_disabled || bNoDisable) { + _wDS('smFail', 2); + _s.disable(bNoDisable); + } + }; + + _normalizeMovieURL = function(smURL) { + var urlParams = null; + if (smURL) { + if (smURL.match(/\.swf(\?\.*)?$/i)) { + urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4); + if (urlParams) { + return smURL; // assume user knows what they're doing + } + } else if (smURL.lastIndexOf('/') !== smURL.length - 1) { + smURL = smURL + '/'; + } + } + return (smURL && smURL.lastIndexOf('/') !== - 1?smURL.substr(0, smURL.lastIndexOf('/') + 1):'./') + _s.movieURL; + }; + + _setVersionInfo = function() { + if (_fV !== 8 && _fV !== 9) { + _s._wD(_str('badFV', _fV, _defaultFlashVersion)); + _s.flashVersion = _defaultFlashVersion; + } + var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); // debug flash movie, if applicable + if (_s.flashVersion < 9 && _s.useHTML5Audio && _s.audioFormats.mp4.required) { + _s._wD(_str('needfl9')); + _s.flashVersion = 9; + } + _fV = _s.flashVersion; // short-hand for internal use + _s.version = _s.versionNumber + (_html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); + // set up default options + if (_fV > 8) { + _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); + _s.features.buffering = true; + } + if (_fV > 8 && _s.useMovieStar) { + // flash 9+ support for movieStar formats as well as MP3 + _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); + _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _s.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + _s.mimePattern = _s.netStreamMimeTypes; + _s.features.movieStar = true; + } else { + _s.features.movieStar = false; + } + _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; + _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf',isDebug); + _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); + }; + + _setPolling = function(bPolling, bHighPerformance) { + if (!_s.o || !_s.allowPolling) { + return false; + } + _s.o._setPolling(bPolling, bHighPerformance); + }; + + (function() { + var old = (_win.attachEvent), + evt = { + add: (old?'attachEvent':'addEventListener'), + remove: (old?'detachEvent':'removeEventListener') + }; + + function getArgs(oArgs) { + var args = _slice.call(oArgs), len = args.length; + if (old) { + args[1] = 'on' + args[1]; // prefix + if (len > 3) { + args.pop(); // no capture + } + } else if (len === 3) { + args.push(false); + } + return args; + } + + function apply(args, sType) { + var oFunc = args.shift()[evt[sType]]; + if (old) { + oFunc(args[0], args[1]); + } else { + oFunc.apply(this, args); + } + } + + _addEvt = function() { + apply(getArgs(arguments), 'add'); + }; + + _removeEvt = function() { + apply(getArgs(arguments), 'remove'); + }; + }()); + + function _initDebug() { + if (_s.debugURLParam.test(_wl)) { + _s.debugMode = true; // allow force of debug mode via URL + } + // <d> + if (_id(_s.debugID)) { + return false; + } + var oD, oDebug, oTarget, oToggle, tmp; + if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) { + oD = _doc.createElement('div'); + oD.id = _s.debugID + '-toggle'; + oToggle = { + 'position': 'fixed', + 'bottom': '0px', + 'right': '0px', + 'width': '1.2em', + 'height': '1.2em', + 'lineHeight': '1.2em', + 'margin': '2px', + 'textAlign': 'center', + 'border': '1px solid #999', + 'cursor': 'pointer', + 'background': '#fff', + 'color': '#333', + 'zIndex': 10001 + }; + oD.appendChild(_doc.createTextNode('-')); + oD.onclick = _toggleDebug; + oD.title = 'Toggle SM2 debug console'; + if (_ua.match(/msie 6/i)) { + oD.style.position = 'absolute'; + oD.style.cursor = 'hand'; + } + for (tmp in oToggle) { + if (oToggle.hasOwnProperty(tmp)) { + oD.style[tmp] = oToggle[tmp]; + } + } + oDebug = _doc.createElement('div'); + oDebug.id = _s.debugID; + oDebug.style.display = (_s.debugMode?'block':'none'); + if (_s.debugMode && !_id(oD.id)) { + try { + oTarget = _getDocument(); + oTarget.appendChild(oD); + } catch(e2) { + throw new Error(_str('appXHTML')); + } + oTarget.appendChild(oDebug); + } + } + oTarget = null; + // </d> + } + + _mobileFlash = (function(){ + + var oM = null; + + function resetPosition() { + if (oM) { + oM.left = oM.top = '-9999px'; + } + } + + function reposition() { + oM.left = _win.scrollX+'px'; + oM.top = _win.scrollY+'px'; + } + + function setReposition(bOn) { + _s._wD('mobileFlash::flash on-screen hack: '+(bOn?'ON':'OFF')); + var f = _win[(bOn?'add':'remove')+'EventListener']; + f('resize', reposition, false); + f('scroll', reposition, false); + } + + function check(inDoc) { + // mobile flash (Android for starters) check + oM = _s.oMC.style; + if (_ua.match(/android/i)) { + if (inDoc) { + if (_s.flashLoadTimeout) { + _s._wDS('mfTimeout'); + _s.flashLoadTimeout = 0; + } + return false; + } + _s._wD('mfOn'); + oM.position = 'absolute'; + oM.left = oM.top = '0px'; + setReposition(true); + _s.onready(function(){ + setReposition(false); // detach + resetPosition(); // restore when OK/timed out + }); + reposition(); + } + return true; + } + + return { + 'check': check + }; + + }()); + + _createMovie = function(smID, smURL) { + + var specialCase = null, + remoteURL = (smURL?smURL:_s.url), + localURL = (_s.altURL?_s.altURL:remoteURL), + oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(), s, x, sClass, side = '100%', isRTL = null, html = _doc.getElementsByTagName('html')[0]; + isRTL = (html && html.dir && html.dir.match(/rtl/i)); + smID = (typeof smID === 'undefined'?_s.id:smID); + + if (_didAppend && _appendSuccess) { + return false; // ignore if already succeeded + } + + function _initMsg() { + _s._wD('-- SoundManager 2 ' + _s.version + (!_html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (_s.useMovieStar?', MovieStar mode':'') + (_s.useHighPerformance?', high performance mode, ':', ') + ((_s.useFastPolling?'fast':'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') + ' --', 1); + } + + if (_html5Only) { + _setVersionInfo(); + _initMsg(); + _s.oMC = _id(_s.movieID); + _init(); + // prevent multiple init attempts + _didAppend = true; + _appendSuccess = true; + return false; + } + + _didAppend = true; + + // safety check for legacy (change to Flash 9 URL) + _setVersionInfo(); + _s.url = _normalizeMovieURL(this._overHTTP?remoteURL:localURL); + smURL = _s.url; + + _s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); + + if (_s.wmode !== null && !_isIE && !_s.useHighPerformance && navigator.platform.match(/win32/i)) { + _s.specialWmodeCase = true; + // extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here + // does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout + _wDS('spcWmode'); + _s.wmode = null; + } + + oEmbed = { + 'name': smID, + 'id': smID, + 'src': smURL, + 'width': side, + 'height': side, + 'quality': 'high', + 'allowScriptAccess': _s.allowScriptAccess, + 'bgcolor': _s.bgColor, + 'pluginspage': 'http://www.macromedia.com/go/getflashplayer', + 'type': 'application/x-shockwave-flash', + 'wmode': _s.wmode + }; + + if (_s.debugFlash) { + oEmbed.FlashVars = 'debug=1'; + } + + if (!_s.wmode) { + delete oEmbed.wmode; // don't write empty attribute + } + + if (_isIE) { + // IE is "special". + oMovie = _doc.createElement('div'); + movieHTML = '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" width="' + oEmbed.width + '" height="' + oEmbed.height + '"><param name="movie" value="' + smURL + '" /><param name="AllowScriptAccess" value="' + _s.allowScriptAccess + '" /><param name="quality" value="' + oEmbed.quality + '" />' + (_s.wmode?'<param name="wmode" value="' + _s.wmode + '" /> ':'') + '<param name="bgcolor" value="' + _s.bgColor + '" />' + (_s.debugFlash?'<param name="FlashVars" value="' + oEmbed.FlashVars + '" />':'') + '<!-- --></object>'; + } else { + oMovie = _doc.createElement('embed'); + for (tmp in oEmbed) { + if (oEmbed.hasOwnProperty(tmp)) { + oMovie.setAttribute(tmp, oEmbed[tmp]); + } + } + } + + _initDebug(); + extraClass = _getSWFCSS(); + oTarget = _getDocument(); + + if (oTarget) { + _s.oMC = _id(_s.movieID)?_id(_s.movieID):_doc.createElement('div'); + if (!_s.oMC.id) { + _s.oMC.id = _s.movieID; + _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass; + // "hide" flash movie + s = null; + oEl = null; + if (!_s.useFlashBlock) { + if (_s.useHighPerformance) { + s = { + 'position': 'fixed', + 'width': '8px', + 'height': '8px', + // >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes. + 'bottom': '0px', + 'left': '0px', + 'overflow': 'hidden' + }; + } else { + s = { + 'position': 'absolute', + 'width': '6px', + 'height': '6px', + 'top': '-9999px', + 'left': '-9999px' + }; + if (isRTL) { + s.left = Math.abs(parseInt(s.left,10))+'px'; + } + } + } + if (_ua.match(/webkit/i)) { + _s.oMC.style.zIndex = 10000; // soundcloud-reported render/crash fix, safari 5 + } + if (!_s.debugFlash) { + for (x in s) { + if (s.hasOwnProperty(x)) { + _s.oMC.style[x] = s[x]; + } + } + } + try { + if (!_isIE) { + _s.oMC.appendChild(oMovie); + } + oTarget.appendChild(_s.oMC); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + } catch(e) { + throw new Error(_str('appXHTML')); + } + _mobileFlash.check(); + } else { + // it's already in the document. + sClass = _s.oMC.className; + _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:''); + _s.oMC.appendChild(oMovie); + if (_isIE) { + oEl = _s.oMC.appendChild(_doc.createElement('div')); + oEl.className = _s.swfCSS.swfBox; + oEl.innerHTML = movieHTML; + } + _appendSuccess = true; + _mobileFlash.check(true); + } + } + + if (specialCase) { + _s._wD(specialCase); + } + + _initMsg(); + _s._wD('soundManager::createMovie(): Trying to load ' + smURL + (!this._overHTTP && _s.altURL?' (alternate URL)':''), 1); + + return true; + }; + + _idCheck = this.getSoundById; + + _initMovie = function() { + if (_html5Only) { + _createMovie(); + return false; + } + // attempt to get, or create, movie + if (_s.o) { + return false; // may already exist + } + _s.o = _s.getMovie(_s.id); // inline markup + if (!_s.o) { + if (!_oRemoved) { + // try to create + _createMovie(_s.id, _s.url); + } else { + // try to re-append removed movie after reboot() + if (!_isIE) { + _s.oMC.appendChild(_oRemoved); + } else { + _s.oMC.innerHTML = _oRemovedHTML; + } + _oRemoved = null; + _didAppend = true; + } + _s.o = _s.getMovie(_s.id); + } + if (_s.o) { + _s._wD('soundManager::initMovie(): Got '+_s.o.nodeName+' element ('+(_didAppend?'created via JS':'static HTML')+')'); + _wDS('waitEI'); + } + if (_s.oninitmovie instanceof Function) { + setTimeout(_s.oninitmovie, 1); + } + return true; + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + _delayWaitForEI = function() { + setTimeout(_waitForEI, 500); + }; + + _waitForEI = function() { + if (_waitingForEI) { + return false; + } + _waitingForEI = true; + _removeEvt(_win, 'load', _delayWaitForEI); + if (_tryInitOnFocus && !_isFocused) { + _wDS('waitFocus'); + return false; + } + var p; + if (!_didInit) { + p = _s.getMoviePercent(); + _s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':'')))); + } + setTimeout(function() { + p = _s.getMoviePercent(); + if (!_didInit) { + _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2); + if (!this._overHTTP && p) { + _wDS('localFail', 2); + if (!_s.debugFlash) { + _wDS('tryDebug', 2); + } + } + if (p === 0) { + // if 0 (not null), probably a 404. + _s._wD(_str('swf404', _s.url)); + } + _debugTS('flashtojs', false, ': Timed out' + this._overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); + } + // give up / time-out, depending + if (!_didInit && _okToDisable) { + if (p === null) { + // SWF failed. Maybe blocked. + if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + _wDS('waitForever'); + } else { + // old SM2 behaviour, simply fail + _failSafely(true); + } + } else { + // flash loaded? Shouldn't be a blocking issue, then. + if (_s.flashLoadTimeout === 0) { + _wDS('waitForever'); + } else { + _failSafely(true); + } + } + } + }, _s.flashLoadTimeout); + }; + + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); + }; + + // <d> + _wDS = function(o, errorLevel) { + if (!o) { + return ''; + } else { + return _s._wD(_str(o), errorLevel); + } + }; + + if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { + _s._wD = function(sText) {alert(sText);}; + } + + _toggleDebug = function() { + var o = _id(_s.debugID), + oT = _id(_s.debugID + '-toggle'); + if (!o) { + return false; + } + if (_debugOpen) { + // minimize + oT.innerHTML = '+'; + o.style.display = 'none'; + } else { + oT.innerHTML = '-'; + o.style.display = 'block'; + } + _debugOpen = !_debugOpen; + }; + + _debugTS = function(sEventType, bSuccess, sMessage) { + // troubleshooter debug hooks + if (typeof sm2Debugger !== 'undefined') { + try { + sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); + } catch(e) { + // oh well + } + } + return true; + }; + // </d> + + _getSWFCSS = function() { + var css = []; + if (_s.debugMode) { + css.push(_s.swfCSS.sm2Debug); + } + if (_s.debugFlash) { + css.push(_s.swfCSS.flashDebug); + } + if (_s.useHighPerformance) { + css.push(_s.swfCSS.highPerf); + } + return css.join(' '); + }; + + _flashBlockHandler = function() { + // *possible* flash block situation. + var name = _str('fbHandler'), p = _s.getMoviePercent(); + if (!_s.supported()) { + if (_needsFlash) { + // make the movie more visible, so user can fix + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + ' ' + (p === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':'')); + } + _s.didFlashBlock = true; + _processOnReady(true); // fire onready(), complain lightly + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + } else { + // SM2 loaded OK (or recovered) + if (_s.didFlashBlock) { + _s._wD(name+': Unblocked'); + } + if (_s.oMC) { + _s.oMC.className = _getSWFCSS() + ' ' + _s.swfCSS.swfDefault + (' '+_s.swfCSS.swfUnblocked); + } + } + }; + + _handleFocus = function() { + function cleanup() { + _removeEvt(_win, 'focus', _handleFocus); + _removeEvt(_win, 'load', _handleFocus); + } + if (_isFocused || !_tryInitOnFocus) { + cleanup(); + return true; + } + _okToDisable = true; + _isFocused = true; + _s._wD('soundManager::handleFocus()'); + if (_isSafari && _tryInitOnFocus) { + // giant Safari 3.1 hack - assume mousemove = focus given lack of focus event + _removeEvt(_win, 'mousemove', _handleFocus); + } + // allow init to restart + _waitingForEI = false; + cleanup(); + return true; + }; + + _initComplete = function(bNoDisable) { + if (_didInit) { + return false; + } + if (_html5Only) { + // all good. + _s._wD('-- SoundManager 2: loaded --'); + _didInit = true; + _processOnReady(); + _initUserOnload(); + return true; + } + var sClass = _s.oMC.className, + wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()); + if (!wasTimeout) { + _didInit = true; + } + _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1); + if (_disabled || bNoDisable) { + if (_s.useFlashBlock) { + _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); + } + _processOnReady(); + _debugTS('onload', false); + if (_s.onerror instanceof Function) { + _s.onerror.apply(_win); + } + return false; + } else { + _debugTS('onload', true); + } + if (_s.waitForWindowLoad && !_windowLoaded) { + _wDS('waitOnload'); + _addEvt(_win, 'load', _initUserOnload); + return false; + } else { + if (_s.waitForWindowLoad && _windowLoaded) { + _wDS('docLoaded'); + } + _initUserOnload(); + } + return true; + }; + + _addOnReady = function(oMethod, oScope) { + _onready.push({ + 'method': oMethod, + 'scope': (oScope || null), + 'fired': false + }); + }; + + _processOnReady = function(ignoreInit) { + if (!_didInit && !ignoreInit) { + // not ready yet. + return false; + } + var status = { + success: (ignoreInit?_s.supported():!_disabled) + }, + queue = [], i, j, + canRetry = (!_s.useFlashBlock || (_s.useFlashBlock && !_s.supported())); + for (i = 0, j = _onready.length; i < j; i++) { + if (_onready[i].fired !== true) { + queue.push(_onready[i]); + } + } + if (queue.length) { + _s._wD(_sm + ': Firing ' + queue.length + ' onready() item' + (queue.length > 1?'s':'')); + for (i = 0, j = queue.length; i < j; i++) { + if (queue[i].scope) { + queue[i].method.apply(queue[i].scope, [status]); + } else { + queue[i].method(status); + } + if (!canRetry) { // flashblock case doesn't count here + queue[i].fired = true; + } + } + } + return true; + }; + + _initUserOnload = function() { + _win.setTimeout(function() { + if (_s.useFlashBlock) { + _flashBlockHandler(); + } + _processOnReady(); + _wDS('onload', 1); + // call user-defined "onload", scoped to window + if (_s.onload instanceof Function) { + _s.onload.apply(_win); + } + _wDS('onloadOK', 1); + if (_s.waitForWindowLoad) { + _addEvt(_win, 'load', _initUserOnload); + } + },1); + }; + + _featureCheck = function() { + var needsFlash, item, + isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_(3|4)/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" bug. https://bugs.webkit.org/show_bug.cgi?id=32159 + isSpecial = (_ua.match(/iphone os (1|2|3_0|3_1)/i)?true:false); // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works. + if (isSpecial) { + _s.hasHTML5 = false; // has Audio(), but is broken; let it load links directly. + _html5Only = true; // ignore flash case, however + if (_s.oMC) { + _s.oMC.style.display = 'none'; + } + return false; + } + if (_s.useHTML5Audio) { + if (!_s.html5 || !_s.html5.canPlayType) { + _s._wD('SoundManager: No HTML5 Audio() support detected.'); + _s.hasHTML5 = false; + return true; + } else { + _s.hasHTML5 = true; + } + if (isBadSafari) { + _s._wD('SoundManager::Note: Buggy HTML5 Audio in Safari on OS X 10.6.[3|4], see https://bugs.webkit.org/show_bug.cgi?id=32159 - disabling HTML5 audio',1); + _s.useHTML5Audio = false; + _s.hasHTML5 = false; + return true; + } + } else { + // flash required. + return true; + } + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item) && _s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) { + // may need flash for this format? + needsFlash = true; + } + } + // sanity check.. + if (_s.ignoreFlash) { + needsFlash = false; + } + _html5Only = (_s.useHTML5Audio && _s.hasHTML5 && !needsFlash); + return needsFlash; + }; + + _init = function() { + var item, tests = []; + _wDS('init'); + + // called after onload() + if (_didInit) { + _wDS('didInit'); + return false; + } + + function _cleanup() { + _removeEvt(_win, 'load', _s.beginDelayedInit); + } + + if (_s.hasHTML5) { + for (item in _s.audioFormats) { + if (_s.audioFormats.hasOwnProperty(item)) { + tests.push(item+': '+_s.html5[item]); + } + } + _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); + } + + if (_html5Only) { + if (!_didInit) { + // we don't need no steenking flash! + _cleanup(); + _s.enabled = true; + _initComplete(); + } + return true; + } + + // flash path + _initMovie(); + try { + _wDS('flashJS'); + _s.o._externalInterfaceTest(false); // attempt to talk to Flash + if (!_s.allowPolling) { + _wDS('noPolling', 1); + } else { + _setPolling(true, _s.useFastPolling?true:false); + } + if (!_s.debugMode) { + _s.o._disableDebug(); + } + _s.enabled = true; + _debugTS('jstoflash', true); + } catch(e) { + _s._wD('js/flash exception: ' + e.toString()); + _debugTS('jstoflash', false); + _failSafely(true); // don't disable, for reboot() + _initComplete(); + return false; + } + _initComplete(); + // event cleanup + _cleanup(); + return true; + }; + + _beginInit = function() { + if (_initPending) { + return false; + } + _createMovie(); + _initMovie(); + _initPending = true; + return true; + }; + + _dcLoaded = function() { + if (_didDCLoaded) { + return false; + } + _didDCLoaded = true; + _initDebug(); + _testHTML5(); + _s.html5.usingFlash = _featureCheck(); + _needsFlash = _s.html5.usingFlash; + _didDCLoaded = true; + if (_doc.removeEventListener) { + _doc.removeEventListener('DOMContentLoaded', _dcLoaded, false); + } + _go(); + return true; + }; + + _startTimer = function(oSound) { + if (!oSound._hasTimer) { + oSound._hasTimer = true; + } + }; + + _stopTimer = function(oSound) { + if (oSound._hasTimer) { + oSound._hasTimer = false; + } + }; + + _die = function() { + if (_s.onerror instanceof Function) { + _s.onerror(); + } + _s.disable(); + }; + + // pseudo-private methods called by Flash + + this._setSandboxType = function(sandboxType) { + // <d> + var sb = _s.sandbox; + sb.type = sandboxType; + sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')]; + _s._wD('Flash security sandbox type: ' + sb.type); + if (sb.type === 'localWithFile') { + sb.noRemote = true; + sb.noLocal = false; + _wDS('secNote', 2); + } else if (sb.type === 'localWithNetwork') { + sb.noRemote = false; + sb.noLocal = true; + } else if (sb.type === 'localTrusted') { + sb.noRemote = false; + sb.noLocal = false; + } + // </d> + }; + + this._externalInterfaceOK = function(flashDate) { + // flash callback confirming flash loaded, EI working etc. + // flashDate = approx. timing/delay info for JS/flash bridge + if (_s.swfLoaded) { + return false; + } + var eiTime = new Date().getTime(); + _s._wD('soundManager::externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); + _debugTS('swf', true); + _debugTS('flashtojs', true); + _s.swfLoaded = true; + _tryInitOnFocus = false; + if (_isIE) { + // IE needs a timeout OR delay until window.onload - may need TODO: investigating + setTimeout(_init, 100); + } else { + _init(); + } + }; + + _dcIE = function() { + if (_doc.readyState === 'complete') { + _dcLoaded(); + _doc.detachEvent('onreadystatechange', _dcIE); + } + return true; + }; + + // focus and window load, init + if (!_s.hasHTML5 || _needsFlash) { + // only applies to Flash mode + _addEvt(_win, 'focus', _handleFocus); + _addEvt(_win, 'load', _handleFocus); + _addEvt(_win, 'load', _delayWaitForEI); + if (_isSafari && _tryInitOnFocus) { + _addEvt(_win, 'mousemove', _handleFocus); // massive Safari focus hack + } + } + + if (_doc.addEventListener) { + _doc.addEventListener('DOMContentLoaded', _dcLoaded, false); + } else if (_doc.attachEvent) { + _doc.attachEvent('onreadystatechange', _dcIE); + } else { + // no add/attachevent support - safe to assume no JS -> Flash either + _debugTS('onload', false); + _die(); + } + + if (_doc.readyState === 'complete') { + setTimeout(_dcLoaded,100); + } + +} // SoundManager() + +// var SM2_DEFER = true; +// details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading + +if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { + soundManager = new SoundManager(); +} + +// public interfaces +window.SoundManager = SoundManager; // constructor +window.soundManager = soundManager; // public instance: API, Flash callbacks etc. + +}(window)); diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2.as b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2.as new file mode 100755 index 0000000..e9d4011 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2.as @@ -0,0 +1,452 @@ +/*
+ SoundManager 2: Javascript Sound for the Web
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ Copyright (c) 2007, Scott Schiller. All rights reserved.
+ Code licensed under the BSD License:
+ http://www.schillmania.com/projects/soundmanager2/license.txt
+
+ Flash 8 / ActionScript 2 version
+
+ Compiling AS to Flash 8 SWF using MTASC (free compiler - http://www.mtasc.org/):
+ mtasc -swf soundmanager2.swf -main -header 16:16:30 SoundManager2.as -version 8
+
+ ActionScript Sound class reference (Macromedia), documentation download:
+ http://livedocs.macromedia.com/flash/8/
+ Previously-live URL:
+ http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002668.html
+
+ *** NOTE ON LOCAL FILE SYSTEM ACCESS ***
+
+ Flash security allows local OR network access, but not both
+ unless explicitly whitelisted/allowed by the flash player's
+ security settings.
+
+ To enable in-flash messaging for troubleshooting, pass debug=1 in FlashVars (within object/embed code)
+ SM2 will do this by default when soundManager.debugFlash = true.
+
+*/
+
+import flash.external.ExternalInterface; // woo
+
+class SoundManager2 {
+
+ static var app: SoundManager2;
+
+ function SoundManager2() {
+
+ var version = "V2.97a.20101010";
+ var version_as = "(AS2/Flash 8)";
+
+ /*
+ * Cross-domain security options
+ * HTML on foo.com loading .swf hosted on bar.com? Define your "HTML domain" here to allow JS+Flash communication to work.
+ * // allow_xdomain_scripting = true;
+ * // xdomain = "foo.com";
+ * For all domains (possible security risk?), use xdomain = "*"; which ends up as System.security.allowDomain("*");
+ * When loading from HTTPS, use System.security.allowInsecureDomain();
+ * See "allowDomain (security.allowDomain method)" in Flash 8/AS2 liveDocs documentation (AS2 reference -> classes -> security)
+ * download from http://livedocs.macromedia.com/flash/8/
+ * Related AS3 documentation: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/Security.html#allowDomain%28%29
+ */
+ var allow_xdomain_scripting = false;
+ var xdomain = "*";
+
+ if (allow_xdomain_scripting && xdomain) {
+ System.security.allowDomain(xdomain);
+ version_as += ' - cross-domain enabled';
+ }
+
+ // externalInterface references (for Javascript callbacks)
+ var baseJSController = "soundManager";
+ var baseJSObject = baseJSController + ".sounds";
+
+ // internal objects
+ var sounds = []; // indexed string array
+ var soundObjects = []; // associative Sound() object array
+ var timer = null;
+ var timerInterval = 50;
+ var pollingEnabled = false; // polling (timer) flag - disabled by default, enabled by JS->Flash call
+ var debugEnabled = true; // Flash debug output enabled by default, disabled by JS call
+ var flashDebugEnabled = false; // debug output to flash movie, off by default
+ var didSandboxMessage = false;
+ var caughtFatal = false;
+
+ // for flash text output, debugging etc.
+ var _messages = [];
+ var _messageObj = null;
+ flashDebugEnabled = (_root.debug == 1);
+
+ // display stuffs
+ Stage.scaleMode = 'noScale';
+ Stage.align = 'TL';
+
+ // context menu item with version info
+
+ var doNothing = function() {}
+
+ var sm2Menu:ContextMenu = new ContextMenu();
+ var sm2MenuItem:ContextMenuItem = new ContextMenuItem('SoundManager ' + version + ' ' + version_as, doNothing);
+ sm2MenuItem.enabled = false;
+ sm2Menu.customItems.push(sm2MenuItem);
+ _root.menu = sm2Menu;
+
+ var writeDebug = function(s) {
+ // <d>
+ if (!debugEnabled) return false;
+ ExternalInterface.call(baseJSController + "['_writeDebug']", "(Flash): " + s);
+ // </d>
+ }
+
+ var flashDebug = function(messageText) {
+ // <d>
+ _messages.push(messageText);
+ if (!flashDebugEnabled) {
+ return false;
+ }
+ var sans = new TextFormat();
+ sans.size = 12;
+ sans.font = "Arial";
+
+ // 320x240 if no stage dimensions (happens in IE, apparently 0 before stage resize event fires.)
+ var w = Stage.width?Stage.width:320;
+ var h = Stage.height?Stage.height:240;
+ if (!_messageObj) {
+ _messageObj = _root.createTextField("_messageObj", 0, 0, 0, w, h);
+ _messageObj.x = 0;
+ _messageObj.y = 0;
+ _messageObj.multiline = true;
+ _messageObj.html = true;
+ _messageObj.wordWrap = true;
+ _messageObj.align = 'left';
+ _messageObj.autoSize = false;
+ }
+ _messageObj.htmlText = _messages.join('\n');
+ _messageObj.setTextFormat(sans);
+ _messageObj.width = w;
+ _messageObj.height = h;
+ // </d>
+ }
+
+ var _externalInterfaceTest = function(isFirstCall) {
+ var sandboxType = System.security['sandboxType'];
+ try {
+ if (isFirstCall) {
+ flashDebug('Testing Flash -> JS...')
+ if (!didSandboxMessage && sandboxType != 'remote' && sandboxType != 'localTrusted') {
+ didSandboxMessage = true;
+ flashDebug('<br><b>Fatal: Security sandbox error: Got "' + sandboxType + '", expected "remote" or "localTrusted".<br>Additional security permissions need to be granted.<br>See <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">flash security settings panel</a> for non-HTTP, eg. file:// use.</b><br>http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html');
+ }
+ var d = new Date();
+ ExternalInterface.call(baseJSController + "._externalInterfaceOK", d.getTime());
+ if (!didSandboxMessage) {
+ flashDebug('Flash -> JS OK');
+ }
+ } else {
+ writeDebug('SM2 SWF ' + version + ' ' + version_as);
+ flashDebug('JS -> Flash OK');
+ writeDebug('JS to/from Flash OK');
+ ExternalInterface.call(baseJSController + "._setSandboxType", sandboxType);
+ }
+ } catch(e) {
+ flashDebug(e.toString());
+ if (!caughtFatal) {
+ caughtFatal = true;
+ }
+ return false;
+ }
+ return true; // to verify that a call from JS to here, works. (eg. JS receives "true", thus OK.)
+ }
+
+ var _disableDebug = function() {
+ // prevent future debug calls from Flash going to client (maybe improve performance)
+ writeDebug('_disableDebug()');
+ debugEnabled = false;
+ }
+
+ var checkProgress = function() {
+ var bL = 0;
+ var bT = 0;
+ var nD = 0;
+ var nP = 0;
+ var oSound = null;
+ for (var i = 0, j = sounds.length; i < j; i++) {
+ oSound = soundObjects[sounds[i]];
+ bL = oSound.getBytesLoaded();
+ bT = oSound.getBytesTotal();
+ nD = oSound.duration || 0; // can sometimes be null with short MP3s? Wack.
+ nP = oSound.position;
+ if (bL && bT && bL != oSound.lastValues.bytes) {
+ oSound.lastValues.bytes = bL;
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._whileloading", bL, bT, nD);
+ }
+ if (typeof nP != 'undefined' && nP != oSound.lastValues.position) {
+ oSound.lastValues.position = nP;
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._whileplaying", nP);
+ // if position changed, check for near-end
+ if (oSound.didJustBeforeFinish != true && oSound.loaded == true && oSound.justBeforeFinishOffset > 0 && nD - nP <= oSound.justBeforeFinishOffset) {
+ // fully-loaded, near end and haven't done this yet..
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._onjustbeforefinish", (nD - nP));
+ oSound.didJustBeforeFinish = true;
+ }
+ }
+ }
+ }
+
+ var onLoad = function(bSuccess) {
+ checkProgress(); // ensure progress stats are up-to-date
+ // force duration update (doesn't seem to be always accurate)
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.getBytesLoaded(), this.getBytesTotal(), this.duration);
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onload", this.duration > 0 ? 1 : 0); // bSuccess doesn't always seem to work, so check MP3 duration instead.
+ }
+
+ var onID3 = function() {
+ // --- NOTE: BUGGY? ---
+ // --------------------
+ // TODO: Investigate holes in ID3 parsing - for some reason, Album will be populated with Date if empty and date is provided. (?)
+ // ID3V1 seem to parse OK, but "holes" / blanks in ID3V2 data seem to get messed up (eg. missing album gets filled with date.)
+ // iTunes issues: onID3 was not called with a test MP3 encoded with iTunes 7.01, and what appeared to be valid ID3V2 data.
+ // May be related to thumbnails for album art included in MP3 file by iTunes. See http://mabblog.com/blog/?p=33
+ var id3Data = [];
+ var id3Props = [];
+ for (var prop in this.id3) {
+ id3Props.push(prop);
+ id3Data.push(this.id3[prop]);
+ // writeDebug('id3['+prop+']: '+this.id3[prop]);
+ }
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onid3", id3Props, id3Data);
+ // unhook own event handler, prevent second call (can fire twice as data is received - ID3V2 at beginning, ID3V1 at end.)
+ // Therefore if ID3V2 data is received, ID3V1 is ignored.
+ soundObjects[this.sID].onID3 = null;
+ }
+
+ var registerOnComplete = function(sID) {
+ soundObjects[sID].onSoundComplete = function() {
+ checkProgress();
+ this.didJustBeforeFinish = false; // reset
+ ExternalInterface.call(baseJSObject + "['" + sID + "']._onfinish");
+ }
+ }
+
+ var _setPosition = function(sID, nSecOffset, isPaused) {
+ var s = soundObjects[sID];
+ // writeDebug('_setPosition()');
+ s.lastValues.position = s.position;
+ if (s.lastValues.loops > 1 && nSecOffset != 0) {
+ writeDebug('Warning: Looping functionality being disabled due to Flash limitation.');
+ s.lastValues.loops = 1;
+ }
+ s.start(nSecOffset, s.lastValues.nLoops || 1); // start playing at new position
+ if (isPaused) s.stop();
+ }
+
+ var _load = function(sID, sURL, bStream, bAutoPlay, bCheckPolicyFile) {
+ // writeDebug('_load(): '+sID+', '+sURL+', '+bStream+', '+bAutoPlay);
+ if (typeof bAutoPlay == 'undefined') bAutoPlay = false;
+ if (typeof bStream == 'undefined') bStream = true;
+ if (typeof bCheckPolicyFile == 'undefined') bCheckPolicyFile = false;
+ // writeDebug('bStream: '+bStream);
+ // writeDebug('bAutoPlay: '+bAutoPlay);
+ // checkProgress();
+ var s = soundObjects[sID];
+ s.onID3 = onID3;
+ s.onLoad = onLoad;
+ s.loaded = true;
+ s.checkPolicyFile = bCheckPolicyFile;
+ s.loadSound(sURL, bStream);
+ s.didJustBeforeFinish = false;
+ if (bAutoPlay != true) {
+ s.stop(); // prevent default auto-play behaviour
+ } else {
+ writeDebug('auto-play allowed');
+ }
+ registerOnComplete(sID);
+ }
+
+ var _unload = function(sID, sURL) {
+ // effectively "stop" loading by loading a tiny MP3
+ // writeDebug('_unload()');
+ var s = soundObjects[sID];
+ s.onID3 = null;
+ s.onLoad = null;
+ s.loaded = false;
+ s.loadSound(sURL, true);
+ s.stop(); // prevent auto-play
+ s.didJustBeforeFinish = false;
+ }
+
+ var _createSound = function(sID, justBeforeFinishOffset, loops, checkPolicyFile) {
+ var s = new Sound();
+ if (!soundObjects[sID]) {
+ sounds.push(sID);
+ }
+ soundObjects[sID] = s;
+ s.setVolume(100);
+ s.didJustBeforeFinish = false;
+ s.sID = sID;
+ s.paused = false;
+ s.loaded = false;
+ s.justBeforeFinishOffset = justBeforeFinishOffset || 0;
+ s.checkPolicyFile = checkPolicyFile;
+ s.lastValues = {
+ bytes: 0,
+ position: 0,
+ nLoops: loops||1
+ };
+ }
+
+ var _destroySound = function(sID) {
+ // for the power of garbage collection! .. er, Greyskull!
+ var s = (soundObjects[sID] || null);
+ if (!s) return false;
+ for (var i = 0; i < sounds.length; i++) {
+ if (sounds[i] == sID) {
+ sounds.splice(i, 1);
+ break;
+ }
+ }
+ s = null;
+ delete soundObjects[sID];
+ }
+
+ var _stop = function(sID, bStopAll) {
+ // stop this particular instance (or "all", based on parameter)
+ if (bStopAll) {
+ _root.stop();
+ } else {
+ soundObjects[sID].stop();
+ soundObjects[sID].paused = false;
+ soundObjects[sID].didJustBeforeFinish = false;
+ }
+ }
+
+ var _start = function(sID, nLoops, nMsecOffset) {
+ // writeDebug('_start: ' + sID + ', loops: ' + nLoops + ', nMsecOffset: ' + nMsecOffset);
+ registerOnComplete();
+ var s = soundObjects[sID];
+ s.lastValues.paused = false; // reset pause if applicable
+ s.lastValues.nLoops = (nLoops || 1);
+ s.start(nMsecOffset, nLoops);
+ }
+
+ var _pause = function(sID) {
+ // writeDebug('_pause()');
+ var s = soundObjects[sID];
+ if (!s.paused) {
+ // reference current position, stop sound
+ s.paused = true;
+ s.lastValues.position = s.position;
+ // writeDebug('_pause(): position: '+s.lastValues.position);
+ s.stop();
+ } else {
+ // resume playing from last position
+ // writeDebug('resuming - playing at '+s.lastValues.position+', '+s.lastValues.nLoops+' times');
+ s.paused = false;
+ s.start(s.lastValues.position / 1000, s.lastValues.nLoops);
+ }
+ }
+
+ var _setPan = function(sID, nPan) {
+ soundObjects[sID].setPan(nPan);
+ }
+
+ var _setVolume = function(sID, nVol) {
+ soundObjects[sID].setVolume(nVol);
+ }
+
+ var _setPolling = function(bPolling) {
+ pollingEnabled = bPolling;
+ if (timer == null && pollingEnabled) {
+ writeDebug('Enabling polling, ' + timerInterval + ' ms interval');
+ timer = setInterval(checkProgress, timerInterval);
+ } else if (timer && !pollingEnabled) {
+ writeDebug('Disabling polling');
+ clearInterval(timer);
+ timer = null;
+ }
+ }
+
+ // XML handler stuff
+ var parseXML = function(oXML) {
+ var xmlRoot = oXML.firstChild;
+ var xmlAttr = xmlRoot.attributes;
+ var oOptions = {};
+ for (var i = 0, j = xmlRoot.childNodes.length; i < j; i++) {
+ xmlAttr = xmlRoot.childNodes[i].attributes;
+ oOptions = {
+ id: xmlAttr.id,
+ url: xmlRoot.attributes.baseHref + xmlAttr.href,
+ stream: xmlAttr.stream
+ }
+ ExternalInterface.call(baseJSController + ".createSound", oOptions);
+ }
+ }
+
+ var xmlOnloadHandler = function(ok) {
+ if (ok) {
+ writeDebug("XML loaded");
+ parseXML(this);
+ } else {
+ writeDebug('XML load failed');
+ }
+ }
+
+ // ---
+ var _loadFromXML = function(sXmlUrl) {
+ writeDebug("_loadFromXML(" + sXmlUrl + ")");
+ // ExternalInterface.call(baseJSController+"._writeDebug","_loadFromXML("+sXmlUrl+")");
+ // var oXmlHandler = new XMLHandler(sXmlUrl);
+ var oXML = new XML();
+ oXML.ignoreWhite = true;
+ oXML.onLoad = xmlOnloadHandler;
+ writeDebug("Attempting to load XML: " + sXmlUrl);
+ oXML.load(sXmlUrl);
+ }
+
+ var _init = function() {
+
+ // OK now stuff should be available
+ try {
+ flashDebug('Adding ExternalInterface callbacks...');
+ ExternalInterface.addCallback('_load', this, _load);
+ ExternalInterface.addCallback('_unload', this, _unload);
+ ExternalInterface.addCallback('_stop', this, _stop);
+ ExternalInterface.addCallback('_start', this, _start);
+ ExternalInterface.addCallback('_pause', this, _pause);
+ ExternalInterface.addCallback('_setPosition', this, _setPosition);
+ ExternalInterface.addCallback('_setPan', this, _setPan);
+ ExternalInterface.addCallback('_setVolume', this, _setVolume);
+ ExternalInterface.addCallback('_setPolling', this, _setPolling);
+ ExternalInterface.addCallback('_externalInterfaceTest', this, _externalInterfaceTest);
+ ExternalInterface.addCallback('_disableDebug', this, _disableDebug);
+ ExternalInterface.addCallback('_loadFromXML', null, _loadFromXML);
+ ExternalInterface.addCallback('_createSound', this, _createSound);
+ ExternalInterface.addCallback('_destroySound', this, _destroySound);
+ } catch(e) {
+ flashDebug('Fatal: ExternalInterface error: ' + e.toString());
+ }
+ // try to talk to JS, do init etc.
+ _externalInterfaceTest(true);
+ // flashDebug('Init OK');
+ }
+
+ flashDebug('SM2 SWF ' + version + ' ' + version_as);
+
+ if (ExternalInterface.available) {
+ flashDebug('ExternalInterface available');
+ _init();
+ } else {
+ // d'oh! - may be from a corrupt install, ancient (pre-Netscape 6?) browser etc.
+ flashDebug('Fatal: ExternalInterface (Flash <-> JS) not available');
+ }
+
+
+ } // SoundManager2()
+
+ // entry point
+ static function main(mc) {
+ app = new SoundManager2();
+ }
+
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_AS3.as b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_AS3.as new file mode 100755 index 0000000..445de48 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_AS3.as @@ -0,0 +1,970 @@ +/*
+ SoundManager 2: Javascript Sound for the Web
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ Copyright (c) 2007, Scott Schiller. All rights reserved.
+ Code licensed under the BSD License:
+ http://www.schillmania.com/projects/soundmanager2/license.txt
+
+ Flash 9 / ActionScript 3 version
+*/
+
+package {
+
+ import flash.display.Sprite;
+ import flash.events.Event;
+ import flash.events.IOErrorEvent;
+ import flash.events.MouseEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.events.AsyncErrorEvent;
+ import flash.events.NetStatusEvent;
+ import flash.events.TimerEvent;
+ import flash.external.ExternalInterface; // woo
+ import flash.media.Sound;
+ import flash.media.SoundChannel;
+ import flash.media.SoundMixer;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
+ import flash.system.Security;
+ import flash.system.System;
+ import flash.text.TextField;
+ import flash.text.TextFormat;
+ import flash.text.TextFieldAutoSize;
+ import flash.ui.ContextMenu;
+ import flash.ui.ContextMenuItem;
+ import flash.utils.setInterval;
+ import flash.utils.clearInterval;
+ import flash.utils.Dictionary;
+ import flash.utils.Timer;
+ import flash.xml.XMLDocument;
+ import flash.xml.XMLNode;
+
+ public class SoundManager2_AS3 extends Sprite {
+
+ public var version:String = "V2.97a.20101010";
+ public var version_as:String = "(AS3/Flash 9)";
+
+ /*
+ * Cross-domain security options
+ * HTML on foo.com loading .swf hosted on bar.com? Define your "HTML domain" here to allow JS+Flash communication to work.
+ * // allow_xdomain_scripting = true;
+ * // xdomain = "foo.com";
+ * For all domains (possible security risk?), use xdomain = "*"; which ends up as System.security.allowDomain("*");
+ * When loading from HTTPS, use System.security.allowInsecureDomain();
+ * See http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/Security.html#allowDomain()
+ */
+ public var allow_xdomain_scripting:Boolean = false;
+ public var xdomain:String = "*";
+
+ // externalInterface references (for Javascript callbacks)
+ public var baseJSController:String = "soundManager";
+ public var baseJSObject:String = baseJSController + ".sounds";
+
+ // internal objects
+ public var sounds:Array = []; // indexed string array
+ public var soundObjects: Dictionary = new Dictionary(); // associative Sound() object Dictionary type
+ public var timerInterval: uint = 50;
+ public var timerIntervalHighPerformance: uint = 10; // ~30fps (in Safari on OSX, anyway..)
+ public var timer: Timer = null;
+ public var pollingEnabled: Boolean = false; // polling (timer) flag - disabled by default, enabled by JS->Flash call
+ public var debugEnabled: Boolean = true; // Flash debug output enabled by default, disabled by JS call
+ public var flashDebugEnabled: Boolean = false; // Flash internal debug output (write to visible SWF in browser)
+ public var loaded: Boolean = false;
+ public var currentObject: SoundManager2_SMSound_AS3 = null;
+ public var paramList:Object = null;
+ public var messages:Array = [];
+ public var textField: TextField = null;
+ public var textStyle: TextFormat = new TextFormat();
+ public var didSandboxMessage: Boolean = false;
+ public var caughtFatal: Boolean = false;
+
+ public function SoundManager2_AS3() {
+
+ if (allow_xdomain_scripting && xdomain) {
+ Security.allowDomain(xdomain);
+ version_as += ' - cross-domain enabled';
+ }
+
+ this.paramList = this.root.loaderInfo.parameters;
+
+ // <d>
+ if (this.paramList['debug'] == 1) {
+ this.flashDebugEnabled = true;
+ }
+
+ if (this.flashDebugEnabled) {
+ var canvas: Sprite = new Sprite();
+ canvas.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
+ addChild(canvas);
+ }
+ // </d>
+
+ flashDebug('SM2 SWF ' + version + ' ' + version_as);
+
+ // context menu item with version info
+
+ var sm2Menu:ContextMenu = new ContextMenu();
+ var sm2MenuItem:ContextMenuItem = new ContextMenuItem('SoundManager ' + version + ' ' + version_as);
+ sm2MenuItem.enabled = false;
+ sm2Menu.customItems.push(sm2MenuItem);
+ contextMenu = sm2Menu;
+
+ if (ExternalInterface.available) {
+ flashDebug('ExternalInterface available');
+ try {
+ flashDebug('Adding ExternalInterface callbacks...');
+ ExternalInterface.addCallback('_load', _load);
+ ExternalInterface.addCallback('_unload', _unload);
+ ExternalInterface.addCallback('_stop', _stop);
+ ExternalInterface.addCallback('_start', _start);
+ ExternalInterface.addCallback('_pause', _pause);
+ ExternalInterface.addCallback('_setPosition', _setPosition);
+ ExternalInterface.addCallback('_setPan', _setPan);
+ ExternalInterface.addCallback('_setVolume', _setVolume);
+ ExternalInterface.addCallback('_setPolling', _setPolling);
+ ExternalInterface.addCallback('_externalInterfaceTest', _externalInterfaceTest);
+ ExternalInterface.addCallback('_disableDebug', _disableDebug);
+ ExternalInterface.addCallback('_getMemoryUse', _getMemoryUse);
+ ExternalInterface.addCallback('_loadFromXML', _loadFromXML);
+ ExternalInterface.addCallback('_createSound', _createSound);
+ ExternalInterface.addCallback('_destroySound', _destroySound);
+ ExternalInterface.addCallback('_setAutoPlay', _setAutoPlay);
+ } catch(e: Error) {
+ flashDebug('Fatal: ExternalInterface error: ' + e.toString());
+ }
+ } else {
+ flashDebug('Fatal: ExternalInterface (Flash <-> JS) not available');
+ };
+
+ // call after delay, to be safe (ensure callbacks are registered by the time JS is called below)
+ var timer: Timer = new Timer(20, 0);
+ timer.addEventListener(TimerEvent.TIMER, function() : void {
+ timer.reset();
+ _externalInterfaceTest(true);
+ // timer.reset();
+ // flashDebug('Init OK');
+ });
+ timer.start();
+ // delayed, see above
+ // _externalInterfaceTest(true);
+ } // SoundManager2()
+
+ public function flashDebug (txt:String) : void {
+ // <d>
+ messages.push(txt);
+ if (this.flashDebugEnabled) {
+ var didCreate: Boolean = false;
+ textStyle.font = 'Arial';
+ textStyle.size = 12;
+ // 320x240 if no stage dimensions (happens in IE, apparently 0 before stage resize event fires.)
+ var w:Number = this.stage.width?this.stage.width:320;
+ var h:Number = this.stage.height?this.stage.height:240;
+ if (textField == null) {
+ didCreate = true;
+ textField = new TextField();
+ textField.autoSize = TextFieldAutoSize.LEFT;
+ textField.x = 0;
+ textField.y = 0;
+ textField.multiline = true;
+ textField.textColor = 0;
+ textField.wordWrap = true;
+ }
+ textField.htmlText = messages.join('\n');
+ textField.setTextFormat(textStyle);
+ textField.width = w;
+ textField.height = h;
+ if (didCreate) {
+ this.addChild(textField);
+ }
+ }
+ // </d>
+ }
+
+ public function _setAutoPlay(sID:String, autoPlay:Boolean) : void {
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (s) {
+ s.setAutoPlay(autoPlay);
+ }
+ }
+
+ // methods
+ // -----------------------------------
+
+ public function writeDebug (s:String, bTimestamp: Boolean = false) : Boolean {
+ if (!debugEnabled) return false;
+ // <d>
+ ExternalInterface.call(baseJSController + "['_writeDebug']", "(Flash): " + s, null, bTimestamp);
+ // </d>
+ return true;
+ }
+
+ public function _externalInterfaceTest(isFirstCall: Boolean) : Boolean {
+ var sandboxType:String = flash.system.Security['sandboxType'];
+ if (!didSandboxMessage && sandboxType != 'localTrusted' && sandboxType != 'remote') {
+ didSandboxMessage = true;
+ flashDebug('<br><b>Fatal: Security sandbox error: Got "' + sandboxType + '", expected "remote" or "localTrusted".<br>Additional security permissions need to be granted.<br>See <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">flash security settings panel</a> for non-HTTP, eg., file:// use.</b><br>http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html');
+ }
+ try {
+ if (isFirstCall == true) {
+ flashDebug('Testing Flash -> JS...');
+ var d: Date = new Date();
+ ExternalInterface.call(baseJSController + "._externalInterfaceOK", d.getTime());
+ flashDebug('Flash -> JS OK');
+ } else {
+ writeDebug('SM2 SWF ' + version + ' ' + version_as);
+ flashDebug('JS -> Flash OK');
+ ExternalInterface.call(baseJSController + "._setSandboxType", sandboxType);
+ writeDebug('JS to/from Flash OK');
+ }
+ } catch(e: Error) {
+ flashDebug('Fatal: Flash <-> JS error: ' + e.toString());
+ writeDebug('_externalInterfaceTest: Error: ' + e.toString());
+ if (!caughtFatal) {
+ caughtFatal = true;
+ }
+ return false;
+ }
+ return true; // to verify that a call from JS to here, works. (eg. JS receives "true", thus OK.)
+ }
+
+ public function _disableDebug() : void {
+ // prevent future debug calls from Flash going to client (maybe improve performance)
+ writeDebug('_disableDebug()');
+ debugEnabled = false;
+ }
+
+ public function checkLoadProgress(e: Event) : void {
+ try {
+ var oSound:Object = e.target;
+ var bL: int = oSound.bytesLoaded;
+ var bT: int = oSound.bytesTotal;
+ var nD: int = oSound.length || oSound.duration || 0;
+ var sMethod:String = baseJSObject + "['" + oSound.sID + "']._whileloading";
+ ExternalInterface.call(sMethod, bL, bT, nD);
+ if (bL && bT && bL != oSound.lastValues.bytes) {
+ oSound.lastValues.bytes = bL;
+ ExternalInterface.call(sMethod, bL, bT, nD);
+ }
+ } catch(e: Error) {
+ writeDebug('checkLoadProgress(): ' + e.toString());
+ }
+ }
+
+ public function checkProgress() : void {
+ var bL: int = 0;
+ var bT: int = 0;
+ var nD: int = 0;
+ var nP: int = 0;
+ var bufferLength: int = 0;
+ var lP:Number = 0;
+ var rP:Number = 0;
+ var isBuffering:Object = null;
+ var oSound: SoundManager2_SMSound_AS3 = null;
+ var oSoundChannel: flash.media.SoundChannel = null;
+ var sMethod:String = null;
+ var newPeakData: Boolean = false;
+ var newWaveformData: Boolean = false;
+ var newEQData: Boolean = false;
+ var areSoundsInaccessible: Boolean = SoundMixer.areSoundsInaccessible();
+ var isPlaying: Boolean = true; // special case for NetStream when ending
+ var hasNew:Boolean = false;
+ var hasNewLoaded:Boolean = false;
+
+ for (var i: int = 0, j: int = sounds.length; i < j; i++) {
+ oSound = soundObjects[sounds[i]];
+ sMethod = baseJSObject + "['" + sounds[i] + "']._whileloading";
+
+ if (!oSound || !oSound.useEvents || oSound.failed || !oSound.connected) {
+ // various cases for ignoring
+ continue; // if sounds are destructed within event handlers while this loop is running, may be null
+ }
+
+ if (oSound.useNetstream) {
+
+ // Don't do anything if there is no NetStream object yet
+ if (!oSound.ns) {
+ continue;
+ }
+
+ // stream
+ bufferLength = oSound.ns.bufferLength;
+ bL = oSound.ns.bytesLoaded;
+ bT = oSound.ns.bytesTotal;
+ nD = int(oSound.duration || 0); // can sometimes be null with short MP3s? Wack.
+ nP = oSound.ns.time * 1000;
+
+ if (nP != oSound.lastValues.position) {
+ oSound.lastValues.position = nP;
+ hasNew = true;
+ }
+ if (nD > oSound.lastValues.duration) {
+ oSound.lastValues.duration = nD;
+ hasNew = true;
+ }
+ if (bL > oSound.lastValues.bytesLoaded) {
+ oSound.lastValues.bytesLoaded = bL;
+ hasNew = true;
+ }
+ if (bT > oSound.lastValues.bytes) {
+ oSound.lastValues.bytes = bT;
+ hasNew = true;
+ }
+ if (bufferLength != oSound.lastValues.bufferLength) {
+ oSound.lastValues.bufferLength = bufferLength;
+ hasNew = true;
+ }
+
+ // Don't set loaded for streams because bytesLoaded and bytesTotal are always 0
+ // writeDebug('ns: time/duration, bytesloaded/total: '+nP+'/'+nD+', '+bL+'/'+bT);
+ if (oSound.loaded != true && nD > 0 && bL == bT && bL != 0 && bT != 0) {
+ // non-MP3 has loaded
+ oSound.loaded = true;
+ try {
+ ExternalInterface.call(sMethod, bL, bT, nD, bufferLength);
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._onload", oSound.duration > 0 ? 1 : 0);
+ } catch(e: Error) {
+ writeDebug('_whileLoading/_onload error: ' + e.toString());
+ }
+ } else if (oSound.loaded != true && hasNew) {
+ ExternalInterface.call(sMethod, bL, bT, nD, bufferLength);
+ }
+
+ } else {
+
+ // MP3 sound
+ oSoundChannel = oSound.soundChannel;
+ bL = oSound.bytesLoaded;
+ bT = oSound.bytesTotal;
+ nD = int(oSound.length || 0); // can sometimes be null with short MP3s? Wack.
+ isBuffering = oSound.isBuffering;
+
+ if (oSoundChannel) {
+ nP = (oSoundChannel.position || 0);
+ if (oSound.lastValues.loops > 1 && nP > oSound.length) {
+ // round down to nearest loop
+ var playedLoops:Number = Math.floor(nP/oSound.length);
+ nP = nP - (oSound.length*playedLoops);
+ }
+ if (oSound.usePeakData) {
+ lP = int((oSoundChannel.leftPeak) * 1000) / 1000;
+ rP = int((oSoundChannel.rightPeak) * 1000) / 1000;
+ } else {
+ lP = 0;
+ rP = 0;
+ }
+ } else {
+ // stopped, not loaded or feature not used
+ nP = 0;
+ }
+
+ if (nP != oSound.lastValues.position) {
+ oSound.lastValues.position = nP;
+ hasNew = true;
+ }
+
+ if (nD > oSound.lastValues.duration) { // original sound duration * number of sound loops
+ oSound.lastValues.duration = nD;
+ hasNew = true;
+ }
+ if (bL > oSound.lastValues.bytesLoaded) {
+ oSound.lastValues.bytesLoaded = bL;
+ hasNew = true;
+ }
+ if (bT > oSound.lastValues.bytes) {
+ oSound.lastValues.bytes = bT;
+ hasNew = true;
+ hasNewLoaded = true;
+ }
+
+ // loading progress
+ if (hasNewLoaded) {
+ oSound.lastValues.bytes = bL;
+ ExternalInterface.call(sMethod, bL, bT, nD);
+ }
+ }
+ // peak data
+ if (oSoundChannel && oSound.usePeakData) {
+ if (lP != oSound.lastValues.leftPeak) {
+ oSound.lastValues.leftPeak = lP;
+ newPeakData = true;
+ }
+ if (rP != oSound.lastValues.rightPeak) {
+ oSound.lastValues.rightPeak = rP;
+ newPeakData = true;
+ }
+ }
+
+ var newDataError:Boolean = false;
+ var dataErrors:Array = [];
+
+ // special case: Netstream may try to fire whileplaying() after finishing. check that stop hasn't fired.
+ isPlaying = (oSound.didLoad && !oSound.paused && (!oSound.useNetstream || (oSound.useNetstream && oSound.lastNetStatus != "NetStream.Play.Stop"))); // don't update if stream has ended
+
+ // raw waveform + EQ spectrum data
+ if (isPlaying && oSoundChannel || oSound.useNetstream) {
+ if (oSound.useWaveformData) {
+ if (areSoundsInaccessible == false) {
+ try {
+ oSound.getWaveformData();
+ } catch(e: Error) {
+ // this shouldn't happen, but does seem to fire from time to time.
+ writeDebug('getWaveformData() warning: ' + e.toString());
+ }
+ } else if (oSound.handledDataError != true && oSound.ignoreDataError != true) {
+ try {
+ oSound.getWaveformData();
+ } catch(e: Error) {
+ writeDebug('getWaveformData() (waveform data) '+e.toString());
+ // oSound.useWaveformData = false;
+ newDataError = true;
+ dataErrors.push(e.toString());
+ oSound.handledDataError = true;
+ }
+ }
+ }
+ if (oSound.useEQData) {
+ if (areSoundsInaccessible == false) {
+ try {
+ oSound.getEQData();
+ } catch(e: Error) {
+ writeDebug('getEQData() warning: ' + e.toString());
+ newDataError = true;
+ dataErrors.push(e.toString());
+ oSound.handledDataError = true;
+ }
+ } else if (oSound.handledDataError != true && oSound.ignoreDataError != true) {
+ try {
+ oSound.getEQData();
+ } catch(e: Error) {
+ // writeDebug('computeSpectrum() (EQ data) '+e.toString());
+ // oSound.useEQData = false;
+ newDataError = true;
+ dataErrors.push(e.toString());
+ oSound.handledDataError = true;
+ }
+ }
+ }
+ if (oSound.waveformDataArray != oSound.lastValues.waveformDataArray) {
+ oSound.lastValues.waveformDataArray = oSound.waveformDataArray;
+ newWaveformData = true;
+ }
+ if (oSound.eqDataArray != oSound.lastValues.eqDataArray) {
+ oSound.lastValues.eqDataArray = oSound.eqDataArray;
+ newEQData = true;
+ }
+ }
+
+ if (newDataError) {
+ sMethod = baseJSObject + "['" + sounds[i] + "']._ondataerror";
+ var errors:String = dataErrors.join('<br>\n');
+ ExternalInterface.call(sMethod, 'data unavailable: ' + errors);
+ }
+
+ if (typeof nP != 'undefined' && hasNew) { // && isPlaying - removed to allow updates while paused, eg. from setPosition() calls
+
+ // oSound.lastValues.position = nP;
+ sMethod = baseJSObject + "['" + sounds[i] + "']._whileplaying";
+ var waveDataLeft:String = (newWaveformData ? oSound.waveformDataArray.slice(0, 256).join(',') : null);
+ var waveDataRight:String = (newWaveformData ? oSound.waveformDataArray.slice(256).join(',') : null);
+ var eqDataLeft:String = (newEQData ? oSound.eqDataArray.slice(0, 256).join(',') : null);
+ var eqDataRight:String = (newEQData ? oSound.eqDataArray.slice(256).join(',') : null);
+ ExternalInterface.call(sMethod, nP, (newPeakData ? {
+ leftPeak: lP,
+ rightPeak: rP
+ } : null), waveDataLeft, waveDataRight, (newEQData ? {
+ leftEQ: eqDataLeft,
+ rightEQ: eqDataRight
+ } : null));
+ // if position changed, check for near-end
+ if (oSound.didJustBeforeFinish != true && oSound.loaded == true && oSound.justBeforeFinishOffset > 0 && nD - nP <= oSound.justBeforeFinishOffset) {
+ // fully-loaded, near end and haven't done this yet..
+ sMethod = baseJSObject + "['" + sounds[i] + "']._onjustbeforefinish";
+ ExternalInterface.call(sMethod, (nD - nP));
+ oSound.didJustBeforeFinish = true;
+ }
+ }
+
+ // check isBuffering
+ if (!oSound.useNetstream && oSound.isBuffering != oSound.lastValues.isBuffering) {
+ // property has changed
+ oSound.lastValues.isBuffering = oSound.isBuffering;
+ sMethod = baseJSObject + "['" + sounds[i] + "']._onbufferchange";
+ ExternalInterface.call(sMethod, oSound.isBuffering ? 1 : 0);
+ }
+
+ }
+
+ }
+
+ public function onLoadError(oSound:Object) : void {
+ // something went wrong. 404, bad format etc.
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._onload", 0);
+ }
+
+ public function onLoad(e: Event) : void {
+ checkProgress(); // ensure progress stats are up-to-date
+ var oSound:Object = e.target;
+ if (!oSound.useNetstream) { // FLV must also have metadata
+ oSound.loaded = true;
+ // force duration update (doesn't seem to be always accurate)
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._whileloading", oSound.bytesLoaded, oSound.bytesTotal, oSound.length || oSound.duration);
+ // TODO: Determine if loaded or failed - bSuccess?
+ // ExternalInterface.call(baseJSObject+"['"+oSound.sID+"']._onload",bSuccess?1:0);
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._onload", 1);
+ }
+ }
+
+ public function onID3(e: Event) : void {
+
+ // --- NOTE: BUGGY (Flash 8 only? Haven't really checked 9 + 10.) ---
+ // TODO: Investigate holes in ID3 parsing - for some reason, Album will be populated with Date if empty and date is provided. (?)
+ // ID3V1 seem to parse OK, but "holes" / blanks in ID3V2 data seem to get messed up (eg. missing album gets filled with date.)
+ // iTunes issues: onID3 was not called with a test MP3 encoded with iTunes 7.01, and what appeared to be valid ID3V2 data.
+ // May be related to thumbnails for album art included in MP3 file by iTunes. See http://mabblog.com/blog/?p=33
+ try {
+ var oSound:Object = e.target;
+
+ var id3Data:Array = [];
+ var id3Props:Array = [];
+ for (var prop:String in oSound.id3) {
+ id3Props.push(prop);
+ id3Data.push(oSound.id3[prop]);
+ // writeDebug('id3['+prop+']: '+oSound.id3[prop]);
+ }
+ ExternalInterface.call(baseJSObject + "['" + oSound.sID + "']._onid3", id3Props, id3Data);
+ // unhook own event handler, prevent second call (can fire twice as data is received - ID3V2 at beginning, ID3V1 at end.)
+ // Therefore if ID3V2 data is received, ID3V1 is ignored.
+ // soundObjects[oSound.sID].onID3 = null;
+ } catch(e: Error) {
+ writeDebug('onID3(): Unable to get ID3 info for ' + oSound.sID + '.');
+ }
+ oSound.removeEventListener(Event.ID3, onID3);
+ }
+
+ public function registerOnComplete(sID:String) : void {
+ var oSound: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (oSound && oSound.soundChannel) {
+ oSound.soundChannel.addEventListener(Event.SOUND_COMPLETE, function() : void {
+ if (oSound) {
+ oSound.didJustBeforeFinish = false; // reset
+ checkProgress();
+ try {
+ oSound.ignoreDataError = true; // workaround: avoid data error handling for this manual step..
+ oSound.start(0, 1); // go back to 0
+ oSound.soundChannel.stop();
+ } catch(e: Error) {
+ writeDebug('Could not set position on ' + sID + ': ' + e.toString());
+ }
+ oSound.ignoreDataError = false; // ..and reset
+ oSound.handledDataError = false; // reset this flag
+ }
+ // checkProgress();
+ ExternalInterface.call(baseJSObject + "['" + sID + "']._onfinish");
+ });
+ }
+ }
+
+ public function doSecurityError(oSound: SoundManager2_SMSound_AS3, e: SecurityErrorEvent) : void {
+ writeDebug('securityError: ' + e.text);
+ // when this happens, you don't have security rights on the server containing the FLV file
+ // a crossdomain.xml file would fix the problem easily
+ }
+
+ public function _setPosition(sID:String, nSecOffset:Number, isPaused: Boolean) : void {
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (!s) return void;
+ // writeDebug('_setPosition()');
+
+ // stop current channel, start new one.
+ if (s.lastValues) {
+ s.lastValues.position = nSecOffset; // s.soundChannel.position;
+ }
+ if (s.useNetstream) {
+ // Minimize the buffer so playback starts ASAP
+ s.setBuffer(s.getStartBuffer());
+ writeDebug('setPosition: setting buffer to '+s.ns.bufferTime+' secs');
+
+ nSecOffset = nSecOffset > 0 ? nSecOffset / 1000 : 0;
+ writeDebug('setPosition: ' + nSecOffset);
+ s.ns.seek(nSecOffset);
+ checkProgress(); // force UI update
+ } else {
+ if (s.soundChannel) {
+ s.soundChannel.stop();
+ }
+ writeDebug('setPosition: ' + nSecOffset); // +', '+(s.lastValues.loops?s.lastValues.loops:1));
+ if (s.lastValues.loops > 1 && nSecOffset != 0) {
+ writeDebug('Warning: Looping functionality being disabled due to Flash limitation.');
+ s.lastValues.loops = 1;
+ }
+ try {
+ s.start(nSecOffset, s.lastValues.loops || 1); // start playing at new position
+ } catch(e: Error) {
+ writeDebug('Warning: Could not set position on ' + sID + ': ' + e.toString());
+ }
+ checkProgress(); // force UI update
+ try {
+ registerOnComplete(sID);
+ } catch(e: Error) {
+ writeDebug('_setPosition(): Could not register onComplete');
+ }
+ if (isPaused && s.soundChannel) {
+ // writeDebug('_setPosition: stopping (paused) sound');
+ // writeDebug('last position: '+s.lastValues.position+' vs '+s.soundChannel.position);
+ s.soundChannel.stop();
+ }
+ }
+ }
+
+ public function _load(sID:String, sURL:String, bStream: Boolean, bAutoPlay: Boolean, nLoops: Number, bAutoLoad: Boolean, bCheckPolicyFile: Boolean) : void {
+ // writeDebug('_load()');
+ if (typeof bAutoPlay == 'undefined') bAutoPlay = false;
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (!s) return void;
+ var didRecreate: Boolean = false;
+ if (s.didLoad == true) {
+ // need to recreate sound
+ didRecreate = true;
+ writeDebug('recreating sound ' + sID + ' in order to load ' + sURL);
+ var ns:Object = new Object();
+ ns.sID = s.sID;
+ ns.loops = nLoops||1;
+ ns.justBeforeFinishOffset = s.justBeforeFinishOffset;
+ ns.usePeakData = s.usePeakData;
+ ns.useWaveformData = s.useWaveformData;
+ ns.useEQData = s.useEQData;
+ ns.useNetstream = s.useNetstream;
+ ns.bufferTime = s.bufferTime;
+ ns.bufferTimes = s.bufferTimes;
+ ns.serverUrl = s.serverUrl;
+ ns.duration = s.duration;
+ ns.recordStats = s.recordStats;
+ ns.checkPolicyFile = s.checkPolicyFile;
+ ns.useEvents = true;
+ _destroySound(s.sID);
+ _createSound(ns.sID, sURL, ns.justBeforeFinishOffset, ns.usePeakData, ns.useWaveformData, ns.useEQData, ns.useNetstream, ns.bufferTime, ns.loops, ns.serverUrl, ns.duration, bAutoPlay, ns.useEvents, ns.bufferTimes, ns.recordStats, bAutoLoad, ns.checkPolicyFile);
+ s = soundObjects[sID];
+ // writeDebug('Sound object replaced');
+ }
+ checkProgress();
+
+ if (!s.didLoad) {
+ try {
+ s.addEventListener(Event.ID3, onID3);
+ s.addEventListener(Event.COMPLETE, onLoad);
+ } catch(e: Error) {
+ writeDebug('_load(): could not assign ID3/complete event handlers');
+ }
+ }
+
+ // don't try to load if same request already made
+ s.sURL = sURL;
+
+ if (s.useNetstream) {
+ try {
+ s.useEvents = true;
+ s.ns.play(sURL);
+ } catch(e: Error) {
+ writeDebug('_load(): error: ' + e.toString());
+ }
+ } else {
+ try {
+ s.addEventListener(IOErrorEvent.IO_ERROR, function(e: IOErrorEvent) : void {
+ s.doIOError(e);
+ });
+ s.loadSound(sURL, bStream);
+ } catch(e: Error) {
+ // oh well
+ writeDebug('_load: Error loading ' + sURL + '. Flash error detail: ' + e.toString());
+ }
+ }
+
+ s.didJustBeforeFinish = false;
+ }
+
+ public function _unload(sID:String) : void {
+ var s: SoundManager2_SMSound_AS3 = (soundObjects[sID] || null);
+ if (!s) return void;
+ var sURL:String = s.sURL; // save existing sound URL for object recreation
+ try {
+ removeEventListener(Event.ID3, onID3);
+ removeEventListener(Event.COMPLETE, onLoad);
+ } catch(e: Error) {
+ writeDebug('_unload() warn: Could not remove ID3/complete events');
+ }
+ s.paused = false;
+ if (s.soundChannel) {
+ s.soundChannel.stop();
+ }
+ try {
+ if (s.didLoad && !s.loaded && !s.useNetstream) {
+ s.close(); // close stream only if still loading?
+ }
+ } catch(e: Error) {
+ // stream may already have closed if sound loaded, etc.
+ writeDebug(sID + '._unload(): Note: Unable to close stream: ' + e.toString());
+ // oh well
+ }
+ // destroy and recreate Flash sound object, try to reclaim memory
+ // writeDebug('sound._unload(): recreating sound '+sID+' to free memory');
+ if (s.useNetstream) {
+ // writeDebug('_unload(): closing netStream stuff');
+ try {
+ s.removeNetstreamEvents();
+ s.ns.close();
+ s.nc.close();
+ // s.nc = null;
+ // s.ns = null;
+ } catch(e: Error) {
+ // oh well
+ writeDebug('_unload(): caught exception during netConnection/netStream close');
+ }
+ }
+ var ns:Object = new Object();
+ ns.sID = s.sID;
+ ns.loops = s.loops;
+ ns.justBeforeFinishOffset = s.justBeforeFinishOffset;
+ ns.usePeakData = s.usePeakData;
+ ns.useWaveformData = s.useWaveformData;
+ ns.useEQData = s.useEQData;
+ ns.useNetstream = s.useNetstream;
+ ns.bufferTime = s.bufferTime;
+ ns.bufferTimes = s.bufferTimes;
+ ns.serverUrl = s.serverUrl;
+ ns.duration = s.duration;
+ ns.autoPlay = s.autoPlay;
+ ns.recordStats = s.recordStats;
+ ns.autoLoad = s.autoLoad;
+ ns.checkPolicyFile = s.checkPolicyFile;
+ _destroySound(s.sID);
+ _createSound(ns.sID, sURL, ns.justBeforeFinishOffset, ns.usePeakData, ns.useWaveformData, ns.useEQData, ns.useNetstream, ns.bufferTime, ns.loops, ns.serverUrl, ns.duration, ns.autoPlay, false, ns.bufferTimes, ns.recordStats, ns.autoLoad, ns.checkPolicyFile); // false: don't allow events just yet
+ soundObjects[sID].connected = true; // fake it?
+ writeDebug(s.sID + '.unload(): ok');
+ }
+
+ public function _createSound(sID:String, sURL:String, justBeforeFinishOffset: int, usePeakData: Boolean, useWaveformData: Boolean, useEQData: Boolean, useNetstream: Boolean, bufferTime:Number, loops:Number, serverUrl:String, duration:Number, autoPlay:Boolean, useEvents:Boolean, bufferTimes:Array, recordStats:Boolean, autoLoad:Boolean, checkPolicyFile:Boolean) : void {
+ var s: SoundManager2_SMSound_AS3 = new SoundManager2_SMSound_AS3(this, sID, sURL, usePeakData, useWaveformData, useEQData, useNetstream, bufferTime, serverUrl, duration, autoPlay, useEvents, bufferTimes, recordStats, autoLoad, checkPolicyFile);
+ if (!soundObjects[sID]) {
+ sounds.push(sID);
+ }
+ soundObjects[sID] = s;
+ this.currentObject = s;
+ s.didJustBeforeFinish = false;
+ s.sID = sID;
+ s.sURL = sURL;
+ s.paused = false;
+ s.loaded = false;
+ s.justBeforeFinishOffset = justBeforeFinishOffset || 0;
+ s.checkPolicyFile = checkPolicyFile;
+ s.lastValues = {
+ bytes: 0,
+ position: 0,
+ loops: loops||1,
+ leftPeak: 0,
+ rightPeak: 0,
+ bufferLength: 0
+ };
+ }
+
+ public function _destroySound(sID:String) : void {
+ // for the power of garbage collection! .. er, Greyskull!
+ var s: SoundManager2_SMSound_AS3 = (soundObjects[sID] || null);
+ if (!s) return void;
+ // try to unload the sound
+ for (var i: int = 0, j: int = sounds.length; i < j; i++) {
+ if (sounds[i] == sID) {
+ sounds.splice(i, 1);
+ break;
+ }
+ }
+ if (s.soundChannel) {
+ s.soundChannel.stop();
+ }
+ // if is a movie, remove that as well.
+ if (s.useNetstream) {
+ // s.nc.client = null;
+ try {
+ s.removeNetstreamEvents();
+ // s.nc.removeEventListener(NetStatusEvent.NET_STATUS, s.doNetStatus);
+ } catch(e: Error) {
+ writeDebug('_destroySound(): Events already removed from netStream/netConnection?');
+ }
+ if (s.didLoad) {
+ // TODO: figure out if stream is still open first, can't close an already-closed stream.
+ try {
+ s.ns.close();
+ s.nc.close();
+ } catch(e: Error) {
+ // oh well
+ writeDebug('_destroySound(): caught exception: '+e.toString());
+ }
+ }
+ } else if (s.didLoad) {
+ // non-netstream case
+ try {
+ s.close(); // close stream only if still loading?
+ } catch(e: Error) {
+ // oh well
+ }
+ }
+ s = null;
+ soundObjects[sID] = null;
+ delete soundObjects[sID];
+ }
+
+ public function _stop(sID:String, bStopAll: Boolean) : void {
+ // stop this particular instance (or "all", based on parameter)
+ if (bStopAll) {
+ SoundMixer.stopAll();
+ } else {
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (!s) return void;
+ if (s.useNetstream && s.ns) {
+ s.ns.pause();
+ } else if (s.soundChannel) {
+ s.soundChannel.stop();
+ }
+ s.paused = false;
+ s.didJustBeforeFinish = false;
+ }
+ }
+
+ public function _start(sID:String, nLoops: int, nMsecOffset: int) : void {
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (!s) return void;
+ writeDebug('start: ' + nMsecOffset+(nLoops?', loops: '+nLoops:''));
+ s.lastValues.paused = false; // reset pause if applicable
+ s.lastValues.loops = (nLoops || 1);
+ if (!s.useNetstream) {
+ s.lastValues.position = nMsecOffset;
+ }
+ s.handledDataError = false; // reset this flag
+ try {
+ s.start(nMsecOffset, nLoops);
+ } catch(e: Error) {
+ writeDebug('Could not start ' + sID + ': ' + e.toString());
+ }
+ try {
+ registerOnComplete(sID);
+ } catch(e: Error) {
+ writeDebug('_start(): registerOnComplete failed');
+ }
+ }
+
+ public function _pause(sID:String) : void {
+ // writeDebug('_pause()');
+ var s: SoundManager2_SMSound_AS3 = soundObjects[sID];
+ if (!s) return void;
+ // writeDebug('s.paused: '+s.paused);
+ if (!s.paused) {
+ // reference current position, stop sound
+ s.paused = true;
+ // writeDebug('_pause(): position: '+s.lastValues.position);
+ if (s.useNetstream) {
+ if (s.ns) {
+ s.lastValues.position = s.ns.time;
+ s.ns.pause();
+ } else if (s.autoPlay) {
+ s.setAutoPlay(false);
+ }
+ } else {
+ if (s.soundChannel) {
+ s.lastValues.position = s.soundChannel.position;
+ s.soundChannel.stop();
+ }
+ }
+ } else {
+ // resume playing from last position
+ // writeDebug('resuming - playing at '+s.lastValues.position+', '+s.lastValues.loops+' times');
+ s.paused = false;
+ if (s.useNetstream) {
+ s.ns.resume();
+ } else {
+ s.start(s.lastValues.position, s.lastValues.loops);
+ }
+ try {
+ registerOnComplete(sID);
+ } catch(e: Error) {
+ writeDebug('_pause(): registerOnComplete() failed');
+ }
+ }
+ }
+
+ public function _setPan(sID:String, nPan:Number) : void {
+ if (soundObjects[sID]) {
+ soundObjects[sID].setPan(nPan);
+ }
+ }
+
+ public function _setVolume(sID:String, nVol:Number) : void {
+ // writeDebug('_setVolume: '+nVol);
+ if (soundObjects[sID]) {
+ soundObjects[sID].setVolume(nVol);
+ }
+ }
+
+ public function _setPolling(bPolling: Boolean = false, bUseHighPerformanceTimer: Boolean = false) : void {
+ pollingEnabled = bPolling;
+ if (timer == null && pollingEnabled) {
+ var nTimerInterval: uint = (bUseHighPerformanceTimer ? timerIntervalHighPerformance : timerInterval);
+ writeDebug('Enabling polling, ' + nTimerInterval + ' ms interval');
+ timer = new Timer(nTimerInterval, 0);
+ timer.addEventListener(TimerEvent.TIMER, function() : void {
+ checkProgress();
+ }); // direct reference eg. checkProgress doesn't work? .. odd.
+ timer.start();
+ } else if (timer && !pollingEnabled) {
+ writeDebug('Disabling polling');
+ // flash.utils.clearInterval(timer);
+ timer.reset();
+ }
+ }
+
+ public function _getMemoryUse() : String {
+ return System.totalMemory.toString();
+ }
+
+ // XML handler stuff
+ public function _loadFromXML(sURL:String) : void {
+ var loader: URLLoader = new URLLoader();
+ loader.addEventListener(Event.COMPLETE, parseXML);
+ writeDebug('Attempting to load XML: ' + sURL);
+ try {
+ loader.load(new URLRequest(sURL));
+ } catch(e: Error) {
+ writeDebug('Error loading XML: ' + e.toString());
+ }
+ }
+
+ public function parseXML(e: Event) : void {
+ try {
+ var oXML: XMLDocument = new XMLDocument();
+ oXML.ignoreWhite = true;
+ oXML.parseXML(e.target.data);
+ var xmlRoot: XMLNode = oXML.firstChild;
+ var xmlAttr:Object = xmlRoot.attributes;
+ var oOptions:Object = {};
+ var i: int = 0;
+ var j: int = 0;
+ for (i = 0, j = xmlRoot.childNodes.length; i < j; i++) {
+ xmlAttr = xmlRoot.childNodes[i].attributes;
+ oOptions = {
+ id: xmlAttr.id,
+ url: xmlRoot.attributes.baseHref + xmlAttr.href,
+ stream: xmlAttr.stream
+ }
+ ExternalInterface.call(baseJSController + ".createSound", oOptions);
+ }
+ } catch(e: Error) {
+ writeDebug('Error parsing XML: ' + e.toString());
+ }
+ }
+
+ // -----------------------------------
+ // end methods
+ }
+
+ // package
+
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_SMSound_AS3.as b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_SMSound_AS3.as new file mode 100755 index 0000000..f9a8c35 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/SoundManager2_SMSound_AS3.as @@ -0,0 +1,597 @@ +/*
+ SoundManager 2: Javascript Sound for the Web
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ Copyright (c) 2007, Scott Schiller. All rights reserved.
+ Code licensed under the BSD License:
+ http://www.schillmania.com/projects/soundmanager2/license.txt
+
+ Flash 9 / ActionScript 3 version
+*/
+
+package {
+
+ import flash.external.*;
+ import flash.events.*;
+ import flash.media.Sound;
+ import flash.media.SoundChannel;
+ import flash.media.SoundLoaderContext;
+ import flash.media.SoundTransform;
+ import flash.media.SoundMixer;
+ import flash.net.URLRequest;
+ import flash.utils.ByteArray;
+ import flash.utils.getTimer;
+ import flash.net.NetConnection;
+ import flash.net.NetStream;
+
+ public class SoundManager2_SMSound_AS3 extends Sound {
+
+ public var sm: SoundManager2_AS3 = null;
+ // externalInterface references (for Javascript callbacks)
+ public var baseJSController: String = "soundManager";
+ public var baseJSObject: String = baseJSController + ".sounds";
+ public var soundChannel: SoundChannel = new SoundChannel();
+ public var urlRequest: URLRequest;
+ public var soundLoaderContext: SoundLoaderContext;
+ public var waveformData: ByteArray = new ByteArray();
+ public var waveformDataArray: Array = [];
+ public var eqData: ByteArray = new ByteArray();
+ public var eqDataArray: Array = [];
+ public var usePeakData: Boolean = false;
+ public var useWaveformData: Boolean = false;
+ public var useEQData: Boolean = false;
+ public var sID: String;
+ public var sURL: String;
+ public var justBeforeFinishOffset: int;
+ public var didJustBeforeFinish: Boolean;
+ public var didFinish: Boolean;
+ public var loaded: Boolean;
+ public var connected: Boolean;
+ public var failed: Boolean;
+ public var paused: Boolean;
+ public var finished: Boolean;
+ public var duration: Number;
+ public var handledDataError: Boolean = false;
+ public var ignoreDataError: Boolean = false;
+ public var autoPlay: Boolean = false;
+ public var autoLoad: Boolean = false;
+ public var pauseOnBufferFull: Boolean = true;
+ public var loops: Number = 1;
+ public var lastValues: Object = {
+ bytes: 0,
+ position: 0,
+ volume: 100,
+ pan: 0,
+ loops: 1,
+ leftPeak: 0,
+ rightPeak: 0,
+ waveformDataArray: null,
+ eqDataArray: null,
+ isBuffering: null,
+ bufferLength: 0
+ };
+ public var didLoad: Boolean = false;
+ public var useEvents: Boolean = false;
+ public var sound: Sound = new Sound();
+
+ public var cc: Object;
+ public var nc: NetConnection;
+ public var ns: NetStream = null;
+ public var st: SoundTransform;
+ public var useNetstream: Boolean;
+ public var bufferTime: Number = 3; // previously 0.1
+ public var bufferTimes: Array; // an array of integers (for specifying multiple buffers)
+ public var lastNetStatus: String = null;
+ public var serverUrl: String = null;
+
+ public var start_time: Number;
+ public var connect_time: Number;
+ public var play_time: Number;
+ public var recordStats: Boolean = false;
+ public var checkPolicyFile:Boolean = false;
+
+ public function SoundManager2_SMSound_AS3(oSoundManager: SoundManager2_AS3, sIDArg: String = null, sURLArg: String = null, usePeakData: Boolean = false, useWaveformData: Boolean = false, useEQData: Boolean = false, useNetstreamArg: Boolean = false, netStreamBufferTime: Number = 1, serverUrl: String = null, duration: Number = 0, autoPlay: Boolean = false, useEvents: Boolean = false, bufferTimes: Array = null, recordStats: Boolean = false, autoLoad: Boolean = false, checkPolicyFile: Boolean = false) {
+ this.sm = oSoundManager;
+ this.sID = sIDArg;
+ this.sURL = sURLArg;
+ this.usePeakData = usePeakData;
+ this.useWaveformData = useWaveformData;
+ this.useEQData = useEQData;
+ this.urlRequest = new URLRequest(sURLArg);
+ this.justBeforeFinishOffset = 0;
+ this.didJustBeforeFinish = false;
+ this.didFinish = false; // non-MP3 formats only
+ this.loaded = false;
+ this.connected = false;
+ this.failed = false;
+ this.finished = false;
+ this.soundChannel = null;
+ this.lastNetStatus = null;
+ this.useNetstream = useNetstreamArg;
+ this.serverUrl = serverUrl;
+ this.duration = duration;
+ this.recordStats = recordStats;
+ this.useEvents = useEvents;
+ this.autoLoad = autoLoad;
+ if (netStreamBufferTime) {
+ this.bufferTime = netStreamBufferTime;
+ }
+ // Use bufferTimes instead of bufferTime
+ if (bufferTimes !== null) {
+ this.bufferTimes = bufferTimes;
+ } else {
+ this.bufferTimes = [this.bufferTime];
+ }
+ setAutoPlay(autoPlay);
+ if (recordStats) {
+ this.start_time = getTimer();
+ }
+ this.checkPolicyFile = checkPolicyFile;
+
+ writeDebug('SoundManager2_SMSound_AS3: Got duration: '+duration+', autoPlay: '+autoPlay);
+
+ if (this.useNetstream) {
+
+ this.cc = new Object();
+ this.nc = new NetConnection();
+
+ // Handle FMS bandwidth check callback.
+ // @see onBWDone
+ // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
+ // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
+ this.nc.client = this;
+
+ // TODO: security/IO error handling
+ // this.nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
+ nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
+
+ if (this.serverUrl != null) {
+ writeDebug('SoundManager2_SMSound_AS3: NetConnection: connecting to server ' + this.serverUrl + '...');
+ }
+ this.nc.connect(serverUrl);
+ } else {
+ this.connect_time = this.start_time;
+ this.connected = true;
+ }
+
+ }
+
+ public function netStatusHandler(event:NetStatusEvent):void {
+
+ if (this.useEvents) {
+ writeDebug('netStatusHandler: '+event.info.code);
+ }
+
+ switch (event.info.code) {
+
+ case "NetConnection.Connect.Success":
+ writeDebug('NetConnection: connected');
+ try {
+ this.ns = new NetStream(this.nc);
+ this.ns.checkPolicyFile = this.checkPolicyFile;
+ // bufferTime reference: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/NetStream.html#bufferTime
+ this.ns.bufferTime = getStartBuffer(); // set to 0.1 or higher. 0 is reported to cause playback issues with static files.
+ this.st = new SoundTransform();
+ this.cc.onMetaData = this.metaDataHandler;
+ this.ns.client = this.cc;
+ this.ns.receiveAudio(true);
+ this.addNetstreamEvents();
+
+ this.connected = true;
+ if (recordStats) {
+ this.recordConnectTime();
+ }
+ if (this.useEvents) {
+ writeDebug('firing _onconnect for '+this.sID);
+ ExternalInterface.call(this.sm.baseJSObject + "['" + this.sID + "']._onconnect", 1);
+ }
+ } catch(e: Error) {
+ this.failed = true;
+ writeDebug('netStream error: ' + e.toString());
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
+ }
+ break;
+
+ case "NetStream.Play.StreamNotFound":
+ this.failed = true;
+ writeDebug("NetConnection: Stream not found!");
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Stream not found!', event.info.level, event.info.code);
+ break;
+
+ // This is triggered when the sound loses the connection with the server.
+ // In some cases one could just try to reconnect to the server and resume playback.
+ // However for streams protected by expiring tokens, I don't think that will work.
+ //
+ // Flash says that this is not an error code, but a status code...
+ // should this call the onFailure handler?
+ case "NetConnection.Connect.Closed":
+ this.failed = true;
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection closed!', event.info.level, event.info.code);
+ writeDebug("NetConnection: Connection closed!");
+ break;
+
+ // Couldn't establish a connection with the server. Attempts to connect to the server
+ // can also fail if the permissible number of socket connections on either the client
+ // or the server computer is at its limit. This also happens when the internet
+ // connection is lost.
+ case "NetConnection.Connect.Failed":
+ this.failed = true;
+ writeDebug("NetConnection: Connection failed! Lost internet connection? Try again... Description: " + event.info.description);
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
+ break;
+
+ // A change has occurred to the network status. This could mean that the network
+ // connection is back, or it could mean that it has been lost...just try to resume
+ // playback.
+
+ // KJV: Can't use this yet because by the time you get your connection back the
+ // song has reached it's maximum retries, so it doesn't retry again. We need
+ // a new _ondisconnect handler.
+ //case "NetConnection.Connect.NetworkChange":
+ // this.failed = true;
+ // writeDebug("NetConnection: Network connection status changed");
+ // ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Reconnecting...');
+ // break;
+
+ // Consider everything else a failure...
+ default:
+ this.failed = true;
+ writeDebug("NetConnection: got unhandled code '" + event.info.code + "'! Description: " + event.info.description);
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', event.info.level, event.info.code);
+ break;
+ }
+
+ }
+
+ // Set the buffer size on the current NetSream instance to <tt>buffer</tt> secs
+ // Only set the buffer if it's different to the current buffer.
+ public function setBuffer(buffer: int) : void {
+ if (buffer != this.ns.bufferTime) {
+ this.ns.bufferTime = buffer;
+ writeDebug('set buffer to '+this.ns.bufferTime+' secs');
+ }
+ }
+
+ // Return the size of the starting buffer.
+ public function getStartBuffer() : int {
+ return this.bufferTimes[0];
+ }
+
+ // Return the size of the next buffer, given the size of the current buffer.
+ // If there are no more buffers, returns the current buffer size.
+ public function getNextBuffer(current_buffer: int) : int {
+ var i: int = bufferTimes.indexOf(current_buffer);
+ if (i == -1) {
+ // Couldn't find the buffer, start from the start buffer size
+ return getStartBuffer();
+ } else if (i + 1 >= bufferTimes.length) {
+ // Last (or only) buffer, keep the current buffer
+ return current_buffer;
+ } else {
+ return this.bufferTimes[i+1];
+ }
+ }
+
+ public function writeDebug (s: String, bTimestamp: Boolean = false) : Boolean {
+ return this.sm.writeDebug (s, bTimestamp); // defined in main SM object
+ }
+
+ public function metaDataHandler(infoObject: Object) : void {
+ /*
+ var data:String = new String();
+ for (var prop:* in infoObject) {
+ data += prop+': '+infoObject[prop]+' ';
+ }
+ ExternalInterface.call('soundManager._writeDebug','Metadata: '+data);
+ */
+ if (!this.loaded) {
+ // writeDebug('not loaded yet: '+this.ns.bytesLoaded+', '+this.ns.bytesTotal+', '+infoObject.duration*1000);
+ // TODO: investigate loaded/total values
+ // ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.ns.bytesLoaded, this.ns.bytesTotal, infoObject.duration*1000);
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.bytesLoaded, this.bytesTotal, (infoObject.duration || this.duration))
+ }
+ this.duration = infoObject.duration * 1000;
+ // null this out for the duration of this object's existence.
+ // it may be called multiple times.
+ this.cc.onMetaData = function(infoObject: Object) : void {}
+
+ }
+
+ public function getWaveformData() : void {
+ // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
+ SoundMixer.computeSpectrum(this.waveformData, false, 0); // sample wave data at 44.1 KHz
+ this.waveformDataArray = [];
+ for (var i: int = 0, j: int = this.waveformData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
+ this.waveformDataArray.push(int(this.waveformData.readFloat() * 1000) / 1000);
+ }
+ }
+
+ public function getEQData() : void {
+ // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
+ SoundMixer.computeSpectrum(this.eqData, true, 0); // sample EQ data at 44.1 KHz
+ this.eqDataArray = [];
+ for (var i: int = 0, j: int = this.eqData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
+ this.eqDataArray.push(int(this.eqData.readFloat() * 1000) / 1000);
+ }
+ }
+
+ public function start(nMsecOffset: int, nLoops: int) : void {
+ this.useEvents = true;
+ if (this.useNetstream) {
+
+ writeDebug("SMSound::start nMsecOffset "+ nMsecOffset+ ' nLoops '+nLoops + ' current bufferTime '+this.ns.bufferTime+' current bufferLength '+this.ns.bufferLength+ ' this.lastValues.position '+this.lastValues.position);
+
+ this.cc.onMetaData = this.metaDataHandler;
+
+ // Don't seek if we don't have to because it destroys the buffer
+ var set_position:Boolean = this.lastValues.position != null && this.lastValues.position != nMsecOffset;
+ if (set_position) {
+ // Minimize the buffer so playback starts ASAP
+ this.setBuffer(this.getStartBuffer());
+ }
+
+ if (this.paused) {
+ writeDebug('start: resuming from paused state');
+ this.ns.resume(); // get the sound going again
+ if (!this.didLoad) {
+ this.didLoad = true;
+ }
+ this.paused = false;
+ } else if (!this.didLoad) {
+ writeDebug('start: !didLoad - playing '+this.sURL);
+ this.ns.play(this.sURL);
+ this.didLoad = true;
+ this.paused = false;
+ } else {
+ // previously loaded, perhaps stopped/finished. play again?
+ writeDebug('playing again (not paused, didLoad = true)');
+ this.ns.play(this.sURL);
+ }
+
+ // KJV seek after calling play otherwise some streams get a NetStream.Seek.Failed
+ // Should only apply to the !didLoad case, but do it for all for simplicity.
+ // nMsecOffset is in milliseconds for streams but in seconds for progressive
+ // download.
+ if (set_position) {
+ this.ns.seek(this.serverUrl ? nMsecOffset / 1000 : nMsecOffset);
+ this.lastValues.position = nMsecOffset; // https://gist.github.com/1de8a3113cf33d0cff67
+ }
+
+ // this.ns.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+ this.applyTransform();
+
+ } else {
+ // writeDebug('start: seeking to '+nMsecOffset+', '+nLoops+(nLoops==1?' loop':' loops'));
+ this.soundChannel = this.play(nMsecOffset, nLoops);
+ this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+ this.applyTransform();
+ }
+
+ }
+
+ private function _onfinish() : void {
+ this.removeEventListener(Event.SOUND_COMPLETE, _onfinish);
+ }
+
+ public function loadSound(sURL: String, bStream: Boolean) : void {
+ if (this.useNetstream) {
+ this.useEvents = true;
+ if (this.didLoad != true) {
+ ExternalInterface.call('loadSound(): loading ' + this.sURL);
+ this.ns.play(this.sURL);
+ this.didLoad = true;
+ }
+ // this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+ this.applyTransform();
+ } else {
+ try {
+ this.didLoad = true;
+ this.urlRequest = new URLRequest(sURL);
+ this.soundLoaderContext = new SoundLoaderContext(1000, this.checkPolicyFile); // check for policy (crossdomain.xml) file on remote domains - http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundLoaderContext.html
+ this.load(this.urlRequest, this.soundLoaderContext);
+ } catch(e: Error) {
+ writeDebug('error during loadSound(): ' + e.toString());
+ }
+ }
+ }
+
+ public function setAutoPlay(autoPlay: Boolean) : void {
+ if (!this.serverUrl) {
+ // don't apply to non-RTMP, netstream stuff.
+ this.autoPlay = true;
+ this.pauseOnBufferFull = false;
+ } else {
+ this.autoPlay = autoPlay;
+ if (this.autoPlay) {
+ this.pauseOnBufferFull = false;
+ // writeDebug('ignoring pauseOnBufferFull because autoPlay is on');
+ } else if (!this.autoPlay) {
+ this.pauseOnBufferFull = true;
+ // writeDebug('pausing on buffer full because autoPlay is off');
+ }
+ }
+ }
+
+ public function setVolume(nVolume: Number) : void {
+ this.lastValues.volume = nVolume / 100;
+ this.applyTransform();
+ }
+
+ public function setPan(nPan: Number) : void {
+ this.lastValues.pan = nPan / 100;
+ this.applyTransform();
+ }
+
+ public function applyTransform() : void {
+ var st: SoundTransform = new SoundTransform(this.lastValues.volume, this.lastValues.pan);
+ if (this.useNetstream) {
+ if (this.ns) {
+ this.ns.soundTransform = st;
+ } else {
+ // writeDebug('applyTransform(): Note: No active netStream');
+ }
+ } else if (this.soundChannel) {
+ this.soundChannel.soundTransform = st; // new SoundTransform(this.lastValues.volume, this.lastValues.pan);
+ }
+ }
+
+ public function recordPlayTime() : void {
+ this.play_time = Math.round(getTimer() - (this.start_time + this.connect_time));
+ writeDebug('Play took '+ this.play_time + ' ms');
+ // We must now have both stats, call the onstats callback
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onstats", {
+ play_time: this.play_time,
+ connect_time: this.connect_time
+ });
+ // Stop tracking any stats for this object
+ this.recordStats = false;
+ }
+
+ public function recordConnectTime() : void {
+ this.connect_time = Math.round(getTimer() - this.start_time);
+ writeDebug('Connect took '+ this.connect_time + ' ms');
+ }
+
+ // Handle FMS bandwidth check callback.
+ // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
+ // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
+ public function onBWDone() : void {
+ // writeDebug('onBWDone: called and ignored');
+ }
+
+ // NetStream client callback. Invoked when the song is complete.
+ public function onPlayStatus(info:Object):void {
+ writeDebug('onPlayStatus called with '+info);
+ switch(info.code) {
+ case "NetStream.Play.Complete":
+ writeDebug('Song has finished!');
+ break;
+ }
+ }
+
+ public function doIOError(e: IOErrorEvent) : void {
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onload", 0); // call onload, assume it failed.
+ // there was a connection drop, a loss of internet connection, or something else wrong. 404 error too.
+ }
+
+ public function doAsyncError(e: AsyncErrorEvent) : void {
+ writeDebug('asyncError: ' + e.text);
+ }
+
+ public function doNetStatus(e: NetStatusEvent) : void {
+
+ // Handle failures
+ if (e.info.code == "NetStream.Failed"
+ || e.info.code == "NetStream.Play.FileStructureInvalid"
+ || e.info.code == "NetStream.Play.StreamNotFound") {
+
+ this.lastNetStatus = e.info.code;
+ writeDebug('netStatusEvent: ' + e.info.code);
+ this.failed = true;
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', e.info.level, e.info.code);
+ return;
+ }
+
+ writeDebug('netStatusEvent: ' + e.info.code); // KJV we like to see all events
+
+ // When streaming, Stop is called when buffering stops, not when the stream is actually finished.
+ // @see http://www.actionscript.org/forums/archive/index.php3/t-159194.html
+ if (e.info.code == "NetStream.Play.Stop") {
+
+ if (!this.useNetstream) {
+ // finished playing
+ // this.didFinish = true; // will be reset via JS callback
+ this.didJustBeforeFinish = false; // reset
+ writeDebug('calling onfinish for a sound');
+ // reset the sound? Move back to position 0?
+ this.sm.checkProgress();
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
+ }
+
+ } else if (e.info.code == "NetStream.Play.Start" || e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Buffer.Full") {
+
+ // First time buffer has filled. Print debugging output.
+ if (this.recordStats && !this.play_time) {
+ this.recordPlayTime();
+ }
+
+ // RTMP case..
+ // We wait for the buffer to fill up before pausing the just-loaded song because only if the
+ // buffer is full will the song continue to buffer until the user hits play.
+ if (this.serverUrl && e.info.code == "NetStream.Buffer.Full" && this.pauseOnBufferFull) {
+ this.ns.pause();
+ this.paused = true;
+ this.pauseOnBufferFull = false;
+ // Call pause in JS. This will call back to us to pause again, but
+ // that should be harmless.
+ writeDebug('Pausing song because buffer is full');
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "'].pause", false);
+ }
+
+ // The buffer is full. Increase its size if possible.
+ // Double buffering has not been shown to cause false starts, so this is safe.
+ if (e.info.code == "NetStream.Buffer.Full") {
+ var next_buffer: int = this.getNextBuffer(this.ns.bufferTime);
+ if (next_buffer != this.ns.bufferTime) {
+ this.setBuffer(next_buffer);
+ }
+ }
+
+ var isNetstreamBuffering: Boolean = (e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Play.Start");
+ // assume buffering when we start playing, eg. initial load.
+ if (isNetstreamBuffering != this.lastValues.isBuffering) {
+ this.lastValues.isBuffering = isNetstreamBuffering;
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onbufferchange", this.lastValues.isBuffering ? 1 : 0);
+ }
+
+ // We can detect the end of the stream when Play.Stop is called followed by Buffer.Empty.
+ // However, if you pause and let the whole song buffer, Buffer.Flush is called followed by
+ // Buffer.Empty, so handle that case too.
+ //
+ // Ignore this event if we are more than 5 seconds from the end of the song.
+ if (e.info.code == "NetStream.Buffer.Empty" && (this.lastNetStatus == 'NetStream.Play.Stop' || this.lastNetStatus == 'NetStream.Buffer.Flush')) {
+ if (this.duration && (this.ns.time * 1000) < (this.duration - 5000)) {
+ writeDebug('Ignoring Buffer.Empty because this is too early to be the end of the stream! (sID: '+this.sID+', time: '+(this.ns.time*1000)+', duration: '+this.duration+')');
+ } else {
+ this.didJustBeforeFinish = false; // reset
+ this.finished = true;
+ writeDebug('calling onfinish for sound '+this.sID);
+ this.sm.checkProgress();
+ ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
+ }
+
+ } else if (e.info.code == "NetStream.Buffer.Empty") {
+
+ // The buffer is empty. Start from the smallest buffer again.
+ this.setBuffer(this.getStartBuffer());
+ }
+ }
+
+ // Remember the last NetStatus event
+ this.lastNetStatus = e.info.code;
+ }
+
+ // KJV The sound adds some of its own netstatus handlers so we don't need to do it here.
+ public function addNetstreamEvents() : void {
+ ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
+ ns.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
+ ns.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
+ }
+
+ public function removeNetstreamEvents() : void {
+ ns.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
+ ns.removeEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
+ ns.addEventListener(NetStatusEvent.NET_STATUS, dummyNetStatusHandler);
+ ns.removeEventListener(IOErrorEvent.IO_ERROR, doIOError);
+ // KJV Stop listening for NetConnection events on the sound
+ nc.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
+ }
+
+ // Prevents possible 'Unhandled NetStatusEvent' condition if a sound is being
+ // destroyed and interacted with at the same time.
+ public function dummyNetStatusHandler(e: NetStatusEvent) : void {
+ // Don't do anything
+ }
+ }
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.bat b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.bat new file mode 100755 index 0000000..fcab423 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.bat @@ -0,0 +1,5 @@ +@REM this builds the soundmanager 2 SWF from source + +mtasc -swf ../swf/soundmanager2_debug.swf -main -header 16:16:30 SoundManager2.as -version 8 +@pause + diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.sh b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.sh new file mode 100755 index 0000000..8857d15 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash8.sh @@ -0,0 +1,2 @@ +#!/bin/bash +/Applications/mtasc/mtasc -swf ../swf/soundmanager2_debug.swf -main -header 16:16:30 SoundManager2.as -version 8 diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.bat b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.bat new file mode 100755 index 0000000..ed63934 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.bat @@ -0,0 +1,4 @@ +@REM this builds the soundmanager 2 SWF from source +@REM using mxmlc from the Adobe open-source Flex SDK + +c:\progra~1\flexsdk\bin\mxmlc -debug=true -use-network=false -static-link-runtime-shared-libraries=true -optimize=true -o ../swf/soundmanager2_flash9_debug.swf -file-specs SoundManager2_AS3.as diff --git a/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.sh b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.sh new file mode 100755 index 0000000..ec6041c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/src/make-flash9.sh @@ -0,0 +1,2 @@ +#!/bin/bash +/Applications/flexsdk/bin/mxmlc -debug=true -static-link-runtime-shared-libraries=true -optimize=true -o ../swf/soundmanager2_flash9_debug.swf -file-specs SoundManager2_AS3.as diff --git a/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2.swf b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2.swf Binary files differnew file mode 100755 index 0000000..4d2dc23 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2.swf diff --git a/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_debug.swf b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_debug.swf Binary files differnew file mode 100755 index 0000000..01ce0ea --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_debug.swf diff --git a/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9.swf b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9.swf Binary files differnew file mode 100755 index 0000000..dad27ea --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9.swf diff --git a/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9_debug.swf b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9_debug.swf Binary files differnew file mode 100755 index 0000000..cdffb46 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash9_debug.swf diff --git a/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash_xdomain.zip b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash_xdomain.zip Binary files differnew file mode 100755 index 0000000..2ac8781 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/swf/soundmanager2_flash_xdomain.zip diff --git a/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.css b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.css new file mode 100755 index 0000000..2b0b8ae --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.css @@ -0,0 +1,120 @@ +/* SM2 troubleshooting CSS */
+
+#sm2-test {
+ position:relative;
+ background:#f6f6f6;
+ border:1px solid #eee;
+ padding:3px;
+}
+
+#sm2-test,
+#sm2-test ul.items {
+ -moz-border-radius:3px;
+ -khtml-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+#sm2-test ul.items {
+ position:relative;
+ background:#fff;
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+ border:1px solid #ccc;
+}
+
+#sm2-test ul.items li {
+ position:relative;
+ margin-left:0.5em;
+ padding-left:0.5em;
+ margin-right:0.5em;
+ padding-right:0.5em;
+}
+
+#sm2-test ul.items li h3 {
+ padding-top:0.3em;
+ margin-top:0px;
+ border-bottom:1px solid #ccc;
+}
+
+#sm2-test ul.items li:last-child h3 {
+ border-bottom:none;
+}
+
+#sm2-test ul.items li div.details {
+ border-bottom:1px solid #ccc;
+}
+
+#sm2-test ul.items li:hover div.details {
+ border-bottom:1px solid #ccc;
+}
+
+#sm2-test ul.items li.open:last-child h3,
+#sm2-test ul.items li.fail:last-child h3,
+#sm2-test ul.items li:last-child div.details:last-child {
+ border-bottom:1px solid #fff;
+}
+
+#sm2-test ul.items li div.details {
+ display:none;
+}
+
+#sm2-test ul.items li.open div.details,
+#sm2-test ul.items li.unknown div.details,
+#sm2-test ul.items li.fail div.details {
+ display:block;
+}
+
+#sm2-test ul.items li span.yay,
+#sm2-test ul.items li span.boo,
+#sm2-test ul.items li span.default,
+#sm2-test ul.items li span.unknown {
+ display:none;
+}
+
+#sm2-test ul.items li span.yay,
+#sm2-test ul.items li.pass span.msg {
+ color:green;
+}
+
+#sm2-test ul.items li span.boo,
+#sm2-test ul.items li.fail span.msg {
+ color:red;
+}
+
+#sm2-test ul.items li span.default,
+#sm2-test ul.items li.default span.msg {
+ color:#ccc;
+}
+
+#sm2-test ul.items li span.unknown,
+#sm2-test ul.items li.unknown span.msg {
+ color:#666;
+}
+
+#sm2-test ul.items li.default span.msg {
+ display:none; /* hide messages in the event a reset occurs */
+}
+
+#sm2-test ul.items li.pass span.yay,
+#sm2-test ul.items li.fail span.boo,
+#sm2-test ul.items li.default span.default,
+#sm2-test ul.items li.unknown span.unknown {
+ float:right;
+ display:inline;
+}
+
+#sm2-container.flash_debug {
+ /* flash movie, when soundManager.debugFlash = true */
+ position:relative;
+ width:auto;
+ height:300px;
+ width:100%;
+ background:#f6f6f6;
+ border:1px solid #ccc;
+}
+
+#sm2-container.flash_debug object,
+#sm2-container.flash_debug embed {
+ border:1px solid #fff;
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.js b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.js new file mode 100755 index 0000000..052955a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/debug.js @@ -0,0 +1,173 @@ +// SoundManager 2 start-up troubleshooting tool
+
+// FlashDetect, by Carl Yestrau
+// http://www.featureblend.com/license.txt
+var FlashDetect=new function(){var self=this;self.installed=false;self.raw="";self.major=-1;self.minor=-1;self.revision=-1;self.revisionStr="";var activeXDetectRules=[{"name":"ShockwaveFlash.ShockwaveFlash.7","version":function(obj){return getActiveXVersion(obj);}},{"name":"ShockwaveFlash.ShockwaveFlash.6","version":function(obj){var version="6,0,21";try{obj.AllowScriptAccess="always";version=getActiveXVersion(obj);}catch(err){}
+return version;}},{"name":"ShockwaveFlash.ShockwaveFlash","version":function(obj){return getActiveXVersion(obj);}}];var getActiveXVersion=function(activeXObj){var version=-1;try{version=activeXObj.GetVariable("$version");}catch(err){}
+return version;};var getActiveXObject=function(name){var obj=-1;try{obj=new ActiveXObject(name);}catch(err){}
+return obj;};var parseActiveXVersion=function(str){var versionArray=str.split(",");return{"raw":str,"major":parseInt(versionArray[0].split(" ")[1],10),"minor":parseInt(versionArray[1],10),"revision":parseInt(versionArray[2],10),"revisionStr":versionArray[2]};};var parseStandardVersion=function(str){var descParts=str.split(/ +/);var majorMinor=descParts[2].split(/\./);var revisionStr=descParts[3];return{"raw":str,"major":parseInt(majorMinor[0],10),"minor":parseInt(majorMinor[1],10),"revisionStr":revisionStr,"revision":parseRevisionStrToInt(revisionStr)};};var parseRevisionStrToInt=function(str){return parseInt(str.replace(/[a-zA-Z]/g,""),10)||self.revision;};self.majorAtLeast=function(version){return self.major>=version;};self.FlashDetect=function(){if(navigator.plugins&&navigator.plugins.length>0){var type='application/x-shockwave-flash';var mimeTypes=navigator.mimeTypes;if(mimeTypes&&mimeTypes[type]&&mimeTypes[type].enabledPlugin&&mimeTypes[type].enabledPlugin.description){var version=mimeTypes[type].enabledPlugin.description;var versionObj=parseStandardVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revisionStr=versionObj.revisionStr;self.revision=versionObj.revision;self.installed=true;}}else if(navigator.appVersion.indexOf("Mac")==-1&&window.execScript){var version=-1;for(var i=0;i<activeXDetectRules.length&&version==-1;i++){var obj=getActiveXObject(activeXDetectRules[i].name);if(typeof obj=="object"){self.installed=true;version=activeXDetectRules[i].version(obj);if(version!=-1){var versionObj=parseActiveXVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revision=versionObj.revision;self.revisionStr=versionObj.revisionStr;}}}}}();};FlashDetect.release="1.0.3";
+
+// flash version URL switch (for this demo page)
+var winLoc = window.location.toString();
+if (winLoc.match(/flash9/i)) {
+ soundManager.flashVersion = 9;
+ if (winLoc.match(/highperformance/i)) {
+ soundManager.useHighPerformance = true;
+ soundManager.useFastPolling = true;
+ }
+} else if (winLoc.match(/flash8/i)) {
+ soundManager.flashVersion = 8;
+}
+
+var sm2Debugger = null;
+
+function SM2Debugger() {
+
+ var elementIDs = ['flashtojs','jstoflash','onload','soundtest','swf','hasflash'];
+ var elements = {};
+ var self = this;
+
+ this.getXHR = function() {
+ var xhr = null;
+ if (typeof window.XMLHttpRequest != 'undefined') {
+ try {
+ xhr = new XMLHttpRequest();
+ } catch(e) {
+ // d'oh
+ }
+ }
+ if (!xhr) {
+ try {
+ xhr = new ActiveXObject('Msxml2.XMLHTTP');
+ } catch(e) {
+ try {
+ xhr = new ActiveXObject('Microsoft.XMLHTTP');
+ } catch(E) {
+ xhr = null;
+ }
+ }
+ }
+ return xhr;
+ }
+
+ this.testURL = function(sURL,fOnComplete) {
+ var xhr = self.getXHR();
+ var msg = '<a href="'+soundManager.url+'" title="This should be a valid .SWF URL, not a 404 etc.">'+soundManager.url+'</a>';
+ if (soundManager.getMoviePercent() == 100) {
+ // SWF may have already loaded
+ fOnComplete(true,msg);
+ } else {
+ try {
+ xhr.open("HEAD",sURL,true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == '200') {
+ fOnComplete(true,msg);
+ } else if (xhr.status == '404') {
+ fOnComplete(false,msg);
+ } else {
+ // some other response
+ fOnComplete('unknown',(xhr.status != '0'?'HTTP response: '+xhr.status+', ':'')+msg); // safari returns 0 when offline
+ }
+ }
+ }
+ xhr.send(null);
+
+ } catch(e) {
+ // fail (cross-domain, or no XHR) unless offline
+ fOnComplete('unknown',msg);
+ return false;
+ }
+ }
+ }
+
+ this.handleEvent = function(sEventType,bSuccess,sMessage) {
+ var o = elements[sEventType];
+ if (o) {
+ o.className = (bSuccess == true?'pass':(bSuccess != false?bSuccess:'fail')); // true = pass, className as argument, or false == fail
+ if (sMessage) {
+ var oSpan = o.getElementsByTagName('span')[4];
+ if (oSpan) {
+ oSpan.innerHTML = (oSpan.innerHTML +' <span class="msg">'+sMessage+'</msg>');
+ } else {
+ o.title = sMessage;
+ }
+ }
+ // associated events
+ if (sEventType == 'onload') {
+ if (bSuccess) {
+ self.doSoundTest();
+ } else {
+ self.testURL(soundManager.url,function(bSuccess,sMessage) {
+ if (typeof sMessage == 'undefined') {
+ sMessage = null;
+ }
+ self.handleEvent('swf',bSuccess,sMessage);
+ });
+ }
+ } else if (sEventType == 'swf') {
+ if (bSuccess == false) {
+ // don't show flashtojs at all if SWF failed to load
+ self.handleEvent('flashtojs','default'); // reset to N/A status
+ }
+ } else if (sEventType == 'flashtojs') {
+ if (bSuccess != true) {
+ // online or offline help messages
+ if (soundManager._overHTTP) {
+ document.getElementById('d-flashtojs-offline').style.display = 'none';
+ } else {
+ document.getElementById('d-flashtojs-online').style.display = 'none';
+ }
+ }
+ }
+ } else {
+ soundManager._writeDebug('SM2 debugger warning: Undefined event type "'+sEventType+'"',1);
+ }
+ }
+
+ this.doSoundTest = function() {
+ var foo = soundManager.createSound({
+ id: 'sm2TestSound',
+ url: ('http://schillmania.com/projects/soundmanager2/demo/_mp3/mouseover.mp3')
+ });
+ if (!soundManager._disabled) {
+ foo.play();
+ // looks to be OK..
+ if (!soundManager._disabled) {
+ // still OK..
+ self.handleEvent('soundtest',true);
+ } else {
+ self.handleEvent('soundtest',false,': Failed after play()');
+ }
+ } else {
+ self.handleEvent('soundtest',false,': Failed after createSound()');
+ }
+ }
+
+ this.init = function() {
+ // map event elements to DOM nodes - eg. elements.flashtojs = document.getElementById('d-flashtojs');
+ for (var i=elementIDs.length; i--;) {
+ elements[elementIDs[i]] = document.getElementById('d-'+elementIDs[i]);
+ }
+ self.doFlashTest();
+ }
+
+ this.doFlashTest = function() {
+ var fd = FlashDetect;
+ var hasFlash = fd.installed;
+ var isSupported = (hasFlash && fd.major >= soundManager.flashVersion);
+ var flashVersion = fd.major+'.'+fd.minor+'.'+fd.revisionStr;
+ var flashInfo = ' version '+(!isSupported?'unsupported ('+flashVersion+', SWF version '+soundManager.flashVersion+')':flashVersion);
+ document.getElementById('d-flashversion').innerHTML = 'soundManager.flashVersion = '+soundManager.flashVersion+';';
+ self.handleEvent('hasflash',isSupported,hasFlash?flashInfo:null);
+ }
+
+ soundManager.debugFlash = true; // try to get flash debug output, as well
+
+ this.init();
+
+}
+
+function sm2DebugInit() {
+ sm2Debugger = new SM2Debugger();
+}
\ No newline at end of file diff --git a/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-add-location.png b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-add-location.png Binary files differnew file mode 100755 index 0000000..61db61c --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-add-location.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-added-location.png b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-added-location.png Binary files differnew file mode 100755 index 0000000..6cf1c19 --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/fpgss-added-location.png diff --git a/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/index.html b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/index.html new file mode 100755 index 0000000..c371d1a --- /dev/null +++ b/docs/dymaxion/soundmanagerv297a-20101010/troubleshoot/index.html @@ -0,0 +1,154 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>SoundManager 2 Start-up Test / Troubleshooting Tool</title> +<meta name="robots" content="noindex" />
+<meta name="description" content="A standalone version of the SoundManager 2 Start-up Troubleshooting Tool." />
+<meta name="keywords" content="javascript sound, javascript audio, javascript play mp3, javascript sound control, javascript video, mp3, mp4, mpeg4" />
+<meta name="robots" content="all" />
+<meta name="author" content="Scott Schiller" />
+<meta name="copyright" content="Copyright (C) 1997 onwards Scott Schiller" />
+<meta name="language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="stylesheet" type="text/css" media="screen" href="../demo/index.css" /> <!-- prettier fonts etc., optional -->
+<link rel="stylesheet" type="text/css" media="screen" href="debug.css" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<style type="text/css">
+#sm2-container {
+ position:relative;
+ width:auto;
+ height:auto;
+ max-height:200px;
+ margin-top:1em;
+ border:1px solid #999;
+ background:#eee;
+ padding:0.5em;
+}
+</style>
+<script type="text/javascript" src="../script/soundmanager2.js"></script>
+<script type="text/javascript">
+// optional
+soundManager.url = '../swf/';
+soundManager.onload = function() {}
+
+</script>
+
+<script type="text/javascript" src="debug.js"></script>
+</head>
+
+<body>
+
+<!-- the following markup, debug.css and debug.js are required. -->
+
+<div style="position:relative;width:500px;margin:1em">
+
+<p class="note">Flash options: <a href="#flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (default), <a href="#flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal) or <a href="#flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance + fastPolling</a> modes.</p>
+
+<div id="sm2-test">
+ <ul class="items">
+
+ <li id="d-onload" class="default">
+ <h3><span class="yay">OK</span><span class="boo">FAIL</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>SoundManager 2 start-up</span></h3>
+ <div id="sm2-startup" class="details">
+ <p>soundManager.onload() or soundManager.onerror() is ultimately called when start-up completes.</p>
+ <p>If you're seeing a failure, refer to the below for troubleshooting details for common causes.</p>
+ </div>
+ </li>
+
+ <li id="d-hasflash" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash</span></h3>
+ <div class="details">
+ <p>The Flash 8 plugin is a minimal requirement for SoundManager 2, but the exact requirement varies based on soundManager.flashVersion. You are currently using <b id="d-flashversion">[unknown]</b>.</p>
+ </div>
+ </li>
+
+ <li id="d-swf" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash SWF</span></h3>
+ <div class="details">
+ <p>SoundManager 2 must load a flash movie before initialisation can proceed. If you have errors here, check that soundManager.url is correctly defined and that the URL being loaded is correct.</p>
+ <p>If the Flash movie URL is OK, Flash security or flash blockers are the likely cause. Check the section below.</p>
+ </div>
+ </li>
+
+ <li id="d-flashtojs" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Flash -> JS</span></h3>
+ <div class="details">
+ <p>Once the flash component of SM2 has loaded, it tries to make a call to Javascript-land. This is a common point of failure, for security reasons:</p>
+ <ul>
+ <li>
+ <p><b>Have a flash blocker?</b> Check that the <a href="#flashdebug">SM2 flash movie</a> (below) is loading and is not being blocked.</p>
+ </li>
+ <li>
+ Is your browser URL at file:// or c:/path/ or otherwise not using HTTP? Flash security "whitelisting" is required to allow Flash + JS to work when offline, placing it in the "LocalTrusted" Flash security sandbox rather than "localWithFile".
+
+ <div id="d-flashtojs-offline" style="padding-bottom:1em">
+ <h4>Offline viewing: Adding a "trusted location" to the Flash Security Settings Panel</h4>
+ <p>The Flash Player Global Security Settings Panel is a web-based control panel which allows you to configure Flash security. You will need to add the path of the SoundManager 2 project in order for it to work "offline" (ie., when viewing via file:// or c:/)</p>
+ <p id="ss"><a href="#screenshots" onclick="document.getElementById('ss-box').style.display = 'block';document.getElementById('ss').style.display='none';return false">Show me how</a>: Adding a "trusted location"</p>
+ <div id="ss-box" style="display:none">
+ <h4>Illustrated guide: Adding a "trusted location" in Flash</h4>
+ <p>Below: Adding a location, and selecting "Browse for folder" (or directory), to whitelist the SoundManager 2 project directory for offline viewing.</p>
+ <p><img src="../../troubleshoot/fpgss-add-location.png" alt="Adding a location: Browse for the file or directory to whitelist" style="width:100%;_width:auto;min-width:72px;max-width:396px" /></p>
+ <p><img src="../../troubleshoot/fpgss-added-location.png" alt="Whitelisted location has now been added, JS + Flash will work under this path" style="width:100%;_width:auto;min-width:72px;max-width:396px" /></p>
+ </div>
+ <p><a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html" target="_blank" class="feature">Launch the Flash Security Settings Panel</a></p>
+ </div>
+
+ </li>
+ <li style="margin-top:0.5em">Flash blockers (FlashBlock, "click to flash" etc.) preventing flash load and start-up - need whitelisting/"allow this domain" to work smoothly. If you suspect blocking is the issue, try the <a href="../demo/flashblock/">SoundManager 2 Flashblock demo</a>.</li>
+ <li style="margin-top:0.5em">Online viewing (HTTP/S): Same-domain security rules apply to HTML + Flash content by default (crossdomain.xml/allowDomain() in .AS source required to override.)</li>
+ </ul>
+ <p>See <a href="#flashdebug" title="SoundManager 2 flash debug output">Flash debug output</a> for more security error details.</p>
+
+ <div id="d-flashtojs-online">
+ <h4>Online viewing: Cross-domain security restrictions</h4>
+ <p>HTML page on domain A loading .SWF from domain B: Flash security prevents JS + Flash when a cross-domain XML permission file is not available on domain B, and/or flash movie was not compiled with allowDomain('domainA') or allowDomain('*') - note that the SWF distributed with SM2 does not use this by default; try using the cross-domain version of the SWF, or compile your own which whitelists your own domain(s).</p>
+
+ <h4>Flash Blockers</h4>
+ <p>Browser extensions/add-ons like "FlashBlock" and "click to flash" can prevent the .SWF from loading, and this will mean SM2 will time-out and fail waiting for a response from Flash. For development, it's best to whitelist the domain(s) or the .SWF for SM2 to allow it to work.</p>
+ <p>Have a flash blocker installed? Want to test it? Try the <a href="../../demo/flashblock">SoundManager 2 Flashblock demo</a>.</p>
+
+ </div>
+
+ </div>
+ </li>
+
+ <li id="d-jstoflash" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>JS -> Flash</span></h3>
+ <div class="details">
+ <p>At this point, Javascript attempts to respond to Flash's initial outgoing Flash -> JS call, completing the test for JS/flash communication. If SM2 does not receive a response from flash, it will eventually fail.</p>
+ <p>Offline viewing conditions and cross-domain security rules will prevent Flash <-> JS communication. See the details of Flash -> JS for information.</p>
+ </div>
+ </li>
+
+ <li id="d-soundtest" class="default">
+ <h3><span class="yay">OK</span><span class="boo">Error</span><span class="default">N/A</span><span class="unknown">Unknown</span><span>Sound test</span></h3>
+ <div class="details">
+ <p>Here, a simple createSound() call is made to test SM2's actual operation. A sound should load and play provided SM2 was able to start successfully.</p>
+ </div>
+ </li>
+
+ </ul>
+</div>
+
+<div class="block" style="margin-top:1em">
+ <div id="soundmanager-debug" class="code">
+ <!-- live debug goes here -->
+ </div>
+</div>
+
+<div id="flashdebug">
+ <div id="sm2-container">
+ <!-- flash goes here -->
+ </div>
+</div>
+
+<script type="text/javascript">
+sm2DebugInit();
+</script>
+
+</div>
+</body>
+</html> |
