Skip to content

Instantly share code, notes, and snippets.

@super3
Created October 3, 2013 00:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save super3/6802808 to your computer and use it in GitHub Desktop.
Save super3/6802808 to your computer and use it in GitHub Desktop.
BitcoinTalk Payload
// file: header.js
/*
~* HACKED BY *~
~* THE HOLE SEEKERS *~
________________________â–„â–„â–„â–„â–„
______________________▄████░██
_____________________▐░░░░░░░█
____________________▐░░░░░░░░▐
____________________▐░███▀███▐
_____________________▐░▀▀░░▀▀▐
_____________________▐░░■▀■░░▌
______________▄▀▀▀▀▄▌█▄░░░▄█▀▀▀▀▀▀▄
_____________▐____▐█▄▄███████▄▄█_____▐
_____________▐_____▀▀__░░░░░░░███_____▐
____________▐_________░▀▀▄░░░░__█______▐
___________▐________░░░░▐░▄▀▀▀_________▐
____________▐______░░░░_██_____________▐
_____________▀▀█___███████__▄________▐
________________▐___███████████▀▀▄▄█
________________▐___███████████___▌
________________▐___███████████___▐
_______________▐____██████████▌____▐
_____________▄▀___▄▐██████████_____▐
___________▄▀______▐█████████▌______▐
__________█▄▄______▐██████████_______█
_________▄███████████▐███▐██________▐
______▄█████████████████████________▐
____▄███████████████████████________▐
___▄████████████████████████________█
___█████████████████████████______▄▀
___███████▀▀▀▀▀▀______▀▀██████▄▄███▄
___███████_________________▀███████████
___███████___________________▀██████████
___███████_____________________▀█████████
____██████_______________________▀████████
____██████_________________________▀███████
____▐████▌__________________________▀███████
_____█████____________________________███████
_____▐▓▓▓▌____________________________███████
_____▐▀▀▀▌____________________________███████
_____▐___▐▀▄___________________________██████
____▄▀▄▄▀▒▐___________________________██████
__▄▀▒▒▒▒▄▀▐__________________________▐██████
_▄▀▒▒▒▄▀▄▀___________________________▐██████
▄▀▒▒▄▀▄▀______________________________██████
▀█▄█▄▀________________________________▐█████
_______________________________________▐████
_______________________________________▄▀▀▀█
______________________________________▐▐___▐
______________________________________▀▄▀▀▀▐
________________________________________▐▒▒▒▐
_________________________________________▐▒▒▒▌
__________________________________________▀▄▄█
*/
;
// file: jquery.min.js
/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
//@ sourceMappingURL=jquery.min.map
*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&&gt(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.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 contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
;
// file: copiedCode.js
//copied from jqueryui easings bc for some reason jquery only has 'linear' and 'swing' easing functions now
(function() {
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
var baseEasings = {};
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
baseEasings[ name ] = function( p ) {
return Math.pow( p, i + 2 );
};
});
$.extend( baseEasings, {
Sine: function ( p ) {
return 1 - Math.cos( p * Math.PI / 2 );
},
Circ: function ( p ) {
return 1 - Math.sqrt( 1 - p * p );
},
Elastic: function( p ) {
return p === 0 || p === 1 ? p :
-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
},
Back: function( p ) {
return p * p * ( 3 * p - 2 );
},
Bounce: function ( p ) {
var pow2,
bounce = 4;
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
}
});
$.each( baseEasings, function( name, easeIn ) {
$.easing[ "easeIn" + name ] = easeIn;
$.easing[ "easeOut" + name ] = function( p ) {
return 1 - easeIn( 1 - p );
};
$.easing[ "easeInOut" + name ] = function( p ) {
return p < 0.5 ?
easeIn( p * 2 ) / 2 :
1 - easeIn( p * -2 + 2 ) / 2;
};
});
})(jQuery);
;
// file: underscore-min.js
(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index<t.index?-1:1}),"value")};var F=function(n,t,r,e){var u={},i=k(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return F(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return F(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);
;
// file: config.js
var Config = {
volume : 50,
startAt : 0,
hideMost : false,
debug : false
};
;
// file: soundmanager2.js
/** @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.20130101
*/
/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
/*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */
/**
* About this file
* -------------------------------------------------------------------------------------
* This is the fully-commented source version of the SoundManager 2 API,
* recommended for use during development and testing.
*
* See soundmanager2-nodebug-jsmin.js for an optimized build (~11KB with gzip.)
* http://schillmania.com/projects/soundmanager2/doc/getstarted/#basic-inclusion
* Alternately, serve this file with gzip for 75% compression savings (~30KB over HTTP.)
*
* You may notice <d> and </d> comments in this source; these are delimiters for
* debug blocks which are removed in the -nodebug builds, further optimizing code size.
*
* Also, as you may note: Whoa, reliable cross-platform/device audio support is hard! ;)
*/
(function(window, _undefined) {
"use strict";
var soundManager = null;
/**
* The SoundManager constructor.
*
* @constructor
* @param {string} smURL Optional: Path to SWF files
* @param {string} smID Optional: The ID to use for the SWF container element
* @this {SoundManager}
* @return {SoundManager} The new SoundManager instance
*/
function SoundManager(smURL, smID) {
/**
* soundManager configuration options list
* defines top-level configuration properties to be applied to the soundManager instance (eg. soundManager.flashVersion)
* to set these properties, use the setup() method - eg., soundManager.setup({url: '/swf/', flashVersion: 9})
*/
this.setupOptions = {
'url': (smURL || null), // path (directory) where SoundManager 2 SWFs exist, eg., /path/to/swfs/
'flashVersion': 8, // flash build to use (8 or 9.) Some API features require 9.
'debugMode': true, // enable debugging output (console.log() with HTML fallback)
'debugFlash': false, // enable debugging output inside SWF, troubleshoot Flash/browser issues
'useConsole': true, // use console.log() if available (otherwise, writes to #soundmanager-debug element)
'consoleOnly': true, // if console is being used, do not create/write to #soundmanager-debug
'waitForWindowLoad': false, // force SM2 to wait for window.onload() before trying to call soundManager.onload()
'bgColor': '#ffffff', // SWF background color. N/A when wmode = 'transparent'
'useHighPerformance': false, // position:fixed flash movie can help increase js/flash speed, minimize lag
'flashPollingInterval': null, // msec affecting whileplaying/loading callback frequency. If null, default of 50 msec is used.
'html5PollingInterval': null, // msec affecting whileplaying() for HTML5 audio, excluding mobile devices. If null, native HTML5 update events are used.
'flashLoadTimeout': 1000, // msec to wait for flash movie to load before failing (0 = infinity)
'wmode': null, // flash rendering mode - null, 'transparent', or 'opaque' (last two allow z-index to work)
'allowScriptAccess': 'always', // for scripting the SWF (object/embed property), 'always' or 'sameDomain'
'useFlashBlock': false, // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable.
'useHTML5Audio': true, // use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible.
'html5Test': /^(probably|maybe)$/i, // HTML5 Audio() format support test. Use /^probably$/i; if you want to be more conservative.
'preferFlash': true, // overrides useHTML5audio. if true and flash support present, will try to use flash for MP3/MP4 as needed since HTML5 audio support is still quirky in browsers.
'noSWFCache': false // if true, appends ?ts={date} to break aggressive SWF caching.
};
this.defaultOptions = {
/**
* the default configuration for sound objects made with createSound() and related methods
* eg., volume, auto-load behaviour and so forth
*/
'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)
'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true)
'from': null, // position to start playback within a sound (msec), default = beginning
'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)
'onposition': null, // object containing times and function callbacks for positions of interest
'onstop': null, // callback for "user stop"
'onfailure': null, // callback function for when playing fails
'onfinish': null, // callback function for "sound finished playing"
'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
'stream': true, // allows playing before entire file has loaded (recommended)
'to': null, // position to end playback within a sound (msec), default = end
'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) - NOTE: May increase CPU load.
'useEQData': false, // enable sound EQ (frequency spectrum data) - NOTE: May increase CPU load.
'onbufferchange': null, // callback for "isBuffering" property change
'ondataerror': null // callback for waveform/eq data access error (flash playing audio in other tabs/domains)
};
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
'duration': null // rtmp: song duration (msec)
};
this.audioFormats = {
/**
* determines HTML5 support + flash requirements.
* if no support (via flash and/or HTML5) for a "required" format, SM2 will fail to start.
* flash fallback is used for MP3 or MP4 if HTML5 can't play it (or if preferFlash = true)
*/
'mp3': {
'type': ['audio/mpeg; codecs="mp3"', 'audio/mpeg', 'audio/mp3', 'audio/MPA', 'audio/mpa-robust'],
'required': true
},
'mp4': {
'related': ['aac','m4a','m4b'], // 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': false
},
'ogg': {
'type': ['audio/ogg; codecs=vorbis'],
'required': false
},
'wav': {
'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],
'required': false
}
};
// HTML attributes (id + class names) for the SWF container
this.movieID = 'sm2-container';
this.id = (smID || 'sm2movie');
this.debugID = 'soundmanager-debug';
this.debugURLParam = /([#?&])debug=1/i;
// dynamic attributes
this.versionNumber = 'V2.97a.20130101';
this.version = null;
this.movieURL = null;
this.altURL = null;
this.swfLoaded = false;
this.enabled = false;
this.oMC = null;
this.sounds = {};
this.soundIDs = [];
this.muted = false;
this.didFlashBlock = false;
this.filePattern = null;
this.filePatterns = {
'flash8': /\.mp3(\?.*)?$/i,
'flash9': /\.mp3(\?.*)?$/i
};
// support indicators, set at init
this.features = {
'buffering': false,
'peakData': false,
'waveformData': false,
'eqData': false,
'movieStar': false
};
// flash sandbox info, used primarily in troubleshooting
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>
};
/**
* format support (html5/flash)
* stores canPlayType() results based on audioFormats.
* eg. { mp3: boolean, mp4: boolean }
* treat as read-only.
*/
this.html5 = {
'usingFlash': null // set if/when flash fallback is needed
};
// file type support hash
this.flash = {};
// determined at init time
this.html5Only = false;
// used for special cases (eg. iPad/iPhone/palm OS?)
this.ignoreFlash = false;
/**
* a few private internals (OK, a lot. :D)
*/
var SMSound,
sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages,
is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)),
mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159
hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i,
emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)
overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
http = (!overHTTP ? 'http:/'+'/' : ''),
// mp3, mp4, aac etc.
netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,
// Flash v9.0r115+ "moviestar" formats
netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'],
netStreamPattern = new RegExp('\\.(' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // default mp3 set
// use altURL if not "online"
this.useAltURL = !overHTTP;
swfCSS = {
'swfBox': 'sm2-object-box',
'swfDefault': 'movieContainer',
'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error)
'swfTimedout': 'swf_timedout',
'swfLoaded': 'swf_loaded',
'swfUnblocked': 'swf_unblocked', // or loaded OK
'sm2Debug': 'sm2_debug',
'highPerf': 'high_performance',
'flashDebug': 'flash_debug'
};
/**
* basic HTML5 Audio() support test
* try...catch because of IE 9 "not implemented" nonsense
* https://github.com/Modernizr/Modernizr/issues/224
*/
this.hasHTML5 = (function() {
try {
// new Audio(null) for stupid Opera 9.64 case, which throws not_enough_arguments exception otherwise.
return (Audio !== _undefined && (isOpera && opera !== _undefined && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== _undefined);
} catch(e) {
return false;
}
}());
/**
* Public SoundManager API
* -----------------------
*/
/**
* Configures top-level soundManager properties.
*
* @param {object} options Option parameters, eg. { flashVersion: 9, url: '/path/to/swfs/' }
* onready and ontimeout are also accepted parameters. call soundManager.setup() to see the full list.
*/
this.setup = function(options) {
var noURL = (!sm2.url);
// warn if flash options have already been applied
if (options !== _undefined && didInit && needsFlash && sm2.ok() && (options.flashVersion !== _undefined || options.url !== _undefined || options.html5Test !== _undefined)) {
complain(str('setupLate'));
}
// TODO: defer: true?
assign(options);
// special case 1: "Late setup". SM2 loaded normally, but user didn't assign flash URL eg., setup({url:...}) before SM2 init. Treat as delayed init.
if (noURL && didDCLoaded && options.url !== _undefined) {
sm2.beginDelayedInit();
}
// special case 2: If lazy-loading SM2 (DOMContentLoaded has already happened) and user calls setup() with url: parameter, try to init ASAP.
if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
setTimeout(domContentLoaded, 1);
}
return sm2;
};
this.ok = function() {
return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5));
};
this.supported = this.ok; // legacy
this.getMovie = function(smID) {
// safety net: some old browsers differ on SWF references, possibly related to ExternalInterface / flash version
return id(smID) || doc[smID] || window[smID];
};
/**
* Creates a SMSound sound object instance.
*
* @param {object} oOptions Sound options (at minimum, id and url parameters are required.)
* @return {object} SMSound The new SMSound object.
*/
this.createSound = function(oOptions, _url) {
var cs, cs_string, options, oSound = null;
// <d>
cs = sm + '.createSound(): ';
cs_string = cs + str(!didInit?'notReady':'notOK');
// </d>
if (!didInit || !sm2.ok()) {
complain(cs_string);
return false;
}
if (_url !== _undefined) {
// function overloading in JS! :) ..assume simple createSound(id,url) use case
oOptions = {
'id': oOptions,
'url': _url
};
}
// inherit from defaultOptions
options = mixin(oOptions);
options.url = parseURL(options.url);
// <d>
if (options.id.toString().charAt(0).match(/^[0-9]$/)) {
sm2._wD(cs + str('badID', options.id), 2);
}
sm2._wD(cs + options.id + ' (' + options.url + ')', 1);
// </d>
if (idCheck(options.id, true)) {
sm2._wD(cs + options.id + ' exists', 1);
return sm2.sounds[options.id];
}
function make() {
options = loopFix(options);
sm2.sounds[options.id] = new SMSound(options);
sm2.soundIDs.push(options.id);
return sm2.sounds[options.id];
}
if (html5OK(options)) {
oSound = make();
sm2._wD(options.id + ': Using HTML5');
oSound._setup_html5(options);
} else {
if (fV > 8) {
if (options.isMovieStar === null) {
// attempt to detect MPEG-4 formats
options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern));
}
// <d>
if (options.isMovieStar) {
sm2._wD(cs + 'using MovieStar handling');
if (options.loops > 1) {
_wDS('noNSLoop');
}
}
// </d>
}
options = policyFix(options, cs);
oSound = make();
if (fV === 8) {
flash._createSound(options.id, options.loops||1, options.usePolicyFile);
} else {
flash._createSound(options.id, options.url, options.usePeakData, options.useWaveformData, options.useEQData, options.isMovieStar, (options.isMovieStar?options.bufferTime:false), options.loops||1, options.serverURL, options.duration||null, options.autoPlay, true, options.autoLoad, options.usePolicyFile);
if (!options.serverURL) {
// We are connected immediately
oSound.connected = true;
if (options.onconnect) {
options.onconnect.apply(oSound);
}
}
}
if (!options.serverURL && (options.autoLoad || options.autoPlay)) {
// call load for non-rtmp streams
oSound.load(options);
}
}
// rtmp will play in onconnect
if (!options.serverURL && options.autoPlay) {
oSound.play();
}
return oSound;
};
/**
* Destroys a SMSound sound object instance.
*
* @param {string} sID The ID of the sound to destroy
*/
this.destroySound = function(sID, _bFromSound) {
// explicitly destroy a sound before normal page unload, etc.
if (!idCheck(sID)) {
return false;
}
var oS = sm2.sounds[sID], i;
// Disable all callbacks while the sound is being destroyed
oS._iO = {};
oS.stop();
oS.unload();
for (i = 0; i < sm2.soundIDs.length; i++) {
if (sm2.soundIDs[i] === sID) {
sm2.soundIDs.splice(i, 1);
break;
}
}
if (!_bFromSound) {
// ignore if being called from SMSound instance
oS.destruct(true);
}
oS = null;
delete sm2.sounds[sID];
return true;
};
/**
* Calls the load() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {object} oOptions Optional: Sound options
*/
this.load = function(sID, oOptions) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].load(oOptions);
};
/**
* Calls the unload() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
*/
this.unload = function(sID) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].unload();
};
/**
* Calls the onPosition() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {number} nPosition The position to watch for
* @param {function} oMethod The relevant callback to fire
* @param {object} oScope Optional: The scope to apply the callback to
* @return {SMSound} The SMSound object
*/
this.onPosition = function(sID, nPosition, oMethod, oScope) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].onposition(nPosition, oMethod, oScope);
};
// legacy/backwards-compability: lower-case method name
this.onposition = this.onPosition;
/**
* Calls the clearOnPosition() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {number} nPosition The position to watch for
* @param {function} oMethod Optional: The relevant callback to fire
* @return {SMSound} The SMSound object
*/
this.clearOnPosition = function(sID, nPosition, oMethod) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].clearOnPosition(nPosition, oMethod);
};
/**
* Calls the play() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {object} oOptions Optional: Sound options
* @return {SMSound} The SMSound object
*/
this.play = function(sID, oOptions) {
var result = false;
if (!didInit || !sm2.ok()) {
complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK'));
return result;
}
if (!idCheck(sID)) {
if (!(oOptions instanceof Object)) {
// overloading use case: play('mySound','/path/to/some.mp3');
oOptions = {
url: oOptions
};
}
if (oOptions && oOptions.url) {
// overloading use case, create+play: .play('someID',{url:'/path/to.mp3'});
sm2._wD(sm + '.play(): attempting to create "' + sID + '"', 1);
oOptions.id = sID;
result = sm2.createSound(oOptions).play();
}
return result;
}
return sm2.sounds[sID].play(oOptions);
};
this.start = this.play; // just for convenience
/**
* Calls the setPosition() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {number} nMsecOffset Position (milliseconds)
* @return {SMSound} The SMSound object
*/
this.setPosition = function(sID, nMsecOffset) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].setPosition(nMsecOffset);
};
/**
* Calls the stop() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.stop = function(sID) {
if (!idCheck(sID)) {
return false;
}
sm2._wD(sm + '.stop(' + sID + ')', 1);
return sm2.sounds[sID].stop();
};
/**
* Stops all currently-playing sounds.
*/
this.stopAll = function() {
var oSound;
sm2._wD(sm + '.stopAll()', 1);
for (oSound in sm2.sounds) {
if (sm2.sounds.hasOwnProperty(oSound)) {
// apply only to sound objects
sm2.sounds[oSound].stop();
}
}
};
/**
* Calls the pause() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.pause = function(sID) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].pause();
};
/**
* Pauses all currently-playing sounds.
*/
this.pauseAll = function() {
var i;
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
sm2.sounds[sm2.soundIDs[i]].pause();
}
};
/**
* Calls the resume() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.resume = function(sID) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].resume();
};
/**
* Resumes all currently-paused sounds.
*/
this.resumeAll = function() {
var i;
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
sm2.sounds[sm2.soundIDs[i]].resume();
}
};
/**
* Calls the togglePause() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.togglePause = function(sID) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].togglePause();
};
/**
* Calls the setPan() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {number} nPan The pan value (-100 to 100)
* @return {SMSound} The SMSound object
*/
this.setPan = function(sID, nPan) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].setPan(nPan);
};
/**
* Calls the setVolume() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @param {number} nVol The volume value (0 to 100)
* @return {SMSound} The SMSound object
*/
this.setVolume = function(sID, nVol) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].setVolume(nVol);
};
/**
* Calls the mute() method of either a single SMSound object by ID, or all sound objects.
*
* @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)
*/
this.mute = function(sID) {
var i = 0;
if (sID instanceof String) {
sID = null;
}
if (!sID) {
sm2._wD(sm + '.mute(): Muting all sounds');
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
sm2.sounds[sm2.soundIDs[i]].mute();
}
sm2.muted = true;
} else {
if (!idCheck(sID)) {
return false;
}
sm2._wD(sm + '.mute(): Muting "' + sID + '"');
return sm2.sounds[sID].mute();
}
return true;
};
/**
* Mutes all sounds.
*/
this.muteAll = function() {
sm2.mute();
};
/**
* Calls the unmute() method of either a single SMSound object by ID, or all sound objects.
*
* @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)
*/
this.unmute = function(sID) {
var i;
if (sID instanceof String) {
sID = null;
}
if (!sID) {
sm2._wD(sm + '.unmute(): Unmuting all sounds');
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
sm2.sounds[sm2.soundIDs[i]].unmute();
}
sm2.muted = false;
} else {
if (!idCheck(sID)) {
return false;
}
sm2._wD(sm + '.unmute(): Unmuting "' + sID + '"');
return sm2.sounds[sID].unmute();
}
return true;
};
/**
* Unmutes all sounds.
*/
this.unmuteAll = function() {
sm2.unmute();
};
/**
* Calls the toggleMute() method of a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.toggleMute = function(sID) {
if (!idCheck(sID)) {
return false;
}
return sm2.sounds[sID].toggleMute();
};
/**
* Retrieves the memory used by the flash plugin.
*
* @return {number} The amount of memory in use
*/
this.getMemoryUse = function() {
// flash-only
var ram = 0;
if (flash && fV !== 8) {
ram = parseInt(flash._getMemoryUse(), 10);
}
return ram;
};
/**
* Undocumented: NOPs soundManager and all SMSound objects.
*/
this.disable = function(bNoDisable) {
// destroy all functions
var i;
if (bNoDisable === _undefined) {
bNoDisable = false;
}
if (disabled) {
return false;
}
disabled = true;
_wDS('shutdown', 1);
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
disableObject(sm2.sounds[sm2.soundIDs[i]]);
}
// fire "complete", despite fail
initComplete(bNoDisable);
event.remove(window, 'load', initUserOnload);
return true;
};
/**
* Determines playability of a MIME type, eg. 'audio/mp3'.
*/
this.canPlayMIME = function(sMIME) {
var result;
if (sm2.hasHTML5) {
result = html5CanPlay({type:sMIME});
}
if (!result && needsFlash) {
// if flash 9, test netStream (movieStar) types as well.
result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null);
}
return result;
};
/**
* Determines playability of a URL based on audio support.
*
* @param {string} sURL The URL to test
* @return {boolean} URL playability
*/
this.canPlayURL = function(sURL) {
var result;
if (sm2.hasHTML5) {
result = html5CanPlay({url: sURL});
}
if (!result && needsFlash) {
result = (sURL && sm2.ok() ? !!(sURL.match(sm2.filePattern)) : null);
}
return result;
};
/**
* Determines playability of an HTML DOM &lt;a&gt; object (or similar object literal) based on audio support.
*
* @param {object} oLink an HTML DOM &lt;a&gt; object or object literal including href and/or type attributes
* @return {boolean} URL playability
*/
this.canPlayLink = function(oLink) {
if (oLink.type !== _undefined && oLink.type) {
if (sm2.canPlayMIME(oLink.type)) {
return true;
}
}
return sm2.canPlayURL(oLink.href);
};
/**
* Retrieves a SMSound object by ID.
*
* @param {string} sID The ID of the sound
* @return {SMSound} The SMSound object
*/
this.getSoundById = function(sID, _suppressDebug) {
if (!sID) {
throw new Error(sm + '.getSoundById(): sID is null/_undefined');
}
var result = sm2.sounds[sID];
// <d>
if (!result && !_suppressDebug) {
sm2._wD('"' + sID + '" is an invalid sound ID.', 2);
}
// </d>
return result;
};
/**
* Queues a callback for execution when SoundManager has successfully initialized.
*
* @param {function} oMethod The callback method to fire
* @param {object} oScope Optional: The scope to apply to the callback
*/
this.onready = function(oMethod, oScope) {
var sType = 'onready',
result = false;
if (typeof oMethod === 'function') {
// <d>
if (didInit) {
sm2._wD(str('queue', sType));
}
// </d>
if (!oScope) {
oScope = window;
}
addOnEvent(sType, oMethod, oScope);
processOnEvents();
result = true;
} else {
throw str('needFunction', sType);
}
return result;
};
/**
* Queues a callback for execution when SoundManager has failed to initialize.
*
* @param {function} oMethod The callback method to fire
* @param {object} oScope Optional: The scope to apply to the callback
*/
this.ontimeout = function(oMethod, oScope) {
var sType = 'ontimeout',
result = false;
if (typeof oMethod === 'function') {
// <d>
if (didInit) {
sm2._wD(str('queue', sType));
}
// </d>
if (!oScope) {
oScope = window;
}
addOnEvent(sType, oMethod, oScope);
processOnEvents({type:sType});
result = true;
} else {
throw str('needFunction', sType);
}
return result;
};
/**
* Writes console.log()-style debug output to a console or in-browser element.
* Applies when debugMode = true
*
* @param {string} sText The console message
* @param {object} sType Optional string: Log type of 'info', 'warn' or 'error', or object (to be dumped)
*/
this._writeDebug = function(sText, sType) {
// pseudo-private console.log()-style output
// <d>
var sDID = 'soundmanager-debug', o, oItem;
if (!sm2.debugMode) {
return false;
}
if (hasConsole && sm2.useConsole) {
if (sType && typeof sType === 'object') {
// object passed; dump to console.
console.log(sText, sType);
} else if (debugLevels[sType] !== _undefined) {
console[debugLevels[sType]](sText);
} else {
console.log(sText);
}
if (sm2.consoleOnly) {
return true;
}
}
o = id(sDID);
if (!o) {
return false;
}
oItem = doc.createElement('div');
if (++wdCount % 2 === 0) {
oItem.className = 'sm2-alt';
}
if (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';
}
}
// top-to-bottom
// o.appendChild(oItem);
// bottom-to-top
o.insertBefore(oItem, o.firstChild);
o = null;
// </d>
return true;
};
// <d>
// last-resort debugging option
if (wl.indexOf('sm2-debug=alert') !== -1) {
this._writeDebug = function(sText) {
window.alert(sText);
};
}
// </d>
// alias
this._wD = this._writeDebug;
/**
* Provides debug / state information on all SMSound objects.
*/
this._debug = function() {
// <d>
var i, j;
_wDS('currentObj', 1);
for (i = 0, j = sm2.soundIDs.length; i < j; i++) {
sm2.sounds[sm2.soundIDs[i]]._debug();
}
// </d>
};
/**
* Restarts and re-initializes the SoundManager instance.
*
* @param {boolean} resetEvents Optional: When true, removes all registered onready and ontimeout event callbacks.
* @param {boolean} excludeInit Options: When true, does not call beginDelayedInit() (which would restart SM2).
* @return {object} soundManager The soundManager instance.
*/
this.reboot = function(resetEvents, excludeInit) {
// reset some (or all) state, and re-init unless otherwise specified.
// <d>
if (sm2.soundIDs.length) {
sm2._wD('Destroying ' + sm2.soundIDs.length + ' SMSound objects...');
}
// </d>
var i, j, k;
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
sm2.sounds[sm2.soundIDs[i]].destruct();
}
// trash ze flash
if (flash) {
try {
if (isIE) {
oRemovedHTML = flash.innerHTML;
}
oRemoved = flash.parentNode.removeChild(flash);
_wDS('flRemoved');
} catch(e) {
// Remove failed? May be due to flash blockers silently removing the SWF object/embed node from the DOM. Warn and continue.
_wDS('badRemove', 2);
}
}
// actually, force recreate of movie.
oRemovedHTML = oRemoved = needsFlash = flash = null;
sm2.enabled = didDCLoaded = didInit = waitingForEI = initPending = didAppend = appendSuccess = disabled = useGlobalHTML5Audio = sm2.swfLoaded = false;
sm2.soundIDs = [];
sm2.sounds = {};
if (!resetEvents) {
// reset callbacks for onready, ontimeout etc. so that they will fire again on re-init
for (i in on_queue) {
if (on_queue.hasOwnProperty(i)) {
for (j = 0, k = on_queue[i].length; j < k; j++) {
on_queue[i][j].fired = false;
}
}
}
} else {
// remove all callbacks entirely
on_queue = [];
}
// <d>
if (!excludeInit) {
sm2._wD(sm + ': Rebooting...');
}
// </d>
// reset HTML5 and flash canPlay test results
sm2.html5 = {
'usingFlash': null
};
sm2.flash = {};
// reset device-specific HTML/flash mode switches
sm2.html5Only = false;
sm2.ignoreFlash = false;
window.setTimeout(function() {
preInit();
// by default, re-init
if (!excludeInit) {
sm2.beginDelayedInit();
}
}, 20);
return sm2;
};
this.reset = function() {
/**
* Shuts down and restores the SoundManager instance to its original loaded state, without an explicit reboot. All onready/ontimeout handlers are removed.
* After this call, SM2 may be re-initialized via soundManager.beginDelayedInit().
* @return {object} soundManager The soundManager instance.
*/
_wDS('reset');
return sm2.reboot(true, true);
};
/**
* Undocumented: Determines the SM2 flash movie's load progress.
*
* @return {number or null} Percent loaded, or if invalid/unsupported, null.
*/
this.getMoviePercent = function() {
/**
* Interesting syntax notes...
* Flash/ExternalInterface (ActiveX/NPAPI) bridge methods are not typeof "function" nor instanceof Function, but are still valid.
* Additionally, JSLint dislikes ('PercentLoaded' in flash)-style syntax and recommends hasOwnProperty(), which does not work in this case.
* Furthermore, using (flash && flash.PercentLoaded) causes IE to throw "object doesn't support this property or method".
* Thus, 'in' syntax must be used.
*/
return (flash && 'PercentLoaded' in flash ? flash.PercentLoaded() : null); // Yes, JSLint. See nearby comment in source for explanation.
};
/**
* Additional helper for manually invoking SM2's init process after DOM Ready / window.onload().
*/
this.beginDelayedInit = function() {
windowLoaded = true;
domContentLoaded();
setTimeout(function() {
if (initPending) {
return false;
}
createMovie();
initMovie();
initPending = true;
return true;
}, 20);
delayWaitForEI();
};
/**
* Destroys the SoundManager instance and all SMSound instances.
*/
this.destruct = function() {
sm2._wD(sm + '.destruct()');
sm2.disable(true);
};
/**
* SMSound() (sound object) constructor
* ------------------------------------
*
* @param {object} oOptions Sound options (id and url are required attributes)
* @return {SMSound} The new SMSound object
*/
SMSound = function(oOptions) {
var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State;
lastHTML5State = {
// tracks duration + position (time)
duration: null,
time: null
};
this.id = oOptions.id;
// legacy
this.sID = this.id;
this.url = oOptions.url;
this.options = mixin(oOptions);
// per-play-instance-specific options
this.instanceOptions = this.options;
// short alias
this._iO = this.instanceOptions;
// assign property defaults
this.pan = this.options.pan;
this.volume = this.options.volume;
// whether or not this object is using HTML5
this.isHTML5 = false;
// internal HTML5 Audio() object reference
this._a = null;
/**
* SMSound() public methods
* ------------------------
*/
this.id3 = {};
/**
* Writes SMSound object parameters to debug console
*/
this._debug = function() {
// <d>
sm2._wD(s.id + ': Merged options:', s.options);
// </d>
};
/**
* Begins loading a sound per its *url*.
*
* @param {object} oOptions Optional: Sound options
* @return {SMSound} The SMSound object
*/
this.load = function(oOptions) {
var oSound = null, instanceOptions;
if (oOptions !== _undefined) {
s._iO = mixin(oOptions, s.options);
} else {
oOptions = s.options;
s._iO = oOptions;
if (lastURL && lastURL !== s.url) {
_wDS('manURL');
s._iO.url = s.url;
s.url = null;
}
}
if (!s._iO.url) {
s._iO.url = s.url;
}
s._iO.url = parseURL(s._iO.url);
// ensure we're in sync
s.instanceOptions = s._iO;
// local shortcut
instanceOptions = s._iO;
sm2._wD(s.id + ': load (' + instanceOptions.url + ')');
if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) {
_wDS('onURL', 1);
// if loaded and an onload() exists, fire immediately.
if (s.readyState === 3 && instanceOptions.onload) {
// assume success based on truthy duration.
instanceOptions.onload.apply(s, [(!!s.duration)]);
}
return s;
}
// reset a few state properties
s.loaded = false;
s.readyState = 1;
s.playState = 0;
s.id3 = {};
// TODO: If switching from HTML5 -> flash (or vice versa), stop currently-playing audio.
if (html5OK(instanceOptions)) {
oSound = s._setup_html5(instanceOptions);
if (!oSound._called_load) {
s._html5_canplay = false;
// TODO: review called_load / html5_canplay logic
// if url provided directly to load(), assign it here.
if (s.url !== instanceOptions.url) {
sm2._wD(_wDS('manURL') + ': ' + instanceOptions.url);
s._a.src = instanceOptions.url;
// TODO: review / re-apply all relevant options (volume, loop, onposition etc.)
// reset position for new URL
s.setPosition(0);
}
// given explicit load call, try to preload.
// early HTML5 implementation (non-standard)
s._a.autobuffer = 'auto';
// standard
s._a.preload = 'auto';
s._a._called_load = true;
if (instanceOptions.autoPlay) {
s.play();
}
} else {
sm2._wD(s.id + ': Ignoring request to load again');
}
} else {
try {
s.isHTML5 = false;
s._iO = policyFix(loopFix(instanceOptions));
// re-assign local shortcut
instanceOptions = s._iO;
if (fV === 8) {
flash._load(s.id, instanceOptions.url, instanceOptions.stream, instanceOptions.autoPlay, instanceOptions.usePolicyFile);
} else {
flash._load(s.id, instanceOptions.url, !!(instanceOptions.stream), !!(instanceOptions.autoPlay), instanceOptions.loops||1, !!(instanceOptions.autoLoad), instanceOptions.usePolicyFile);
}
} catch(e) {
_wDS('smError', 2);
debugTS('onload', false);
catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});
}
}
// after all of this, ensure sound url is up to date.
s.url = instanceOptions.url;
return s;
};
/**
* Unloads a sound, canceling any open HTTP requests.
*
* @return {SMSound} The SMSound object
*/
this.unload = function() {
// Flash 8/AS2 can't "close" a stream - fake it by loading an empty URL
// Flash 9/AS3: Close stream, preventing further load
// HTML5: Most UAs will use empty URL
if (s.readyState !== 0) {
sm2._wD(s.id + ': unload()');
if (!s.isHTML5) {
if (fV === 8) {
flash._unload(s.id, emptyURL);
} else {
flash._unload(s.id);
}
} else {
stop_html5_timer();
if (s._a) {
s._a.pause();
html5Unload(s._a, emptyURL);
// update empty URL, too
lastURL = emptyURL;
}
}
// reset load/status flags
resetProperties();
}
return s;
};
/**
* Unloads and destroys a sound.
*/
this.destruct = function(_bFromSM) {
sm2._wD(s.id + ': Destruct');
if (!s.isHTML5) {
// kill sound within Flash
// Disable the onfailure handler
s._iO.onfailure = null;
flash._destroySound(s.id);
} else {
stop_html5_timer();
if (s._a) {
s._a.pause();
html5Unload(s._a);
if (!useGlobalHTML5Audio) {
remove_html5_events();
}
// break obvious circular reference
s._a._s = null;
s._a = null;
}
}
if (!_bFromSM) {
// ensure deletion from controller
sm2.destroySound(s.id, true);
}
};
/**
* Begins playing a sound.
*
* @param {object} oOptions Optional: Sound options
* @return {SMSound} The SMSound object
*/
this.play = function(oOptions, _updatePlayState) {
var fN, allowMulti, a, onready, startOK = true,
exit = null;
// <d>
fN = s.id + ': play(): ';
// </d>
// default to true
_updatePlayState = (_updatePlayState === _undefined ? true : _updatePlayState);
if (!oOptions) {
oOptions = {};
}
// first, use local URL (if specified)
if (s.url) {
s._iO.url = s.url;
}
// mix in any options defined at createSound()
s._iO = mixin(s._iO, s.options);
// mix in any options specific to this method
s._iO = mixin(oOptions, s._iO);
s._iO.url = parseURL(s._iO.url);
s.instanceOptions = s._iO;
// RTMP-only
if (s._iO.serverURL && !s.connected) {
if (!s.getAutoPlay()) {
sm2._wD(fN +' Netstream not connected yet - setting autoPlay');
s.setAutoPlay(true);
}
// play will be called in onconnect()
return s;
}
if (html5OK(s._iO)) {
s._setup_html5(s._iO);
start_html5_timer();
}
if (s.playState === 1 && !s.paused) {
allowMulti = s._iO.multiShot;
if (!allowMulti) {
sm2._wD(fN + 'Already playing (one-shot)', 1);
exit = s;
} else {
sm2._wD(fN + 'Already playing (multi-shot)', 1);
}
}
if (exit !== null) {
return exit;
}
// edge case: play() with explicit URL parameter
if (oOptions.url && oOptions.url !== s.url) {
// load using merged options
s.load(s._iO);
}
if (!s.loaded) {
if (s.readyState === 0) {
sm2._wD(fN + 'Attempting to load');
// try to get this sound playing ASAP
if (!s.isHTML5) {
// assign directly because setAutoPlay() increments the instanceCount
s._iO.autoPlay = true;
s.load(s._iO);
} else {
// iOS needs this when recycling sounds, loading a new URL on an existing object.
s.load(s._iO);
}
// HTML5 hack - re-set instanceOptions?
s.instanceOptions = s._iO;
} else if (s.readyState === 2) {
sm2._wD(fN + 'Could not load - exiting', 2);
exit = s;
} else {
sm2._wD(fN + 'Loading - attempting to play...');
}
} else {
sm2._wD(fN);
}
if (exit !== null) {
return exit;
}
if (!s.isHTML5 && fV === 9 && s.position > 0 && s.position === s.duration) {
// flash 9 needs a position reset if play() is called while at the end of a sound.
sm2._wD(fN + 'Sound at end, resetting to position:0');
oOptions.position = 0;
}
/**
* Streams will pause when their buffer is full if they are being loaded.
* 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.
* So only call resume() if the position is > 0.
* Another reason is because options like volume won't have been applied yet.
* For normal sounds, just resume.
*/
if (s.paused && s.position >= 0 && (!s._iO.serverURL || s.position > 0)) {
// https://gist.github.com/37b17df75cc4d7a90bf6
sm2._wD(fN + 'Resuming from paused state', 1);
s.resume();
} else {
s._iO = mixin(oOptions, s._iO);
// apply from/to parameters, if they exist (and not using RTMP)
if (s._iO.from !== null && s._iO.to !== null && s.instanceCount === 0 && s.playState === 0 && !s._iO.serverURL) {
onready = function() {
// sound "canplay" or onload()
// re-apply from/to to instance options, and start playback
s._iO = mixin(oOptions, s._iO);
s.play(s._iO);
};
// HTML5 needs to at least have "canplay" fired before seeking.
if (s.isHTML5 && !s._html5_canplay) {
// this hasn't been loaded yet. load it first, and then do this again.
sm2._wD(fN + 'Beginning load for from/to case');
s.load({
// TODO: was _oncanplay. Sounds wrong.
oncanplay: onready
});
exit = false;
} else if (!s.isHTML5 && !s.loaded && (!s.readyState || s.readyState !== 2)) {
// to be safe, preload the whole thing in Flash.
sm2._wD(fN + 'Preloading for from/to case');
s.load({
onload: onready
});
exit = false;
}
if (exit !== null) {
return exit;
}
// otherwise, we're ready to go. re-apply local options, and continue
s._iO = applyFromTo();
}
sm2._wD(fN + 'Starting to play');
if (!s.instanceCount || s._iO.multiShotEvents || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) {
s.instanceCount++;
}
// if first play and onposition parameters exist, apply them now
if (s._iO.onposition && s.playState === 0) {
attachOnPosition(s);
}
s.playState = 1;
s.paused = false;
s.position = (s._iO.position !== _undefined && !isNaN(s._iO.position) ? s._iO.position : 0);
if (!s.isHTML5) {
s._iO = policyFix(loopFix(s._iO));
}
if (s._iO.onplay && _updatePlayState) {
s._iO.onplay.apply(s);
onplay_called = true;
}
s.setVolume(s._iO.volume, true);
s.setPan(s._iO.pan, true);
if (!s.isHTML5) {
startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s._iO.position : s._iO.position / 1000), s._iO.multiShot);
if (fV === 9 && !startOK) {
// edge case: no sound hardware, or 32-channel flash ceiling hit.
// applies only to Flash 9, non-NetStream/MovieStar sounds.
// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#play%28%29
sm2._wD(fN + 'No sound hardware, or 32-sound ceiling hit');
if (s._iO.onplayerror) {
s._iO.onplayerror.apply(s);
}
}
} else {
start_html5_timer();
a = s._setup_html5();
s.setPosition(s._iO.position);
a.play();
}
}
return s;
};
// just for convenience
this.start = this.play;
/**
* Stops playing a sound (and optionally, all sounds)
*
* @param {boolean} bAll Optional: Whether to stop all sounds
* @return {SMSound} The SMSound object
*/
this.stop = function(bAll) {
var instanceOptions = s._iO,
originalPosition;
if (s.playState === 1) {
sm2._wD(s.id + ': stop()');
s._onbufferchange(0);
s._resetOnPosition(0);
s.paused = false;
if (!s.isHTML5) {
s.playState = 0;
}
// remove onPosition listeners, if any
detachOnPosition();
// and "to" position, if set
if (instanceOptions.to) {
s.clearOnPosition(instanceOptions.to);
}
if (!s.isHTML5) {
flash._stop(s.id, bAll);
// hack for netStream: just unload
if (instanceOptions.serverURL) {
s.unload();
}
} else {
if (s._a) {
originalPosition = s.position;
// act like Flash, though
s.setPosition(0);
// hack: reflect old position for onstop() (also like Flash)
s.position = originalPosition;
// html5 has no stop()
// NOTE: pausing means iOS requires interaction to resume.
s._a.pause();
s.playState = 0;
// and update UI
s._onTimer();
stop_html5_timer();
}
}
s.instanceCount = 0;
s._iO = {};
if (instanceOptions.onstop) {
instanceOptions.onstop.apply(s);
}
}
return s;
};
/**
* Undocumented/internal: Sets autoPlay for RTMP.
*
* @param {boolean} autoPlay state
*/
this.setAutoPlay = function(autoPlay) {
sm2._wD(s.id + ': Autoplay turned ' + (autoPlay ? 'on' : 'off'));
s._iO.autoPlay = autoPlay;
if (!s.isHTML5) {
flash._setAutoPlay(s.id, autoPlay);
if (autoPlay) {
// only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP)
if (!s.instanceCount && s.readyState === 1) {
s.instanceCount++;
sm2._wD(s.id + ': Incremented instance count to '+s.instanceCount);
}
}
}
};
/**
* Undocumented/internal: Returns the autoPlay boolean.
*
* @return {boolean} The current autoPlay value
*/
this.getAutoPlay = function() {
return s._iO.autoPlay;
};
/**
* Sets the position of a sound.
*
* @param {number} nMsecOffset Position (milliseconds)
* @return {SMSound} The SMSound object
*/
this.setPosition = function(nMsecOffset) {
if (nMsecOffset === _undefined) {
nMsecOffset = 0;
}
var original_pos,
position, position1K,
// Use the duration from the instance options, if we don't have a track duration yet.
// position >= 0 and <= current available (loaded) duration
offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0)));
original_pos = s.position;
s.position = offset;
position1K = s.position/1000;
s._resetOnPosition(s.position);
s._iO.position = offset;
if (!s.isHTML5) {
position = (fV === 9 ? s.position : position1K);
if (s.readyState && s.readyState !== 2) {
// if paused or not playing, will not resume (by playing)
flash._setPosition(s.id, position, (s.paused || !s.playState), s._iO.multiShot);
}
} else if (s._a) {
// Set the position in the canplay handler if the sound is not ready yet
if (s._html5_canplay) {
if (s._a.currentTime !== position1K) {
/**
* DOM/JS errors/exceptions to watch out for:
* if seek is beyond (loaded?) position, "DOM exception 11"
* "INDEX_SIZE_ERR": DOM exception 1
*/
sm2._wD(s.id + ': setPosition('+position1K+')');
try {
s._a.currentTime = position1K;
if (s.playState === 0 || s.paused) {
// allow seek without auto-play/resume
s._a.pause();
}
} catch(e) {
sm2._wD(s.id + ': setPosition(' + position1K + ') failed: ' + e.message, 2);
}
}
} else {
sm2._wD(s.id + ': setPosition(' + position1K + '): Cannot seek yet, sound not ready');
}
}
if (s.isHTML5) {
if (s.paused) {
// if paused, refresh UI right away
// force update
s._onTimer(true);
}
}
return s;
};
/**
* Pauses sound playback.
*
* @return {SMSound} The SMSound object
*/
this.pause = function(_bCallFlash) {
if (s.paused || (s.playState === 0 && s.readyState !== 1)) {
return s;
}
sm2._wD(s.id + ': pause()');
s.paused = true;
if (!s.isHTML5) {
if (_bCallFlash || _bCallFlash === _undefined) {
flash._pause(s.id, s._iO.multiShot);
}
} else {
s._setup_html5().pause();
stop_html5_timer();
}
if (s._iO.onpause) {
s._iO.onpause.apply(s);
}
return s;
};
/**
* Resumes sound playback.
*
* @return {SMSound} The SMSound object
*/
/**
* 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".
* When a paused stream is resumed, we need to trigger the onplay() callback if it
* hasn't been called already. In this case since the sound is being played for the
* first time, I think it's more appropriate to call onplay() rather than onresume().
*/
this.resume = function() {
var instanceOptions = s._iO;
if (!s.paused) {
return s;
}
sm2._wD(s.id + ': resume()');
s.paused = false;
s.playState = 1;
if (!s.isHTML5) {
if (instanceOptions.isMovieStar && !instanceOptions.serverURL) {
// Bizarre Webkit bug (Chrome reported via 8tracks.com dudes): AAC content paused for 30+ seconds(?) will not resume without a reposition.
s.setPosition(s.position);
}
// flash method is toggle-based (pause/resume)
flash._pause(s.id, instanceOptions.multiShot);
} else {
s._setup_html5().play();
start_html5_timer();
}
if (!onplay_called && instanceOptions.onplay) {
instanceOptions.onplay.apply(s);
onplay_called = true;
} else if (instanceOptions.onresume) {
instanceOptions.onresume.apply(s);
}
return s;
};
/**
* Toggles sound playback.
*
* @return {SMSound} The SMSound object
*/
this.togglePause = function() {
sm2._wD(s.id + ': togglePause()');
if (s.playState === 0) {
s.play({
position: (fV === 9 && !s.isHTML5 ? s.position : s.position / 1000)
});
return s;
}
if (s.paused) {
s.resume();
} else {
s.pause();
}
return s;
};
/**
* Sets the panning (L-R) effect.
*
* @param {number} nPan The pan value (-100 to 100)
* @return {SMSound} The SMSound object
*/
this.setPan = function(nPan, bInstanceOnly) {
if (nPan === _undefined) {
nPan = 0;
}
if (bInstanceOnly === _undefined) {
bInstanceOnly = false;
}
if (!s.isHTML5) {
flash._setPan(s.id, nPan);
} // else { no HTML5 pan? }
s._iO.pan = nPan;
if (!bInstanceOnly) {
s.pan = nPan;
s.options.pan = nPan;
}
return s;
};
/**
* Sets the volume.
*
* @param {number} nVol The volume value (0 to 100)
* @return {SMSound} The SMSound object
*/
this.setVolume = function(nVol, _bInstanceOnly) {
/**
* Note: Setting volume has no effect on iOS "special snowflake" devices.
* Hardware volume control overrides software, and volume
* will always return 1 per Apple docs. (iOS 4 + 5.)
* http://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingSoundtoCanvasAnimations/AddingSoundtoCanvasAnimations.html
*/
if (nVol === _undefined) {
nVol = 100;
}
if (_bInstanceOnly === _undefined) {
_bInstanceOnly = false;
}
if (!s.isHTML5) {
flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol);
} else if (s._a) {
// valid range: 0-1
s._a.volume = Math.max(0, Math.min(1, nVol/100));
}
s._iO.volume = nVol;
if (!_bInstanceOnly) {
s.volume = nVol;
s.options.volume = nVol;
}
return s;
};
/**
* Mutes the sound.
*
* @return {SMSound} The SMSound object
*/
this.mute = function() {
s.muted = true;
if (!s.isHTML5) {
flash._setVolume(s.id, 0);
} else if (s._a) {
s._a.muted = true;
}
return s;
};
/**
* Unmutes the sound.
*
* @return {SMSound} The SMSound object
*/
this.unmute = function() {
s.muted = false;
var hasIO = (s._iO.volume !== _undefined);
if (!s.isHTML5) {
flash._setVolume(s.id, hasIO?s._iO.volume:s.options.volume);
} else if (s._a) {
s._a.muted = false;
}
return s;
};
/**
* Toggles the muted state of a sound.
*
* @return {SMSound} The SMSound object
*/
this.toggleMute = function() {
return (s.muted?s.unmute():s.mute());
};
/**
* Registers a callback to be fired when a sound reaches a given position during playback.
*
* @param {number} nPosition The position to watch for
* @param {function} oMethod The relevant callback to fire
* @param {object} oScope Optional: The scope to apply the callback to
* @return {SMSound} The SMSound object
*/
this.onPosition = function(nPosition, oMethod, oScope) {
// TODO: basic dupe checking?
onPositionItems.push({
position: parseInt(nPosition, 10),
method: oMethod,
scope: (oScope !== _undefined ? oScope : s),
fired: false
});
return s;
};
// legacy/backwards-compability: lower-case method name
this.onposition = this.onPosition;
/**
* Removes registered callback(s) from a sound, by position and/or callback.
*
* @param {number} nPosition The position to clear callback(s) for
* @param {function} oMethod Optional: Identify one callback to be removed when multiple listeners exist for one position
* @return {SMSound} The SMSound object
*/
this.clearOnPosition = function(nPosition, oMethod) {
var i;
nPosition = parseInt(nPosition, 10);
if (isNaN(nPosition)) {
// safety check
return false;
}
for (i=0; i < onPositionItems.length; i++) {
if (nPosition === onPositionItems[i].position) {
// remove this item if no method was specified, or, if the method matches
if (!oMethod || (oMethod === onPositionItems[i].method)) {
if (onPositionItems[i].fired) {
// decrement "fired" counter, too
onPositionFired--;
}
onPositionItems.splice(i, 1);
}
}
}
};
this._processOnPosition = function() {
var i, item, j = onPositionItems.length;
if (!j || !s.playState || onPositionFired >= j) {
return false;
}
for (i=j-1; i >= 0; i--) {
item = onPositionItems[i];
if (!item.fired && s.position >= item.position) {
item.fired = true;
onPositionFired++;
item.method.apply(item.scope, [item.position]);
}
}
return true;
};
this._resetOnPosition = function(nPosition) {
// reset "fired" for items interested in this position
var i, item, j = onPositionItems.length;
if (!j) {
return false;
}
for (i=j-1; i >= 0; i--) {
item = onPositionItems[i];
if (item.fired && nPosition <= item.position) {
item.fired = false;
onPositionFired--;
}
}
return true;
};
/**
* SMSound() private internals
* --------------------------------
*/
applyFromTo = function() {
var instanceOptions = s._iO,
f = instanceOptions.from,
t = instanceOptions.to,
start, end;
end = function() {
// end has been reached.
sm2._wD(s.id + ': "To" time of ' + t + ' reached.');
// detach listener
s.clearOnPosition(t, end);
// stop should clear this, too
s.stop();
};
start = function() {
sm2._wD(s.id + ': Playing "from" ' + f);
// add listener for end
if (t !== null && !isNaN(t)) {
s.onPosition(t, end);
}
};
if (f !== null && !isNaN(f)) {
// apply to instance options, guaranteeing correct start position.
instanceOptions.position = f;
// multiShot timing can't be tracked, so prevent that.
instanceOptions.multiShot = false;
start();
}
// return updated instanceOptions including starting position
return instanceOptions;
};
attachOnPosition = function() {
var item,
op = s._iO.onposition;
// attach onposition things, if any, now.
if (op) {
for (item in op) {
if (op.hasOwnProperty(item)) {
s.onPosition(parseInt(item, 10), op[item]);
}
}
}
};
detachOnPosition = function() {
var item,
op = s._iO.onposition;
// detach any onposition()-style listeners.
if (op) {
for (item in op) {
if (op.hasOwnProperty(item)) {
s.clearOnPosition(parseInt(item, 10));
}
}
}
};
start_html5_timer = function() {
if (s.isHTML5) {
startTimer(s);
}
};
stop_html5_timer = function() {
if (s.isHTML5) {
stopTimer(s);
}
};
resetProperties = function(retainPosition) {
if (!retainPosition) {
onPositionItems = [];
onPositionFired = 0;
}
onplay_called = false;
s._hasTimer = null;
s._a = null;
s._html5_canplay = false;
s.bytesLoaded = null;
s.bytesTotal = null;
s.duration = (s._iO && s._iO.duration ? s._iO.duration : null);
s.durationEstimate = null;
s.buffered = [];
// legacy: 1D array
s.eqData = [];
s.eqData.left = [];
s.eqData.right = [];
s.failures = 0;
s.isBuffering = false;
s.instanceOptions = {};
s.instanceCount = 0;
s.loaded = false;
s.metadata = {};
// 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success
s.readyState = 0;
s.muted = false;
s.paused = false;
s.peakData = {
left: 0,
right: 0
};
s.waveformData = {
left: [],
right: []
};
s.playState = 0;
s.position = null;
s.id3 = {};
};
resetProperties();
/**
* Pseudo-private SMSound internals
* --------------------------------
*/
this._onTimer = function(bForce) {
/**
* HTML5-only _whileplaying() etc.
* called from both HTML5 native events, and polling/interval-based timers
* mimics flash and fires only when time/duration change, so as to be polling-friendly
*/
var duration, isNew = false, time, x = {};
if (s._hasTimer || bForce) {
// TODO: May not need to track readyState (1 = loading)
if (s._a && (bForce || ((s.playState > 0 || s.readyState === 1) && !s.paused))) {
duration = s._get_html5_duration();
if (duration !== lastHTML5State.duration) {
lastHTML5State.duration = duration;
s.duration = duration;
isNew = true;
}
// TODO: investigate why this goes wack if not set/re-set each time.
s.durationEstimate = s.duration;
time = (s._a.currentTime * 1000 || 0);
if (time !== lastHTML5State.time) {
lastHTML5State.time = time;
isNew = true;
}
if (isNew || bForce) {
s._whileplaying(time,x,x,x,x);
}
}/* else {
// sm2._wD('_onTimer: Warn for "'+s.id+'": '+(!s._a?'Could not find element. ':'')+(s.playState === 0?'playState bad, 0?':'playState = '+s.playState+', OK'));
return false;
}*/
return isNew;
}
};
this._get_html5_duration = function() {
var instanceOptions = s._iO,
// if audio object exists, use its duration - else, instance option duration (if provided - it's a hack, really, and should be retired) OR null
d = (s._a && s._a.duration ? s._a.duration*1000 : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)),
result = (d && !isNaN(d) && d !== Infinity ? d : null);
return result;
};
this._apply_loop = function(a, nLoops) {
/**
* boolean instead of "loop", for webkit? - spec says string. http://www.w3.org/TR/html-markup/audio.html#audio.attrs.loop
* note that loop is either off or infinite under HTML5, unlike Flash which allows arbitrary loop counts to be specified.
*/
// <d>
if (!a.loop && nLoops > 1) {
sm2._wD('Note: Native HTML5 looping is infinite.', 1);
}
// </d>
a.loop = (nLoops > 1 ? 'loop' : '');
};
this._setup_html5 = function(oOptions) {
var instanceOptions = mixin(s._iO, oOptions), d = decodeURI,
a = useGlobalHTML5Audio ? globalHTML5Audio : s._a,
dURL = d(instanceOptions.url),
sameURL;
/**
* "First things first, I, Poppa..." (reset the previous state of the old sound, if playing)
* Fixes case with devices that can only play one sound at a time
* Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state
*/
if (useGlobalHTML5Audio) {
if (dURL === lastGlobalHTML5URL) {
// global HTML5 audio: re-use of URL
sameURL = true;
}
} else if (dURL === lastURL) {
// options URL is the same as the "last" URL, and we used (loaded) it
sameURL = true;
}
if (a) {
if (a._s) {
if (useGlobalHTML5Audio) {
if (a._s && a._s.playState && !sameURL) {
// global HTML5 audio case, and loading a new URL. stop the currently-playing one.
a._s.stop();
}
} else if (!useGlobalHTML5Audio && dURL === d(lastURL)) {
// non-global HTML5 reuse case: same url, ignore request
s._apply_loop(a, instanceOptions.loops);
return a;
}
}
if (!sameURL) {
// don't retain onPosition() stuff with new URL.
resetProperties(false);
// assign new HTML5 URL
a.src = instanceOptions.url;
s.url = instanceOptions.url;
lastURL = instanceOptions.url;
lastGlobalHTML5URL = instanceOptions.url;
a._called_load = false;
}
} else {
if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
s._a = new Audio(instanceOptions.url);
} else {
// null for stupid Opera 9.64 case
s._a = (isOpera && opera.version() < 10 ? new Audio(null) : new Audio());
}
// assign local reference
a = s._a;
a._called_load = false;
if (useGlobalHTML5Audio) {
globalHTML5Audio = a;
}
}
s.isHTML5 = true;
// store a ref on the track
s._a = a;
// store a ref on the audio
a._s = s;
add_html5_events();
s._apply_loop(a, instanceOptions.loops);
if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
s.load();
} else {
// early HTML5 implementation (non-standard)
a.autobuffer = false;
// standard ('none' is also an option.)
a.preload = 'auto';
}
return a;
};
add_html5_events = function() {
if (s._a._added_events) {
return false;
}
var f;
function add(oEvt, oFn, bCapture) {
return s._a ? s._a.addEventListener(oEvt, oFn, bCapture||false) : null;
}
s._a._added_events = true;
for (f in html5_events) {
if (html5_events.hasOwnProperty(f)) {
add(f, html5_events[f]);
}
}
return true;
};
remove_html5_events = function() {
// Remove event listeners
var f;
function remove(oEvt, oFn, bCapture) {
return (s._a ? s._a.removeEventListener(oEvt, oFn, bCapture||false) : null);
}
sm2._wD(s.id + ': Removing event listeners');
s._a._added_events = false;
for (f in html5_events) {
if (html5_events.hasOwnProperty(f)) {
remove(f, html5_events[f]);
}
}
};
/**
* Pseudo-private event internals
* ------------------------------
*/
this._onload = function(nSuccess) {
var fN,
// check for duration to prevent false positives from flash 8 when loading from cache.
loadOK = !!nSuccess || (!s.isHTML5 && fV === 8 && s.duration);
// <d>
fN = s.id + ': ';
sm2._wD(fN + (loadOK ? 'onload()' : 'Failed to load? - ' + s.url), (loadOK ? 1 : 2));
if (!loadOK && !s.isHTML5) {
if (sm2.sandbox.noRemote === true) {
sm2._wD(fN + str('noNet'), 1);
}
if (sm2.sandbox.noLocal === true) {
sm2._wD(fN + str('noLocal'), 1);
}
}
// </d>
s.loaded = loadOK;
s.readyState = loadOK?3:2;
s._onbufferchange(0);
if (s._iO.onload) {
s._iO.onload.apply(s, [loadOK]);
}
return true;
};
this._onbufferchange = function(nIsBuffering) {
if (s.playState === 0) {
// ignore if not playing
return false;
}
if ((nIsBuffering && s.isBuffering) || (!nIsBuffering && !s.isBuffering)) {
return false;
}
s.isBuffering = (nIsBuffering === 1);
if (s._iO.onbufferchange) {
sm2._wD(s.id + ': Buffer state change: ' + nIsBuffering);
s._iO.onbufferchange.apply(s);
}
return true;
};
/**
* Playback may have stopped due to buffering, or related reason.
* This state can be encountered on iOS < 6 when auto-play is blocked.
*/
this._onsuspend = function() {
if (s._iO.onsuspend) {
sm2._wD(s.id + ': Playback suspended');
s._iO.onsuspend.apply(s);
}
return true;
};
/**
* flash 9/movieStar + RTMP-only method, should fire only once at most
* at this point we just recreate failed sounds rather than trying to reconnect
*/
this._onfailure = function(msg, level, code) {
s.failures++;
sm2._wD(s.id + ': Failures = ' + s.failures);
if (s._iO.onfailure && s.failures === 1) {
s._iO.onfailure(s, msg, level, code);
} else {
sm2._wD(s.id + ': Ignoring failure');
}
};
this._onfinish = function() {
// store local copy before it gets trashed...
var io_onfinish = s._iO.onfinish;
s._onbufferchange(0);
s._resetOnPosition(0);
// reset some state items
if (s.instanceCount) {
s.instanceCount--;
if (!s.instanceCount) {
// remove onPosition listeners, if any
detachOnPosition();
// reset instance options
s.playState = 0;
s.paused = false;
s.instanceCount = 0;
s.instanceOptions = {};
s._iO = {};
stop_html5_timer();
// reset position, too
if (s.isHTML5) {
s.position = 0;
}
}
if (!s.instanceCount || s._iO.multiShotEvents) {
// fire onfinish for last, or every instance
if (io_onfinish) {
sm2._wD(s.id + ': onfinish()');
io_onfinish.apply(s);
}
}
}
};
this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {
var instanceOptions = s._iO;
s.bytesLoaded = nBytesLoaded;
s.bytesTotal = nBytesTotal;
s.duration = Math.floor(nDuration);
s.bufferLength = nBufferLength;
if (!s.isHTML5 && !instanceOptions.isMovieStar) {
if (instanceOptions.duration) {
// use duration from options, if specified and larger. nobody should be specifying duration in options, actually, and it should be retired.
s.durationEstimate = (s.duration > instanceOptions.duration) ? s.duration : instanceOptions.duration;
} else {
s.durationEstimate = parseInt((s.bytesTotal / s.bytesLoaded) * s.duration, 10);
}
} else {
s.durationEstimate = s.duration;
}
// for flash, reflect sequential-load-style buffering
if (!s.isHTML5) {
s.buffered = [{
'start': 0,
'end': s.duration
}];
}
// allow whileloading to fire even if "load" fired under HTML5, due to HTTP range/partials
if ((s.readyState !== 3 || s.isHTML5) && instanceOptions.whileloading) {
instanceOptions.whileloading.apply(s);
}
};
this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {
var instanceOptions = s._iO,
eqLeft;
if (isNaN(nPosition) || nPosition === null) {
// flash safety net
return false;
}
// Safari HTML5 play() may return small -ve values when starting from position: 0, eg. -50.120396875. Unexpected/invalid per W3, I think. Normalize to 0.
s.position = Math.max(0, nPosition);
s._processOnPosition();
if (!s.isHTML5 && fV > 8) {
if (instanceOptions.usePeakData && oPeakData !== _undefined && oPeakData) {
s.peakData = {
left: oPeakData.leftPeak,
right: oPeakData.rightPeak
};
}
if (instanceOptions.useWaveformData && oWaveformDataLeft !== _undefined && oWaveformDataLeft) {
s.waveformData = {
left: oWaveformDataLeft.split(','),
right: oWaveformDataRight.split(',')
};
}
if (instanceOptions.useEQData) {
if (oEQData !== _undefined && oEQData && oEQData.leftEQ) {
eqLeft = oEQData.leftEQ.split(',');
s.eqData = eqLeft;
s.eqData.left = eqLeft;
if (oEQData.rightEQ !== _undefined && oEQData.rightEQ) {
s.eqData.right = oEQData.rightEQ.split(',');
}
}
}
}
if (s.playState === 1) {
// special case/hack: ensure buffering is false if loading from cache (and not yet started)
if (!s.isHTML5 && fV === 8 && !s.position && s.isBuffering) {
s._onbufferchange(0);
}
if (instanceOptions.whileplaying) {
// flash may call after actual finish
instanceOptions.whileplaying.apply(s);
}
}
return true;
};
this._oncaptiondata = function(oData) {
/**
* internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
*
* @param {object} oData
*/
sm2._wD(s.id + ': Caption data received.');
s.captiondata = oData;
if (s._iO.oncaptiondata) {
s._iO.oncaptiondata.apply(s, [oData]);
}
};
this._onmetadata = function(oMDProps, oMDData) {
/**
* internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
* RTMP may include song title, MovieStar content may include encoding info
*
* @param {array} oMDProps (names)
* @param {array} oMDData (values)
*/
sm2._wD(s.id + ': Metadata received.');
var oData = {}, i, j;
for (i = 0, j = oMDProps.length; i < j; i++) {
oData[oMDProps[i]] = oMDData[i];
}
s.metadata = oData;
if (s._iO.onmetadata) {
s._iO.onmetadata.apply(s);
}
};
this._onid3 = function(oID3Props, oID3Data) {
/**
* internal: flash 8 + flash 9 ID3 feature
* may include artist, song title etc.
*
* @param {array} oID3Props (names)
* @param {array} oID3Data (values)
*/
sm2._wD(s.id + ': ID3 data received.');
var oData = [], i, j;
for (i = 0, j = oID3Props.length; i < j; i++) {
oData[oID3Props[i]] = oID3Data[i];
}
s.id3 = mixin(s.id3, oData);
if (s._iO.onid3) {
s._iO.onid3.apply(s);
}
};
// flash/RTMP-only
this._onconnect = function(bSuccess) {
bSuccess = (bSuccess === 1);
sm2._wD(s.id + ': ' + (bSuccess ? 'Connected.' : 'Failed to connect? - ' + s.url), (bSuccess ? 1 : 2));
s.connected = bSuccess;
if (bSuccess) {
s.failures = 0;
if (idCheck(s.id)) {
if (s.getAutoPlay()) {
// only update the play state if auto playing
s.play(_undefined, s.getAutoPlay());
} else if (s._iO.autoLoad) {
s.load();
}
}
if (s._iO.onconnect) {
s._iO.onconnect.apply(s, [bSuccess]);
}
}
};
this._ondataerror = function(sError) {
// flash 9 wave/eq data handler
// hack: called at start, and end from flash at/after onfinish()
if (s.playState > 0) {
sm2._wD(s.id + ': Data error: ' + sError);
if (s._iO.ondataerror) {
s._iO.ondataerror.apply(s);
}
}
};
// <d>
this._debug();
// </d>
}; // SMSound()
/**
* Private SoundManager internals
* ------------------------------
*/
getDocument = function() {
return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]);
};
id = function(sID) {
return doc.getElementById(sID);
};
mixin = function(oMain, oAdd) {
// non-destructive merge
var o1 = (oMain || {}), o2, o;
// if unspecified, o2 is the default options object
o2 = (oAdd === _undefined ? sm2.defaultOptions : oAdd);
for (o in o2) {
if (o2.hasOwnProperty(o) && o1[o] === _undefined) {
if (typeof o2[o] !== 'object' || o2[o] === null) {
// assign directly
o1[o] = o2[o];
} else {
// recurse through o2
o1[o] = mixin(o1[o], o2[o]);
}
}
}
return o1;
};
// additional soundManager properties that soundManager.setup() will accept
extraOptions = {
'onready': 1,
'ontimeout': 1,
'defaultOptions': 1,
'flash9Options': 1,
'movieStarOptions': 1
};
assign = function(o, oParent) {
/**
* recursive assignment of properties, soundManager.setup() helper
* allows property assignment based on whitelist
*/
var i,
result = true,
hasParent = (oParent !== _undefined),
setupOptions = sm2.setupOptions,
bonusOptions = extraOptions;
// <d>
// if soundManager.setup() called, show accepted parameters.
if (o === _undefined) {
result = [];
for (i in setupOptions) {
if (setupOptions.hasOwnProperty(i)) {
result.push(i);
}
}
for (i in bonusOptions) {
if (bonusOptions.hasOwnProperty(i)) {
if (typeof sm2[i] === 'object') {
result.push(i+': {...}');
} else if (sm2[i] instanceof Function) {
result.push(i+': function() {...}');
} else {
result.push(i);
}
}
}
sm2._wD(str('setup', result.join(', ')));
return false;
}
// </d>
for (i in o) {
if (o.hasOwnProperty(i)) {
// if not an {object} we want to recurse through...
if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array || o[i] instanceof RegExp) {
// check "allowed" options
if (hasParent && bonusOptions[oParent] !== _undefined) {
// valid recursive / nested object option, eg., { defaultOptions: { volume: 50 } }
sm2[oParent][i] = o[i];
} else if (setupOptions[i] !== _undefined) {
// special case: assign to setupOptions object, which soundManager property references
sm2.setupOptions[i] = o[i];
// assign directly to soundManager, too
sm2[i] = o[i];
} else if (bonusOptions[i] === _undefined) {
// invalid or disallowed parameter. complain.
complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
result = false;
} else {
/**
* valid extraOptions (bonusOptions) parameter.
* is it a method, like onready/ontimeout? call it.
* multiple parameters should be in an array, eg. soundManager.setup({onready: [myHandler, myScope]});
*/
if (sm2[i] instanceof Function) {
sm2[i].apply(sm2, (o[i] instanceof Array? o[i] : [o[i]]));
} else {
// good old-fashioned direct assignment
sm2[i] = o[i];
}
}
} else {
// recursion case, eg., { defaultOptions: { ... } }
if (bonusOptions[i] === _undefined) {
// invalid or disallowed parameter. complain.
complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
result = false;
} else {
// recurse through object
return assign(o[i], i);
}
}
}
}
return result;
};
function preferFlashCheck(kind) {
// whether flash should play a given type
return (sm2.preferFlash && hasFlash && !sm2.ignoreFlash && (sm2.flash[kind] !== _undefined && sm2.flash[kind]));
}
/**
* Internal DOM2-level event helpers
* ---------------------------------
*/
event = (function() {
// normalize event methods
var old = (window.attachEvent),
evt = {
add: (old?'attachEvent':'addEventListener'),
remove: (old?'detachEvent':'removeEventListener')
};
// normalize "on" event prefix, optional capture argument
function getArgs(oArgs) {
var args = slice.call(oArgs),
len = args.length;
if (old) {
// prefix
args[1] = 'on' + args[1];
if (len > 3) {
// no capture
args.pop();
}
} else if (len === 3) {
args.push(false);
}
return args;
}
function apply(args, sType) {
// normalize and call the event method, with the proper arguments
var element = args.shift(),
method = [evt[sType]];
if (old) {
// old IE can't do apply().
element[method](args[0], args[1]);
} else {
element[method].apply(element, args);
}
}
function add() {
apply(getArgs(arguments), 'add');
}
function remove() {
apply(getArgs(arguments), 'remove');
}
return {
'add': add,
'remove': remove
};
}());
/**
* Internal HTML5 event handling
* -----------------------------
*/
function html5_event(oFn) {
// wrap html5 event handlers so we don't call them on destroyed and/or unloaded sounds
return function(e) {
var s = this._s,
result;
if (!s || !s._a) {
// <d>
if (s && s.id) {
sm2._wD(s.id + ': Ignoring ' + e.type);
} else {
sm2._wD(h5 + 'Ignoring ' + e.type);
}
// </d>
result = null;
} else {
result = oFn.call(this, e);
}
return result;
};
}
html5_events = {
// HTML5 event-name-to-handler map
abort: html5_event(function() {
sm2._wD(this._s.id + ': abort');
}),
// enough has loaded to play
canplay: html5_event(function() {
var s = this._s,
position1K;
if (s._html5_canplay) {
// this event has already fired. ignore.
return true;
}
s._html5_canplay = true;
sm2._wD(s.id + ': canplay');
s._onbufferchange(0);
// position according to instance options
position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/1000:null);
// set the position if position was set before the sound loaded
if (s.position && this.currentTime !== position1K) {
sm2._wD(s.id + ': canplay: Setting position to ' + position1K);
try {
this.currentTime = position1K;
} catch(ee) {
sm2._wD(s.id + ': canplay: Setting position of ' + position1K + ' failed: ' + ee.message, 2);
}
}
// hack for HTML5 from/to case
if (s._iO._oncanplay) {
s._iO._oncanplay();
}
}),
canplaythrough: html5_event(function() {
var s = this._s;
if (!s.loaded) {
s._onbufferchange(0);
s._whileloading(s.bytesLoaded, s.bytesTotal, s._get_html5_duration());
s._onload(true);
}
}),
// TODO: Reserved for potential use
/*
emptied: html5_event(function() {
sm2._wD(this._s.id + ': emptied');
}),
*/
ended: html5_event(function() {
var s = this._s;
sm2._wD(s.id + ': ended');
s._onfinish();
}),
error: html5_event(function() {
sm2._wD(this._s.id + ': HTML5 error, code ' + this.error.code);
// call load with error state?
this._s._onload(false);
}),
loadeddata: html5_event(function() {
var s = this._s;
sm2._wD(s.id + ': loadeddata');
// safari seems to nicely report progress events, eventually totalling 100%
if (!s._loaded && !isSafari) {
s.duration = s._get_html5_duration();
}
}),
loadedmetadata: html5_event(function() {
sm2._wD(this._s.id + ': loadedmetadata');
}),
loadstart: html5_event(function() {
sm2._wD(this._s.id + ': loadstart');
// assume buffering at first
this._s._onbufferchange(1);
}),
play: html5_event(function() {
sm2._wD(this._s.id + ': play()');
// once play starts, no buffering
this._s._onbufferchange(0);
}),
playing: html5_event(function() {
sm2._wD(this._s.id + ': playing');
// once play starts, no buffering
this._s._onbufferchange(0);
}),
progress: html5_event(function(e) {
// note: can fire repeatedly after "loaded" event, due to use of HTTP range/partials
var s = this._s,
i, j, str, buffered = 0,
isProgress = (e.type === 'progress'),
ranges = e.target.buffered,
// firefox 3.6 implements e.loaded/total (bytes)
loaded = (e.loaded||0),
total = (e.total||1),
// HTML5 returns msec. SM2 API uses seconds for setPosition() etc., whether Flash or HTML5.
scale = 1000;
// reset the "buffered" (loaded byte ranges) array
s.buffered = [];
if (ranges && ranges.length) {
// if loaded is 0, try TimeRanges implementation as % of load
// https://developer.mozilla.org/en/DOM/TimeRanges
// re-build "buffered" array
for (i=0, j=ranges.length; i<j; i++) {
s.buffered.push({
'start': ranges.start(i) * scale,
'end': ranges.end(i) * scale
});
}
// use the last value locally
buffered = (ranges.end(0) - ranges.start(0)) * scale;
// linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges
loaded = buffered/(e.target.duration*scale);
// <d>
if (isProgress && ranges.length > 1) {
str = [];
j = ranges.length;
for (i=0; i<j; i++) {
str.push(e.target.buffered.start(i)*scale +'-'+ e.target.buffered.end(i)*scale);
}
sm2._wD(this._s.id + ': progress, timeRanges: ' + str.join(', '));
}
if (isProgress && !isNaN(loaded)) {
sm2._wD(this._s.id + ': progress, ' + Math.floor(loaded*100) + '% loaded');
}
// </d>
}
if (!isNaN(loaded)) {
// if progress, likely not buffering
s._onbufferchange(0);
// TODO: prevent calls with duplicate values.
s._whileloading(loaded, total, s._get_html5_duration());
if (loaded && total && loaded === total) {
// in case "onload" doesn't fire (eg. gecko 1.9.2)
html5_events.canplaythrough.call(this, e);
}
}
}),
ratechange: html5_event(function() {
sm2._wD(this._s.id + ': ratechange');
}),
suspend: html5_event(function(e) {
// download paused/stopped, may have finished (eg. onload)
var s = this._s;
sm2._wD(this._s.id + ': suspend');
html5_events.progress.call(this, e);
s._onsuspend();
}),
stalled: html5_event(function() {
sm2._wD(this._s.id + ': stalled');
}),
timeupdate: html5_event(function() {
this._s._onTimer();
}),
waiting: html5_event(function() {
var s = this._s;
// see also: seeking
sm2._wD(this._s.id + ': waiting');
// playback faster than download rate, etc.
s._onbufferchange(1);
})
};
html5OK = function(iO) {
// playability test based on URL or MIME type
var result;
if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) {
// RTMP, or preferring flash
result = false;
} else {
// Use type, if specified. If HTML5-only mode, no other options, so just give 'er
result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only));
}
return result;
};
html5Unload = function(oAudio, url) {
/**
* Internal method: Unload media, and cancel any current/pending network requests.
* Firefox can load an empty URL, which allegedly destroys the decoder and stops the download.
* https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media
* However, Firefox has been seen loading a relative URL from '' and thus requesting the hosting page on unload.
* Other UA behaviour is unclear, so everyone else gets an about:blank-style URL.
*/
if (oAudio) {
// Firefox likes '' for unload (used to work?) - however, may request hosting page URL (bad.) Most other UAs dislike '' and fail to unload.
oAudio.src = url;
// reset some state, too
oAudio._called_load = false;
}
if (useGlobalHTML5Audio) {
// ensure URL state is trashed, also
lastGlobalHTML5URL = null;
}
};
html5CanPlay = function(o) {
/**
* Try to find MIME, test and return truthiness
* o = {
* url: '/path/to/an.mp3',
* type: 'audio/mp3'
* }
*/
if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
return false;
}
var url = (o.url || null),
mime = (o.type || null),
aF = sm2.audioFormats,
result,
offset,
fileExt,
item;
// account for known cases like audio/mp3
if (mime && sm2.html5[mime] !== _undefined) {
return (sm2.html5[mime] && !preferFlashCheck(mime));
}
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');
}
// TODO: Strip URL queries, etc.
fileExt = (url ? url.toLowerCase().match(html5Ext) : null);
if (!fileExt || !fileExt.length) {
if (!mime) {
result = false;
} else {
// audio/mp3 -> mp3, result should be known
offset = mime.indexOf(';');
// strip "audio/X; codecs..."
fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);
}
} else {
// match the raw extension name - "mp3", for example
fileExt = fileExt[1];
}
if (fileExt && sm2.html5[fileExt] !== _undefined) {
// result known
result = (sm2.html5[fileExt] && !preferFlashCheck(fileExt));
} else {
mime = 'audio/'+fileExt;
result = sm2.html5.canPlayType({type:mime});
sm2.html5[fileExt] = result;
// sm2._wD('canPlayType, found result: ' + result);
result = (result && sm2.html5[mime] && !preferFlashCheck(mime));
}
return result;
};
testHTML5 = function() {
/**
* Internal: Iterates over audioFormats, determining support eg. audio/mp3, audio/mpeg and so on
* assigns results to html5[] and flash[].
*/
if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
return false;
}
// double-whammy: Opera 9.64 throws WRONG_ARGUMENTS_ERR if no parameter passed to Audio(), and Webkit + iOS happily tries to load "null" as a URL. :/
var a = (Audio !== _undefined ? (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null),
item, lookup, support = {}, aF, i;
function cp(m) {
var canPlay, i, j,
result = false,
isOK = false;
if (!a || typeof a.canPlayType !== 'function') {
return result;
}
if (m instanceof Array) {
// iterate through all mime types, return any successes
for (i=0, j=m.length; i<j; i++) {
if (sm2.html5[m[i]] || a.canPlayType(m[i]).match(sm2.html5Test)) {
isOK = true;
sm2.html5[m[i]] = true;
// note flash support, too
sm2.flash[m[i]] = !!(m[i].match(flashMIME));
}
}
result = isOK;
} else {
canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);
result = !!(canPlay && (canPlay.match(sm2.html5Test)));
}
return result;
}
// test all registered formats + codecs
aF = sm2.audioFormats;
for (item in aF) {
if (aF.hasOwnProperty(item)) {
lookup = 'audio/' + item;
support[item] = cp(aF[item].type);
// write back generic type too, eg. audio/mp3
support[lookup] = support[item];
// assign flash
if (item.match(flashMIME)) {
sm2.flash[item] = true;
sm2.flash[lookup] = true;
} else {
sm2.flash[item] = false;
sm2.flash[lookup] = false;
}
// assign result to related formats, too
if (aF[item] && aF[item].related) {
for (i=aF[item].related.length-1; i >= 0; i--) {
// eg. audio/m4a
support['audio/'+aF[item].related[i]] = support[item];
sm2.html5[aF[item].related[i]] = support[item];
sm2.flash[aF[item].related[i]] = support[item];
}
}
}
}
support.canPlayType = (a?cp:null);
sm2.html5 = mixin(sm2.html5, support);
return true;
};
strings = {
// <d>
notReady: 'Unavailable - wait until onready() has fired.',
notOK: 'Audio support is not available.',
domError: sm + 'exception caught while appending SWF to DOM.',
spcWmode: 'Removing wmode, preventing known SWF loading issue(s)',
swf404: smc + '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: smc + '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: smc + 'Special case: Waiting for SWF to load with window focus...',
waitForever: smc + 'Waiting indefinitely for Flash (will recover if unblocked)...',
waitSWF: smc + 'Waiting for 100% SWF load...',
needFunction: smc + 'Function object expected for %s',
badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',
currentObj: smc + '_debug(): Current sound objects',
waitOnload: smc + 'Waiting for window.onload()',
docLoaded: smc + 'Document already loaded',
onload: smc + 'initComplete(): calling soundManager.onload()',
onloadOK: sm + '.onload() complete',
didInit: smc + 'init(): Already called?',
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: smc + 'Failed to remove Flash node.',
shutdown: sm + '.disable(): Shutting down',
queue: smc + 'Queueing %s handler',
smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',
fbTimeout: 'No flash response, applying .'+swfCSS.swfTimedout+' CSS...',
fbLoaded: 'Flash loaded',
flRemoved: smc + 'Flash movie removed.',
fbHandler: smc + 'flashBlockHandler()',
manURL: 'SMSound.load(): Using manually-assigned URL',
onURL: sm + '.load(): current URL already assigned.',
badFV: sm + '.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',
needFlash: smc + 'Fatal error: Flash is needed to play some required formats, but is not available.',
gotFocus: smc + 'Got window focus.',
policy: 'Enabling usePolicyFile for data access',
setup: sm + '.setup(): allowed parameters: %s',
setupError: sm + '.setup(): "%s" cannot be assigned with this method.',
setupUndef: sm + '.setup(): Could not find option "%s"',
setupLate: sm + '.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().',
noURL: smc + 'Flash URL required. Call soundManager.setup({url:...}) to get started.',
sm2Loaded: 'SoundManager 2: Ready.',
reset: sm + '.reset(): Removing event callbacks',
mobileUA: 'Mobile UA detected, preferring HTML5 by default.',
globalHTML5: 'Using singleton HTML5 Audio() pattern for this device.'
// </d>
};
str = function() {
// internal string replace helper.
// arguments: o [,items to replace]
// <d>
// real array, please
var args = slice.call(arguments),
// first arg
o = args.shift(),
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)) {
sm2._wD((sPre || '') + str('policy'));
sOpt.usePolicyFile = true;
}
return sOpt;
};
complain = function(sMsg) {
// <d>
if (console !== _undefined && console.warn !== _undefined) {
console.warn(sMsg);
} else {
sm2._wD(sMsg);
}
// </d>
};
doNothing = function() {
return false;
};
disableObject = function(o) {
var oProp;
for (oProp in o) {
if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {
o[oProp] = doNothing;
}
}
oProp = null;
};
failSafely = function(bNoDisable) {
// general failure exception handler
if (bNoDisable === _undefined) {
bNoDisable = false;
}
if (disabled || bNoDisable) {
sm2.disable(bNoDisable);
}
};
normalizeMovieURL = function(smURL) {
var urlParams = null, url;
if (smURL) {
if (smURL.match(/\.swf(\?.*)?$/i)) {
urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4);
if (urlParams) {
// assume user knows what they're doing
return smURL;
}
} else if (smURL.lastIndexOf('/') !== smURL.length - 1) {
// append trailing slash, if needed
smURL += '/';
}
}
url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + sm2.movieURL;
if (sm2.noSWFCache) {
url += ('?ts=' + new Date().getTime());
}
return url;
};
setVersionInfo = function() {
// short-hand for internal use
fV = parseInt(sm2.flashVersion, 10);
if (fV !== 8 && fV !== 9) {
sm2._wD(str('badFV', fV, defaultFlashVersion));
sm2.flashVersion = fV = defaultFlashVersion;
}
// debug flash movie, if applicable
var isDebug = (sm2.debugMode || sm2.debugFlash?'_debug.swf':'.swf');
if (sm2.useHTML5Audio && !sm2.html5Only && sm2.audioFormats.mp4.required && fV < 9) {
sm2._wD(str('needfl9'));
sm2.flashVersion = fV = 9;
}
sm2.version = sm2.versionNumber + (sm2.html5Only?' (HTML5-only mode)':(fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));
// set up default options
if (fV > 8) {
// +flash 9 base options
sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.flash9Options);
sm2.features.buffering = true;
// +moviestar support
sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.movieStarOptions);
sm2.filePatterns.flash9 = new RegExp('\\.(mp3|' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
sm2.features.movieStar = true;
} else {
sm2.features.movieStar = false;
}
// regExp for flash canPlay(), etc.
sm2.filePattern = sm2.filePatterns[(fV !== 8?'flash9':'flash8')];
// if applicable, use _debug versions of SWFs
sm2.movieURL = (fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);
sm2.features.peakData = sm2.features.waveformData = sm2.features.eqData = (fV > 8);
};
setPolling = function(bPolling, bHighPerformance) {
if (!flash) {
return false;
}
flash._setPolling(bPolling, bHighPerformance);
};
initDebug = function() {
// starts debug mode, creating output <div> for UAs without console object
// allow force of debug mode via URL
if (sm2.debugURLParam.test(wl)) {
sm2.debugMode = true;
}
// <d>
if (id(sm2.debugID)) {
return false;
}
var oD, oDebug, oTarget, oToggle, tmp;
if (sm2.debugMode && !id(sm2.debugID) && (!hasConsole || !sm2.useConsole || !sm2.consoleOnly)) {
oD = doc.createElement('div');
oD.id = sm2.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 = sm2.debugID;
oDebug.style.display = (sm2.debugMode?'block':'none');
if (sm2.debugMode && !id(oD.id)) {
try {
oTarget = getDocument();
oTarget.appendChild(oD);
} catch(e2) {
throw new Error(str('domError')+' \n'+e2.toString());
}
oTarget.appendChild(oDebug);
}
}
oTarget = null;
// </d>
};
idCheck = this.getSoundById;
// <d>
_wDS = function(o, errorLevel) {
return (!o ? '' : sm2._wD(str(o), errorLevel));
};
toggleDebug = function() {
var o = id(sm2.debugID),
oT = id(sm2.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 (window.sm2Debugger !== _undefined) {
try {
sm2Debugger.handleEvent(sEventType, bSuccess, sMessage);
} catch(e) {
// oh well
}
}
return true;
};
// </d>
getSWFCSS = function() {
var css = [];
if (sm2.debugMode) {
css.push(swfCSS.sm2Debug);
}
if (sm2.debugFlash) {
css.push(swfCSS.flashDebug);
}
if (sm2.useHighPerformance) {
css.push(swfCSS.highPerf);
}
return css.join(' ');
};
flashBlockHandler = function() {
// *possible* flash block situation.
var name = str('fbHandler'),
p = sm2.getMoviePercent(),
css = swfCSS,
error = {type:'FLASHBLOCK'};
if (sm2.html5Only) {
return false;
}
if (!sm2.ok()) {
if (needsFlash) {
// make the movie more visible, so user can fix
sm2.oMC.className = getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);
sm2._wD(name + ': ' + str('fbTimeout') + (p ? ' (' + str('fbLoaded') + ')' : ''));
}
sm2.didFlashBlock = true;
// fire onready(), complain lightly
processOnEvents({type:'ontimeout', ignoreInit:true, error:error});
catchError(error);
} else {
// SM2 loaded OK (or recovered)
// <d>
if (sm2.didFlashBlock) {
sm2._wD(name + ': Unblocked');
}
// </d>
if (sm2.oMC) {
sm2.oMC.className = [getSWFCSS(), css.swfDefault, css.swfLoaded + (sm2.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');
}
}
};
addOnEvent = function(sType, oMethod, oScope) {
if (on_queue[sType] === _undefined) {
on_queue[sType] = [];
}
on_queue[sType].push({
'method': oMethod,
'scope': (oScope || null),
'fired': false
});
};
processOnEvents = function(oOptions) {
// if unspecified, assume OK/error
if (!oOptions) {
oOptions = {
type: (sm2.ok() ? 'onready' : 'ontimeout')
};
}
if (!didInit && oOptions && !oOptions.ignoreInit) {
// not ready yet.
return false;
}
if (oOptions.type === 'ontimeout' && (sm2.ok() || (disabled && !oOptions.ignoreInit))) {
// invalid case
return false;
}
var status = {
success: (oOptions && oOptions.ignoreInit?sm2.ok():!disabled)
},
// queue specified by type, or none
srcQueue = (oOptions && oOptions.type?on_queue[oOptions.type]||[]:[]),
queue = [], i, j,
args = [status],
canRetry = (needsFlash && !sm2.ok());
if (oOptions.error) {
args[0].error = oOptions.error;
}
for (i = 0, j = srcQueue.length; i < j; i++) {
if (srcQueue[i].fired !== true) {
queue.push(srcQueue[i]);
}
}
if (queue.length) {
// sm2._wD(sm + ': Firing ' + queue.length + ' ' + oOptions.type + '() 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, args);
} else {
queue[i].method.apply(this, args);
}
if (!canRetry) {
// useFlashBlock and SWF timeout case doesn't count here.
queue[i].fired = true;
}
}
}
return true;
};
initUserOnload = function() {
window.setTimeout(function() {
if (sm2.useFlashBlock) {
flashBlockHandler();
}
processOnEvents();
// call user-defined "onload", scoped to window
if (typeof sm2.onload === 'function') {
_wDS('onload', 1);
sm2.onload.apply(window);
_wDS('onloadOK', 1);
}
if (sm2.waitForWindowLoad) {
event.add(window, 'load', initUserOnload);
}
},1);
};
detectFlash = function() {
// hat tip: Flash Detect library (BSD, (C) 2007) by Carl "DocYes" S. Yestrau - http://featureblend.com/javascript-flash-detection-library.html / http://featureblend.com/license.txt
if (hasFlash !== _undefined) {
// this work has already been done.
return hasFlash;
}
var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = window.ActiveXObject;
if (nP && nP.length) {
type = 'application/x-shockwave-flash';
types = n.mimeTypes;
if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {
hasPlugin = true;
}
} else if (AX !== _undefined && !ua.match(/MSAppHost/i)) {
// Windows 8 Store Apps (MSAppHost) are weird (compatibility?) and won't complain here, but will barf if Flash/ActiveX object is appended to the DOM.
try {
obj = new AX('ShockwaveFlash.ShockwaveFlash');
} catch(e) {
// oh well
}
hasPlugin = (!!obj);
// cleanup, because it is ActiveX after all
obj = null;
}
hasFlash = hasPlugin;
return hasPlugin;
};
featureCheck = function() {
var needsFlash,
item,
result = true,
formats = sm2.audioFormats,
// iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (original iPad) + iOS4 works.
isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i)));
if (isSpecial) {
// has Audio(), but is broken; let it load links directly.
sm2.hasHTML5 = false;
// ignore flash case, however
sm2.html5Only = true;
if (sm2.oMC) {
sm2.oMC.style.display = 'none';
}
result = false;
} else {
if (sm2.useHTML5Audio) {
if (!sm2.html5 || !sm2.html5.canPlayType) {
sm2._wD('SoundManager: No HTML5 Audio() support detected.');
sm2.hasHTML5 = false;
}
// <d>
if (isBadSafari) {
sm2._wD(smc + 'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - ' + (!hasFlash ?' would use flash fallback for MP3/MP4, but none detected.' : 'will use flash fallback for MP3/MP4, if available'), 1);
}
// </d>
}
}
if (sm2.useHTML5Audio && sm2.hasHTML5) {
for (item in formats) {
if (formats.hasOwnProperty(item)) {
if ((formats[item].required && !sm2.html5.canPlayType(formats[item].type)) || (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type]))) {
// flash may be required, or preferred for this format
needsFlash = true;
}
}
}
}
// sanity check...
if (sm2.ignoreFlash) {
needsFlash = false;
}
sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !needsFlash);
return (!sm2.html5Only);
};
parseURL = function(url) {
/**
* Internal: Finds and returns the first playable URL (or failing that, the first URL.)
* @param {string or array} url A single URL string, OR, an array of URL strings or {url:'/path/to/resource', type:'audio/mp3'} objects.
*/
var i, j, urlResult = 0, result;
if (url instanceof Array) {
// find the first good one
for (i=0, j=url.length; i<j; i++) {
if (url[i] instanceof Object) {
// MIME check
if (sm2.canPlayMIME(url[i].type)) {
urlResult = i;
break;
}
} else if (sm2.canPlayURL(url[i])) {
// URL string check
urlResult = i;
break;
}
}
// normalize to string
if (url[urlResult].url) {
url[urlResult] = url[urlResult].url;
}
result = url[urlResult];
} else {
// single URL case
result = url;
}
return result;
};
startTimer = function(oSound) {
/**
* attach a timer to this sound, and start an interval if needed
*/
if (!oSound._hasTimer) {
oSound._hasTimer = true;
if (!mobileHTML5 && sm2.html5PollingInterval) {
if (h5IntervalTimer === null && h5TimerCount === 0) {
h5IntervalTimer = window.setInterval(timerExecute, sm2.html5PollingInterval);
}
h5TimerCount++;
}
}
};
stopTimer = function(oSound) {
/**
* detach a timer
*/
if (oSound._hasTimer) {
oSound._hasTimer = false;
if (!mobileHTML5 && sm2.html5PollingInterval) {
// interval will stop itself at next execution.
h5TimerCount--;
}
}
};
timerExecute = function() {
/**
* manual polling for HTML5 progress events, ie., whileplaying() (can achieve greater precision than conservative default HTML5 interval)
*/
var i;
if (h5IntervalTimer !== null && !h5TimerCount) {
// no active timers, stop polling interval.
window.clearInterval(h5IntervalTimer);
h5IntervalTimer = null;
return false;
}
// check all HTML5 sounds with timers
for (i = sm2.soundIDs.length-1; i >= 0; i--) {
if (sm2.sounds[sm2.soundIDs[i]].isHTML5 && sm2.sounds[sm2.soundIDs[i]]._hasTimer) {
sm2.sounds[sm2.soundIDs[i]]._onTimer();
}
}
};
catchError = function(options) {
options = (options !== _undefined ? options : {});
if (typeof sm2.onerror === 'function') {
sm2.onerror.apply(window, [{type:(options.type !== _undefined ? options.type : null)}]);
}
if (options.fatal !== _undefined && options.fatal) {
sm2.disable();
}
};
badSafariFix = function() {
// special case: "bad" Safari (OS X 10.3 - 10.7) must fall back to flash for MP3/MP4
if (!isBadSafari || !detectFlash()) {
// doesn't apply
return false;
}
var aF = sm2.audioFormats, i, item;
for (item in aF) {
if (aF.hasOwnProperty(item)) {
if (item === 'mp3' || item === 'mp4') {
sm2._wD(sm + ': Using flash fallback for ' + item + ' format');
sm2.html5[item] = false;
// assign result to related formats, too
if (aF[item] && aF[item].related) {
for (i = aF[item].related.length-1; i >= 0; i--) {
sm2.html5[aF[item].related[i]] = false;
}
}
}
}
}
};
/**
* Pseudo-private flash/ExternalInterface methods
* ----------------------------------------------
*/
this._setSandboxType = function(sandboxType) {
// <d>
var sb = sm2.sandbox;
sb.type = sandboxType;
sb.description = sb.types[(sb.types[sandboxType] !== _undefined?sandboxType:'unknown')];
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, swfVersion) {
// flash callback confirming flash loaded, EI working etc.
// flashDate = approx. timing/delay info for JS/flash bridge
// swfVersion: SWF build string
if (sm2.swfLoaded) {
return false;
}
var e;
debugTS('swf', true);
debugTS('flashtojs', true);
sm2.swfLoaded = true;
tryInitOnFocus = false;
if (isBadSafari) {
badSafariFix();
}
// complain if JS + SWF build/version strings don't match, excluding +DEV builds
// <d>
if (!swfVersion || swfVersion.replace(/\+dev/i,'') !== sm2.versionNumber.replace(/\+dev/i, '')) {
e = sm + ': Fatal: JavaScript file build "' + sm2.versionNumber + '" does not match Flash SWF build "' + swfVersion + '" at ' + sm2.url + '. Ensure both are up-to-date.';
// escape flash -> JS stack so this error fires in window.
setTimeout(function versionMismatch() {
throw new Error(e);
}, 0);
// exit, init will fail with timeout
return false;
}
// </d>
// slight delay before init
setTimeout(init, isIE ? 100 : 1);
};
/**
* Private initialization helpers
* ------------------------------
*/
createMovie = function(smID, smURL) {
if (didAppend && appendSuccess) {
// ignore if already succeeded
return false;
}
function initMsg() {
// <d>
var options = [], title, str = [], delimiter = ' + ';
title = 'SoundManager ' + sm2.version + (!sm2.html5Only && sm2.useHTML5Audio ? (sm2.hasHTML5 ? ' + HTML5 audio' : ', no HTML5 audio support') : '');
if (!sm2.html5Only) {
if (sm2.preferFlash) {
options.push('preferFlash');
}
if (sm2.useHighPerformance) {
options.push('useHighPerformance');
}
if (sm2.flashPollingInterval) {
options.push('flashPollingInterval (' + sm2.flashPollingInterval + 'ms)');
}
if (sm2.html5PollingInterval) {
options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)');
}
if (sm2.wmode) {
options.push('wmode (' + sm2.wmode + ')');
}
if (sm2.debugFlash) {
options.push('debugFlash');
}
if (sm2.useFlashBlock) {
options.push('flashBlock');
}
} else {
if (sm2.html5PollingInterval) {
options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)');
}
}
if (options.length) {
str = str.concat([options.join(delimiter)]);
}
sm2._wD(title + (str.length ? delimiter + str.join(', ') : ''), 1);
showSupport();
// </d>
}
if (sm2.html5Only) {
// 100% HTML5 mode
setVersionInfo();
initMsg();
sm2.oMC = id(sm2.movieID);
init();
// prevent multiple init attempts
didAppend = true;
appendSuccess = true;
return false;
}
// flash path
var remoteURL = (smURL || sm2.url),
localURL = (sm2.altURL || remoteURL),
swfTitle = 'JS/Flash audio component (SoundManager 2)',
oTarget = getDocument(),
extraClass = getSWFCSS(),
isRTL = null,
html = doc.getElementsByTagName('html')[0],
oEmbed, oMovie, tmp, movieHTML, oEl, s, x, sClass;
isRTL = (html && html.dir && html.dir.match(/rtl/i));
smID = (smID === _undefined?sm2.id:smID);
function param(name, value) {
return '<param name="'+name+'" value="'+value+'" />';
}
// safety check for legacy (change to Flash 9 URL)
setVersionInfo();
sm2.url = normalizeMovieURL(overHTTP?remoteURL:localURL);
smURL = sm2.url;
sm2.wmode = (!sm2.wmode && sm2.useHighPerformance ? 'transparent' : sm2.wmode);
if (sm2.wmode !== null && (ua.match(/msie 8/i) || (!isIE && !sm2.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {
/**
* 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
* wmode breaks IE 8 on Vista + Win7 too in some cases, as of January 2011 (?)
*/
messages.push(strings.spcWmode);
sm2.wmode = null;
}
oEmbed = {
'name': smID,
'id': smID,
'src': smURL,
'quality': 'high',
'allowScriptAccess': sm2.allowScriptAccess,
'bgcolor': sm2.bgColor,
'pluginspage': http+'www.macromedia.com/go/getflashplayer',
'title': swfTitle,
'type': 'application/x-shockwave-flash',
'wmode': sm2.wmode,
// http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html
'hasPriority': 'true'
};
if (sm2.debugFlash) {
oEmbed.FlashVars = 'debug=1';
}
if (!sm2.wmode) {
// don't write empty attribute
delete oEmbed.wmode;
}
if (isIE) {
// IE is "special".
oMovie = doc.createElement('div');
movieHTML = [
'<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">',
param('movie', smURL),
param('AllowScriptAccess', sm2.allowScriptAccess),
param('quality', oEmbed.quality),
(sm2.wmode? param('wmode', sm2.wmode): ''),
param('bgcolor', sm2.bgColor),
param('hasPriority', 'true'),
(sm2.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),
'</object>'
].join('');
} 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) {
sm2.oMC = (id(sm2.movieID) || doc.createElement('div'));
if (!sm2.oMC.id) {
sm2.oMC.id = sm2.movieID;
sm2.oMC.className = swfCSS.swfDefault + ' ' + extraClass;
s = null;
oEl = null;
if (!sm2.useFlashBlock) {
if (sm2.useHighPerformance) {
// on-screen at all times
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 {
// hide off-screen, lower priority
s = {
'position': 'absolute',
'width': '6px',
'height': '6px',
'top': '-9999px',
'left': '-9999px'
};
if (isRTL) {
s.left = Math.abs(parseInt(s.left,10))+'px';
}
}
}
if (isWebkit) {
// soundcloud-reported render/crash fix, safari 5
sm2.oMC.style.zIndex = 10000;
}
if (!sm2.debugFlash) {
for (x in s) {
if (s.hasOwnProperty(x)) {
sm2.oMC.style[x] = s[x];
}
}
}
try {
if (!isIE) {
sm2.oMC.appendChild(oMovie);
}
oTarget.appendChild(sm2.oMC);
if (isIE) {
oEl = sm2.oMC.appendChild(doc.createElement('div'));
oEl.className = swfCSS.swfBox;
oEl.innerHTML = movieHTML;
}
appendSuccess = true;
} catch(e) {
throw new Error(str('domError')+' \n'+e.toString());
}
} else {
// SM2 container is already in the document (eg. flashblock use case)
sClass = sm2.oMC.className;
sm2.oMC.className = (sClass?sClass+' ':swfCSS.swfDefault) + (extraClass?' '+extraClass:'');
sm2.oMC.appendChild(oMovie);
if (isIE) {
oEl = sm2.oMC.appendChild(doc.createElement('div'));
oEl.className = swfCSS.swfBox;
oEl.innerHTML = movieHTML;
}
appendSuccess = true;
}
}
didAppend = true;
initMsg();
// sm2._wD(sm + ': Trying to load ' + smURL + (!overHTTP && sm2.altURL ? ' (alternate URL)' : ''), 1);
return true;
};
initMovie = function() {
if (sm2.html5Only) {
createMovie();
return false;
}
// attempt to get, or create, movie (may already exist)
if (flash) {
return false;
}
if (!sm2.url) {
/**
* Something isn't right - we've reached init, but the soundManager url property has not been set.
* User has not called setup({url: ...}), or has not set soundManager.url (legacy use case) directly before init time.
* Notify and exit. If user calls setup() with a url: property, init will be restarted as in the deferred loading case.
*/
_wDS('noURL');
return false;
}
// inline markup case
flash = sm2.getMovie(sm2.id);
if (!flash) {
if (!oRemoved) {
// try to create
createMovie(sm2.id, sm2.url);
} else {
// try to re-append removed movie after reboot()
if (!isIE) {
sm2.oMC.appendChild(oRemoved);
} else {
sm2.oMC.innerHTML = oRemovedHTML;
}
oRemoved = null;
didAppend = true;
}
flash = sm2.getMovie(sm2.id);
}
if (typeof sm2.oninitmovie === 'function') {
setTimeout(sm2.oninitmovie, 1);
}
// <d>
flushMessages();
// </d>
return true;
};
delayWaitForEI = function() {
setTimeout(waitForEI, 1000);
};
waitForEI = function() {
var p,
loadIncomplete = false;
if (!sm2.url) {
// No SWF url to load (noURL case) - exit for now. Will be retried when url is set.
return false;
}
if (waitingForEI) {
return false;
}
waitingForEI = true;
event.remove(window, 'load', delayWaitForEI);
if (tryInitOnFocus && !isFocused) {
// Safari won't load flash in background tabs, only when focused.
_wDS('waitFocus');
return false;
}
if (!didInit) {
p = sm2.getMoviePercent();
if (p > 0 && p < 100) {
loadIncomplete = true;
}
}
setTimeout(function() {
p = sm2.getMoviePercent();
if (loadIncomplete) {
// special case: if movie *partially* loaded, retry until it's 100% before assuming failure.
waitingForEI = false;
sm2._wD(str('waitSWF'));
window.setTimeout(delayWaitForEI, 1);
return false;
}
// <d>
if (!didInit) {
sm2._wD(sm + ': No Flash response within expected time. Likely causes: ' + (p === 0 ? 'SWF load failed, ':'') + 'Flash blocked or JS-Flash security error.' + (sm2.debugFlash?' ' + str('checkSWF'):''), 2);
if (!overHTTP && p) {
_wDS('localFail', 2);
if (!sm2.debugFlash) {
_wDS('tryDebug', 2);
}
}
if (p === 0) {
// if 0 (not null), probably a 404.
sm2._wD(str('swf404', sm2.url), 1);
}
debugTS('flashtojs', false, ': Timed out' + overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');
}
// </d>
// give up / time-out, depending
if (!didInit && okToDisable) {
if (p === null) {
// SWF failed. Maybe blocked.
if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) {
if (sm2.useFlashBlock) {
flashBlockHandler();
}
_wDS('waitForever');
} else {
// no custom flash block handling, but SWF has timed out. Will recover if user unblocks / allows SWF load.
_wDS('waitForever');
// fire any regular registered ontimeout() listeners.
processOnEvents({type:'ontimeout', ignoreInit: true});
}
} else {
// flash loaded? Shouldn't be a blocking issue, then.
if (sm2.flashLoadTimeout === 0) {
_wDS('waitForever');
} else {
failSafely(true);
}
}
}
}, sm2.flashLoadTimeout);
};
handleFocus = function() {
function cleanup() {
event.remove(window, 'focus', handleFocus);
}
if (isFocused || !tryInitOnFocus) {
// already focused, or not special Safari background tab case
cleanup();
return true;
}
okToDisable = true;
isFocused = true;
_wDS('gotFocus');
// allow init to restart
waitingForEI = false;
// kick off ExternalInterface timeout, now that the SWF has started
delayWaitForEI();
cleanup();
return true;
};
flushMessages = function() {
// <d>
// SM2 pre-init debug messages
if (messages.length) {
sm2._wD('SoundManager 2: ' + messages.join(' '), 1);
messages = [];
}
// </d>
};
showSupport = function() {
// <d>
flushMessages();
var item, tests = [];
if (sm2.useHTML5Audio && sm2.hasHTML5) {
for (item in sm2.audioFormats) {
if (sm2.audioFormats.hasOwnProperty(item)) {
tests.push(item + ' = ' + sm2.html5[item] + (!sm2.html5[item] && hasFlash && sm2.flash[item] ? ' (using flash)' : (sm2.preferFlash && sm2.flash[item] && hasFlash ? ' (preferring flash)': (!sm2.html5[item] ? ' (' + (sm2.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));
}
}
sm2._wD('SoundManager 2 HTML5 support: ' + tests.join(', '), 1);
}
// </d>
};
initComplete = function(bNoDisable) {
if (didInit) {
return false;
}
if (sm2.html5Only) {
// all good.
_wDS('sm2Loaded');
didInit = true;
initUserOnload();
debugTS('onload', true);
return true;
}
var wasTimeout = (sm2.useFlashBlock && sm2.flashLoadTimeout && !sm2.getMoviePercent()),
result = true,
error;
if (!wasTimeout) {
didInit = true;
if (disabled) {
error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
}
}
sm2._wD('SoundManager 2 ' + (disabled ? 'failed to load' : 'loaded') + ' (' + (disabled ? 'Flash security/load error' : 'OK') + ')', disabled ? 2: 1);
if (disabled || bNoDisable) {
if (sm2.useFlashBlock && sm2.oMC) {
sm2.oMC.className = getSWFCSS() + ' ' + (sm2.getMoviePercent() === null?swfCSS.swfTimedout:swfCSS.swfError);
}
processOnEvents({type:'ontimeout', error:error, ignoreInit: true});
debugTS('onload', false);
catchError(error);
result = false;
} else {
debugTS('onload', true);
}
if (!disabled) {
if (sm2.waitForWindowLoad && !windowLoaded) {
_wDS('waitOnload');
event.add(window, 'load', initUserOnload);
} else {
// <d>
if (sm2.waitForWindowLoad && windowLoaded) {
_wDS('docLoaded');
}
// </d>
initUserOnload();
}
}
return result;
};
/**
* apply top-level setupOptions object as local properties, eg., this.setupOptions.flashVersion -> this.flashVersion (soundManager.flashVersion)
* this maintains backward compatibility, and allows properties to be defined separately for use by soundManager.setup().
*/
setProperties = function() {
var i,
o = sm2.setupOptions;
for (i in o) {
if (o.hasOwnProperty(i)) {
// assign local property if not already defined
if (sm2[i] === _undefined) {
sm2[i] = o[i];
} else if (sm2[i] !== o[i]) {
// legacy support: write manually-assigned property (eg., soundManager.url) back to setupOptions to keep things in sync
sm2.setupOptions[i] = sm2[i];
}
}
}
};
init = function() {
// called after onload()
if (didInit) {
_wDS('didInit');
return false;
}
function cleanup() {
event.remove(window, 'load', sm2.beginDelayedInit);
}
if (sm2.html5Only) {
if (!didInit) {
// we don't need no steenking flash!
cleanup();
sm2.enabled = true;
initComplete();
}
return true;
}
// flash path
initMovie();
try {
// attempt to talk to Flash
flash._externalInterfaceTest(false);
// apply user-specified polling interval, OR, if "high performance" set, faster vs. default polling
// (determines frequency of whileloading/whileplaying callbacks, effectively driving UI framerates)
setPolling(true, (sm2.flashPollingInterval || (sm2.useHighPerformance ? 10 : 50)));
if (!sm2.debugMode) {
// stop the SWF from making debug output calls to JS
flash._disableDebug();
}
sm2.enabled = true;
debugTS('jstoflash', true);
if (!sm2.html5Only) {
// prevent browser from showing cached page state (or rather, restoring "suspended" page state) via back button, because flash may be dead
// http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
event.add(window, 'unload', doNothing);
}
} catch(e) {
sm2._wD('js/flash exception: ' + e.toString());
debugTS('jstoflash', false);
catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});
// don't disable, for reboot()
failSafely(true);
initComplete();
return false;
}
initComplete();
// disconnect events
cleanup();
return true;
};
domContentLoaded = function() {
if (didDCLoaded) {
return false;
}
didDCLoaded = true;
// assign top-level soundManager properties eg. soundManager.url
setProperties();
initDebug();
/**
* Temporary feature: allow force of HTML5 via URL params: sm2-usehtml5audio=0 or 1
* Ditto for sm2-preferFlash, too.
*/
// <d>
(function(){
var a = 'sm2-usehtml5audio=',
a2 = 'sm2-preferflash=',
b = null,
b2 = null,
hasCon = (window.console !== _undefined && typeof console.log === 'function'),
l = wl.toLowerCase();
if (l.indexOf(a) !== -1) {
b = (l.charAt(l.indexOf(a)+a.length) === '1');
if (hasCon) {
console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter');
}
sm2.setup({
'useHTML5Audio': b
});
}
if (l.indexOf(a2) !== -1) {
b2 = (l.charAt(l.indexOf(a2)+a2.length) === '1');
if (hasCon) {
console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter');
}
sm2.setup({
'preferFlash': b2
});
}
}());
// </d>
if (!hasFlash && sm2.hasHTML5) {
sm2._wD('SoundManager: No Flash detected' + (!sm2.useHTML5Audio ? ', enabling HTML5.' : '. Trying HTML5-only mode.'), 1);
sm2.setup({
'useHTML5Audio': true,
// make sure we aren't preferring flash, either
// TODO: preferFlash should not matter if flash is not installed. Currently, stuff breaks without the below tweak.
'preferFlash': false
});
}
testHTML5();
sm2.html5.usingFlash = featureCheck();
needsFlash = sm2.html5.usingFlash;
if (!hasFlash && needsFlash) {
messages.push(strings.needFlash);
// TODO: Fatal here vs. timeout approach, etc.
// hack: fail sooner.
sm2.setup({
'flashLoadTimeout': 1
});
}
if (doc.removeEventListener) {
doc.removeEventListener('DOMContentLoaded', domContentLoaded, false);
}
initMovie();
return true;
};
domContentLoadedIE = function() {
if (doc.readyState === 'complete') {
domContentLoaded();
doc.detachEvent('onreadystatechange', domContentLoadedIE);
}
return true;
};
winOnLoad = function() {
// catch edge case of initComplete() firing after window.load()
windowLoaded = true;
event.remove(window, 'load', winOnLoad);
};
/**
* miscellaneous run-time, pre-init stuff
*/
preInit = function() {
if (mobileHTML5) {
// prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point.
// <d>
if (!sm2.setupOptions.useHTML5Audio || sm2.setupOptions.preferFlash) {
// notify that defaults are being changed.
messages.push(strings.mobileUA);
}
// </d>
sm2.setupOptions.useHTML5Audio = true;
sm2.setupOptions.preferFlash = false;
if (is_iDevice || (isAndroid && !ua.match(/android\s2\.3/i))) {
// iOS and Android devices tend to work better with a single audio instance, specifically for chained playback of sounds in sequence.
// common use case: exiting sound onfinish() -> createSound() -> play()
// <d>
messages.push(strings.globalHTML5);
// </d>
if (is_iDevice) {
sm2.ignoreFlash = true;
}
useGlobalHTML5Audio = true;
}
}
};
preInit();
// sniff up-front
detectFlash();
// focus and window load, init (primarily flash-driven)
event.add(window, 'focus', handleFocus);
event.add(window, 'load', delayWaitForEI);
event.add(window, 'load', winOnLoad);
if (doc.addEventListener) {
doc.addEventListener('DOMContentLoaded', domContentLoaded, false);
} else if (doc.attachEvent) {
doc.attachEvent('onreadystatechange', domContentLoadedIE);
} else {
// no add/attachevent support - safe to assume no JS -> Flash either
debugTS('onload', false);
catchError({type:'NO_DOM2_EVENTS', fatal:true});
}
} // SoundManager()
// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading
if (window.SM2_DEFER === undefined || !SM2_DEFER) {
soundManager = new SoundManager();
}
/**
* SoundManager public interfaces
* ------------------------------
*/
window.SoundManager = SoundManager; // constructor
window.soundManager = soundManager; // public API, flash callbacks etc.
}(window));
;
// file: jquery.rotate.js
/*
* JQuery CSS Rotate property using CSS3 Transformations
* Copyright (c) 2011 Jakub Jankiewicz <http://jcubic.pl>
* licensed under the LGPL Version 3 license.
* http://www.gnu.org/licenses/lgpl.html
*/
(function($) {
function getTransformProperty(element) {
var properties = ['transform', 'WebkitTransform',
'MozTransform', 'msTransform',
'OTransform'];
var p;
while (p = properties.shift()) {
if (element.style[p] !== undefined) {
return p;
}
}
return false;
}
$.cssHooks['rotate'] = {
get: function(elem, computed, extra){
var property = getTransformProperty(elem);
if (property) {
return elem.style[property].replace(/.*rotate\((.*)deg\).*/, '$1');
} else {
return '';
}
},
set: function(elem, value){
var property = getTransformProperty(elem);
if (property) {
value = parseInt(value);
$(elem).data('rotatation', value);
if (value == 0) {
elem.style[property] = '';
} else {
elem.style[property] = 'rotate(' + value%360 + 'deg)';
}
} else {
return '';
}
}
};
$.fx.step['rotate'] = function(fx){
$.cssHooks['rotate'].set(fx.elem, fx.now);
};
})(jQuery);
;
// file: jquery.scale.js
/*!
/**
* Monkey patch jQuery 1.3.1+ to add support for setting or animating CSS
* scale and rotation independently.
* https://github.com/zachstronaut/jquery-animate-css-rotate-scale
* Released under dual MIT/GPL license just like jQuery.
* 2009-2012 Zachary Johnson www.zachstronaut.com
*/
(function ($) {
// Updated 2010.11.06
// Updated 2012.10.13 - Firefox 16 transform style returns a matrix rather than a string of transform functions. This broke the features of this jQuery patch in Firefox 16. It should be possible to parse the matrix for both scale and rotate (especially when scale is the same for both the X and Y axis), however the matrix does have disadvantages such as using its own units and also 45deg being indistinguishable from 45+360deg. To get around these issues, this patch tracks internally the scale, rotation, and rotation units for any elements that are .scale()'ed, .rotate()'ed, or animated. The major consequences of this are that 1. the scaled/rotated element will blow away any other transform rules applied to the same element (such as skew or translate), and 2. the scaled/rotated element is unaware of any preset scale or rotation initally set by page CSS rules. You will have to explicitly set the starting scale/rotation value.
function initData($el) {
var _ARS_data = $el.data('_ARS_data');
if (!_ARS_data) {
_ARS_data = {
rotateUnits: 'deg',
scale: 1,
rotate: 0
};
$el.data('_ARS_data', _ARS_data);
}
return _ARS_data;
}
function setTransform($el, data) {
$el.css('transform', 'rotate(' + data.rotate + data.rotateUnits + ') scale(' + data.scale + ',' + data.scale + ')');
}
$.fn.rotate = function (val) {
var $self = $(this), m, data = initData($self);
if (typeof val == 'undefined') {
return data.rotate + data.rotateUnits;
}
m = val.toString().match(/^(-?\d+(\.\d+)?)(.+)?$/);
if (m) {
if (m[3]) {
data.rotateUnits = m[3];
}
data.rotate = m[1];
setTransform($self, data);
}
return this;
};
// Note that scale is unitless.
$.fn.scale = function (val) {
var $self = $(this), data = initData($self);
if (typeof val == 'undefined') {
return data.scale;
}
data.scale = val;
setTransform($self, data);
return this;
};
// fx.cur() must be monkey patched because otherwise it would always
// return 0 for current rotate and scale values
var curProxied = $.fx.prototype.cur;
$.fx.prototype.cur = function () {
if (this.prop == 'rotate') {
return parseFloat($(this.elem).rotate());
} else if (this.prop == 'scale') {
return parseFloat($(this.elem).scale());
}
return curProxied.apply(this, arguments);
};
$.fx.step.rotate = function (fx) {
var data = initData($(fx.elem));
$(fx.elem).rotate(fx.now + data.rotateUnits);
};
$.fx.step.scale = function (fx) {
$(fx.elem).scale(fx.now);
};
/*
Starting on line 3905 of jquery-1.3.2.js we have this code:
// We need to compute starting value
if ( unit != "px" ) {
self.style[ name ] = (end || 1) + unit;
start = ((end || 1) / e.cur(true)) * start;
self.style[ name ] = start + unit;
}
This creates a problem where we cannot give units to our custom animation
because if we do then this code will execute and because self.style[name]
does not exist where name is our custom animation's name then e.cur(true)
will likely return zero and create a divide by zero bug which will set
start to NaN.
The following monkey patch for animate() gets around this by storing the
units used in the rotation definition and then stripping the units off.
*/
var animateProxied = $.fn.animate;
$.fn.animate = function (prop) {
if (typeof prop['rotate'] != 'undefined') {
var $self, data, m = prop['rotate'].toString().match(/^(([+-]=)?(-?\d+(\.\d+)?))(.+)?$/);
if (m && m[5]) {
$self = $(this);
data = initData($self);
data.rotateUnits = m[5];
}
prop['rotate'] = m[1];
}
return animateProxied.apply(this, arguments);
};
})(jQuery);
;
// file: exps.js
//explosions
window.Exps = {};
//creates a new "container" and returns it. attach explosions/etc to these. then when you want to switch "views" (ie change to a different bitcointalk thread view), make a new one and .hide() the old one. that way if you have explosions and crap in the middle of running on one view and then you switch, those explosions disappear, which is desired
Exps.createContainer = function(){
var id = Exps.createContainer.getId();
$expContainer = $('<div>', {id : id, class:'expContainer'}).appendTo($screenContainer);
return $expContainer;
};
Exps.createContainer.getId = (function(){
var id=0;
return function(){return 'expContainer' + (id++);};
})();
Exps.hideAll = function(){
$('.expContainer').hide();
};
/**
* creates an explosion on container at x,y
*
* x,y default to rand()
* expType is the explosion image to use, defaults to 1
*/
Exps.createExplosion = function(container, x, y, expType, scale, shakeLevel){
if(!x && !y) {
var temp = randXY();
x = temp[0];
y = temp[1];
}
if(!expType) {
expType = 1;
}
if(!scale) {
scale = 1;
}
if(!_.isObject(scale)) {
scale = {
x : scale,
y : scale
};
}
var $exp = $('<div>')
.addClass('exp')
.addClass('expType' + expType)
.css({
top : y,
left : x,
transform : 'scale(' + scale.x + ', ' + scale.y + ')'
})
;
container.append($exp);
var callback = function(){
$exp.addClass('exploding');
if(shakeLevel){
Exps.triggerShake(null, shakeLevel, shakeLevel * 2);
}
};
setTimeout(callback, 50);
};
Exps.createExplosionRandom = function(container){
var x = 0;
var y = 0;
var expType = Math.floor(Math.random() * 2) + 1;
var scale = Math.random()*3 + 2;
Exps.createExplosion(container, x, y, expType, scale);
}
Exps.createCircle = function(container) {
var coords = [
[47.471,2.5],
[42.506,3.669],
[37.716,5.979],
[33.229,9.375],
[29.153,13.769],
[25.591,19.056],
[22.631,25.104],
[20.344,31.766],
[18.788,38.876],
[18,46.262],
[18,53.738],
[18.788,61.123],
[20.344,68.232],
[22.631,74.896],
[25.591,80.944],
[29.153,86.23],
[33.229,90.626],
[37.716,94.02],
[42.506,96.33],
[47.481,97.5],
[52.519,97.5],
[57.493,96.33],
[62.283,94.02],
[66.771,90.626],
[70.846,86.23],
[74.408,80.944],
[77.369,74.896],
[79.655,68.232],
[81.212,61.123],
[82,53.738],
[82,46.262],
[81.212,38.876],
[79.655,31.766],
[77.369,25.104],
[74.408,19.056],
[70.846,13.769],
[66.771,9.375],
[62.283,5.979],
[57.493,3.669],
[52.519,2.5]
];
var coords2 =[
[45.583,23.833],
[45.583,26.083],
[45.583,30.083],
[45.583,33.5],
[45.583,37],
[45.583,40],
[45.583,45.083],
[45.583,49.417],
[45.583,53.5],
[45.583,57.084],
[45.583,61.334],
[45.583,65.941],
[45.583,69.5],
[45.583,72.75],
[45.583,76.083],
[52.584,23.833],
[52.584,26.083],
[52.584,30.083],
[52.584,33.5],
[52.584,37],
[52.584,40],
[52.584,45.083],
[52.584,49.417],
[52.584,53.5],
[52.584,57.084],
[52.584,61.334],
[52.584,65.941],
[52.584,69.5],
[52.584,72.75],
[52.584,76.083],
[39.167,33.5],
[42.5,33.482],
[45.583,33.495],
[48.925,33.634],
[52.584,34.093],
[55.863,35.084],
[58.473,37.049],
[59.5,40.167],
[59.182,42.98],
[57.822,45.728],
[54.843,47.954],
[51.113,49.022],
[51.167,49.586],
[55.031,50.074],
[57.844,50.979],
[59.951,52.686],
[60.852,54.641],
[61.167,57.5],
[60.879,60.055],
[59.75,62.457],
[57.582,64.25],
[55.104,65.172],
[52.584,65.628],
[48.921,65.893],
[45.583,65.941],
[42.593,65.929],
[39.75,65.917]
];
var i = 0;
_.each(coords, function(coord){
i++;
(function(){
var callback = function(){
Exps.createExplosion(container, coord[0] * window.width * 0.01, coord[1] * window.height * 0.01, 2, 2);
};
setTimeout(callback, i * 30);
})();
});
_.each(coords2, function(coord){
(function(){
var callback = function(){
Exps.createExplosion(container, coord[0] * window.width * 0.01, coord[1] * window.height * 0.01, 2, 2);
};
setTimeout(callback, i * 30);
})();
});
}
// makes the screen shake aww yeaaah
Exps.triggerShake = function($el, quakedecay, quakeness){
$el = $el || $wrapper;
quakedecay = quakedecay || 32;
quakeness = quakeness || 64;
if($el.css('position') == 'static'){
$el.css('position', 'relative');
}
var intId = setInterval(function(){
if(quakeness > 0){
offsetx = (Math.random() - 0.5) * quakeness;
offsety = (Math.random() - 0.5) * quakeness;
quakeness = quakeness - (60/1000 * quakedecay);
}
else{
offsetx = 0;
offsety = 0;
clearInterval(intId);
}
$el.css({top:offsety, left:offsetx});
}, 1000/60);
};
;
// file: conductor.js
(function(){
//changes the image of the conductor. refer to urls.conductors for the full list
$.fn.setStatus = function(type){
return $(this).attr('src', urls.conductors[type]);
};
//returns the conductor to 0deg rotation
$.fn.resetCss = function(){
return $(this).stop().css({rotate:0});
};
$.fn.rotateTo = function(deg, ms){
//return $(this).css('rotate', deg);
return $(this).animate({rotate: deg}, ms);
};
})();
;
// file: missiles.js
window.Missiles = {};
Missiles.types = []; //set inside spawnAll()
Missiles.els = [];
Missiles.spawnAll = function(){
Missiles.types = [
{url : urls.missiles[0], width:200, height:300},
{url : urls.missiles[0], width:100, height:150},
{url : urls.missiles[0], width:200, height:400}, //last of first section
{url : urls.missiles[0], width:200, height:400} //last
];
var missileOrder = [0, 1, 1, 0, 1, 0, 2, 0, 0, 1, 1, 0, 3];
var curLeft = 0;
_.each(missileOrder, function(typeId){
var missileType = Missiles.types[typeId];
var $missile = Missiles.createMissile(typeId)
.css({
left : curLeft,
})
.appendTo($missileContainer)
;
Missiles.els.push($missile);
curLeft += missileType.width;
});
};
Missiles.createMissile = function(typeId){
var missileType = Missiles.types[typeId];
var $missile = $('<img>', {class:'missile'})
.attr('src', missileType.url)
.css({
width : missileType.width,
height : missileType.height
})
;
return $missile;
};
//launches an el upwards
Missiles.launchUp = function(el, duration, onDone){
onDone = onDone || noop();
el = $(el);
var height = el.height();
var top = el.offset().top;
el.css('top', top); //required bc transitional doctype screws up jquery
var props = {
top : -height - 100
};
var options = {
easing : 'easeInQuad',
duration : duration,
complete : onDone
};
el.animate(props, options);
};
//adds a missile to the containerEl and makes it fall down to position x,y and triggers an explosion of expType and scale
Missiles.fallDown = function(missileTypeId, $container, x, y, expType, scale, duration, shakeLevel){
if($container == 'cur'){
$container = Screens.getCurScreen();
}
if(_.isNumber($container)){
$container = Screens.getElId($container);
}
if(!x && !y) {
var temp = randXY();
x = temp[0];
y = temp[1];
}
var missileType = Missiles.types[missileTypeId];
var $missile = Missiles.createMissile(missileTypeId);
$missile.appendTo($container);
$missile.css({
top: -1 * (missileType.height + 100),
left : x,//(width / 2),
scale : -1
});
$missile.animate({scale:-2}, {duration:0})
var props = {
left : x - (missileType.width/2),
top : y - (missileType.height/2),
scale : -0.25
};
var options = {
duration : duration,
easing : 'easeInQuad'
};
options.complete = function(){
$missile.remove();
Exps.createExplosion($container, x, y, expType, scale, shakeLevel);
};
$missile.animate(props, options);
};
;
// file: drstrangelove.js
window.DrStrangelove = {};
DrStrangelove.drop = function($container) {
//$drStrangelove = $('<div>').addClass('drstrangelove');
$drStrangelove = $('<img>', {src:urls.drStrangelove})
.addClass('drstrangelove')
.css({
width:501,
height:720
})
;
$container.append($drStrangelove);
var callback = function(){
//$drStrangelove.addClass('dropping');
$drStrangelove.animate({
width:1,
height:1,
left:'+=250',
bottom:'+=600'
}, 4000);
};
callback();
/* he takes 5 seconds to drop. can be modified in css */
}
DrStrangelove.hide = function(container) {
$('.drstrangelove', container).hide();
}
;
// file: fbi.js
window.Fbi = {};
Fbi.showGuys = function(container){
var $fbi1 = $('<div>').addClass('fbi1');
var $fbi2 = $('<div>').addClass('fbi2');
$(container).append($fbi1, $fbi2);
$fbi1.animate({left : '200px'}, 2000);
$fbi2.animate({right : '200px'}, 2000);
};
Fbi.hideGuys = function(container){
var $fbi1 = $('.fbi1', container);
var $fbi2 = $('.fbi2', container);
$fbi1.animate({left : '-450px'}, 2000);
$fbi2.animate({right : '-450px'}, 2000);
};
Fbi.showMessage = function(container) {
var message = '<p>Hello friend,</p><p>Bitcoin has been seized by the FBI for being illegal.</p><p>Thanks, bye</p>';
var $fbiMessage = $('<div>')
.addClass('fbiMessage')
.html(message)
.appendTo(container)
;
$fbiMessage.animate({top : '50px'}, 2000);
};
Fbi.hideMessage = function(container) {
$('.fbiMessage', container).animate({top : '-400px'}, 2000);
};
;
// file: run.js
if(!window.console){
window.console = {};
}
if(!window.console.log){
window.console.log = function(){};
}
var noop = function(){
return function(){};
};
//options for enabling/disabling the "video"
var control = {
disable : function(){
document.cookie = 'disableWin=1';
},
enable : function(){
document.cookie = 'disableWin=0';
},
checkEnabled : function(){
return (!document.cookie.match(/disableWin/) || document.cookie.match(/disableWin=0/));
},
showEnableLink : function(){
var $el = $('<a>', {href:'#'})
.text('Click here to win!')
.css({
position:'fixed',
right:0,
top:0,
color:'white',
background:'black',
padding:5
})
.on('click', function(){
control.enable();
initAll();
return false;
})
.appendTo(document.body)
;
}
};
var urls = {
swf : '/useravatars/swf/',
muse : '/useravatars/muse.mp3',
conductors : {
deep : 'http://i.imgur.com/wnCymKE.jpg',
angry : 'http://i.imgur.com/HyaOCqn.jpg',
reg : 'http://i.imgur.com/MYKoUcS.jpg',
},
screenshots : [
'http://i.imgur.com/hAGu8NI.gif',
'http://i.imgur.com/zX83PKq.gif',
'http://i.imgur.com/rfMLpcn.gif',
'http://i.imgur.com/Bv2HB2P.gif',
'http://i.imgur.com/1WTzMdD.gif'
],
missiles : [
'http://i.imgur.com/8D0qDQA.png'
],
explosions : [
'http://i.imgur.com/gWKImus.png',
'http://i.imgur.com/KMTLhUO.png'
],
drStrangelove : [
'http://i.imgur.com/CkO5ODX.gif'
],
fbi : [
'http://i.imgur.com/eweUrLj.png'
],
WCs : {
//slide0 : 'images/wincoins/slide0.png'
},
speech : {
satoshi1 : 'http://i.imgur.com/d8nNMwI.jpg',
satoshi2 : 'http://i.imgur.com/qcJQBJ0.jpg'
}
};
var width = 1371;
var height = 927;
var baseWidth = 1920;
var baseHeight = 1080;
//designed to make it scale to your browser's resolution. this'll be updated when everything else is complete. for now we'll just test on 1920x1080 or whatever the hell your resolution is
function normalizePos(type, baseVal){
switch(type){
case 'width':
return parseInt(baseVal * width / baseWidth, 10);
break;
case 'height':
return parseInt(baseVal * height / baseHeight, 10);
break;
case 'top':
return parseInt(baseVal * height / baseHeight, 10);
break;
case 'left':
return parseInt(baseVal * width / baseWidth, 10);
break;
}
}
//preloads images
function preloadImages(obj){
_.each(obj, function(val, name){
if(_.isObject(val)){
preloadImages(val);
}
else if(val.toString().match(/\.(jpe?g|png|gif)$/i)){
(new Image()).src = val.toString();
}
});
}
preloadImages(urls);
$(window.initAll = function(){
//if disabled, then leaves. :(
if(!control.checkEnabled()){
//but adds the button to show it
control.showEnableLink();
return;
}
//builds the wrappers. dont put any z-indexes on these. just change the ordering they get appended if you want to mess with them
window.$body = $(document.body);
window.$mainWrapper = $('<div>', {id:'mainWrapper'});
window.$wrapper = $('<div>', {id:'wrapper'});
window.$screenContainer = $('<div>', {id:'screenContainer'});
window.$conductor = $('<img>', {id:'conductor'});
window.$missileContainer = $('<div>', {id:'missileContainer'});
window.$topmostView = $('<div>', {id:'topmostView'});
window.$debug1 = $('<div>', {id:'debug1', class:'debug'});
window.$debug2 = $('<div>', {id:'debug2', class:'debug'});
if(!Config.debug){
$debug1.css({display:'none'});
$debug2.css({display:'none'});
}
window.width = $(document).width();
window.height = $(document).height();
console.log(width,height);
//explosion examples. remove later
var $exp = Exps.createContainer();
if(!Config.hideMost){
/*
Exps.createCircle($exp);
Exps.createExplosion($exp, 100, 100, 1, 1);
Exps.createExplosion($exp, 600, 400, 2, {x:10,y:8});
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
Exps.createExplosionRandom($exp);
DrStrangelove.drop($wrapper);
Fbi.showGuys($wrapper);
Fbi.showMessage($wrapper);
*/
}
//builds the sound thinger. runs loadMuse() when everything's ready
soundManager.setup({
url: urls.swf,
flashVersion: 9, // optional: shiny features (default = 8)
useFlashBlock: false, // optionally, enable when you're ready to dive in
/**
* read up on HTML5 audio support, if you're feeling adventurous.
* iPad/iPhone and devices without flash installed will always attempt to use it.
*/
onready: function() {
loadMuse();
}
});
//inserts all the el's
$body.append($mainWrapper);
$mainWrapper.append($wrapper);
$wrapper.append(
$screenContainer,
$conductor,
$missileContainer,
$topmostView
);
$mainWrapper.append(
$debug1,
$debug2
);
//logs the ms time that you do a click. designed to make it so i can play the song and click at each note but i think the event's delayed so it doesnt work very well
var mousedowns = [];
$(document).on('mousedown', function(){
mousedowns.push((muse||{}).position);
console.log('mousedown', mousedowns.join(', '));
});
//click the debug thing at the top left to trigger a jitter and stop the music. remove this later
$debug1.on('mousedown', function(){
Exps.triggerShake();
if(!muse.paused){
muse.pause();
}
else{
muse.play();
}
});
if(Config.hideMost){
$missile1.hide();
$conductor.hide();
}
Missiles.spawnAll();
//WC.start();
});
function rand(min, max){
if(min == max){
return min;
}
return Math.floor(Math.random() * (max - min + 1) + min);
}
function randXY(depth){
depth = parseInt(depth, 10) || 0;
var x = rand(100, width - 100);
var y = rand(100, height - 100);
//avoids overlapping the conductor
if(x < 500 && y > height - 350 && depth < 20){
return randXY(depth + 1);
}
return [x, y];
}
//tries to load the song. runs start() when its loaded
function loadMuse(){
//if disabled, then leaves. :(
if(!control.checkEnabled()){
return;
}
var s=new Date()-0;
console.log(soundManager);
window.muse = soundManager.createSound({
id: 'muse',
url: urls.muse,
autoLoad: true,
autoPlay: false,
onload: function(){
//alert('The sound '+this.id+' loaded!' + (new Date()-s));
start();
},
volume: Config.volume
});
console.log(muse);
}
//
function start(){
//if disabled, then leaves. :(
if(!control.checkEnabled()){
return;
}
console.log('start() beginning');
$conductor.setStatus('reg');
//binds all the times that events should happen
bindPositions();
//turn up the volume turn up the volume turn up the volume dance dance
window.$turnVolumeUp = $('<div>', {id:'volumeUpIndicator'})
.text('Turn your volume up')
.appendTo($wrapper)
;
if(Config.hideMost){
$turnVolumeUp.hide();
}
//listen while i play-play-play-play my green tamborine
muse.play();
//debug
//updates the debug ms timer at the top left every ~100ms. it shows how many seconds in the song it is
setInterval(function(){
$debug1.text(muse.position);
}, 100);
}
//sets ms times that events should be triggered
//the moves array says when the conductor should move. if a number is >1000, then its at that ms time. if its <1000, then its (that ms time * 1000)
function bindPositions(){
if(Config.startAt){
muse.setPosition(Config.startAt);
$conductor.css('left',0);
/*if(Config.startAt >= 11000){
$missileContainer.css('left',200);
}*/
}
// ffmpeg.exe -f lavfi -i amovie=btc.mp3,silencedetect=noise=0.5:duration=0.1 -f null - 2>&1 | grep silence_end | gawk -F" " "{printf(\"%s,\", $5)}"
var moves = [
{t:4.7, r:'A'}, 5.25061, 5.8, 6.34776, 6.92245, 7.88898,
{t:9.11673,r:'B'}, 10.2139, 11.1894, 12.9567, 13.5143,
{t:14.8376, r:'C'},
{t:16.2, r:'D'}, 16.4, 16.6, 16.8, 17.3192, 17.8939,
{t:19.5918, r:'E'}, 20.1404, 20.7673,
{t:21446, r:'F'}, 21700, 21894, 22126, 22312, 22498, 22591, 22823, 23009, 23334, 23613,
{t:24774, r:'G'}, 24866, 25052, 25284, 25377, 25563, 25795, 26074, 26399,
{t:27514, r:'H'}, 27699, 27792, 28024, 28117, 28303, 28535, 28628, 28814, 29046, 29139,
{t:30247, r:'I'}, 30340, 30526, 30665, 30851, 31037, 31176, 31362, 31548, 31640, 31873,
{t:32476, r:'J'}, 33870, 35309, 36424, 36702,
{t:38066, r:'K'}, 39413, 40017, 40760, 42130, 43616,
{t:45139, r:'L'}, 45743, 46439, 47322, 47647, 47832, 48158, 48436, 48761,
{t:49133, r:'M'}, 49318, 49504, 49829, 50061, 50247, 50433, 50665, 50851, 51037, 51269, 51455,
{t:51640, r:'N'}, 52291, 52894, 53498, 54102,
{t:54473, r:'O'}, 54613, 54798, 55123, 55402,
{t:55681, r:'P'}, 55913, 56099, 56331, 56609, 56935, 57213, 57538, 57817, 58049, 58328, 58653, 59024, 59349, 59675, 59953, 60278, 60464, 60743, 61068,
{t:61393, r:'Q'}, 61671, 61857, 61997, 62182, 62368, 62693,
{t:63204, r:'R'}, 63297, 63529, 63622, 63808, 63994, 64412, 64505, 64737, 64922, 65015, 65201, 65805, 66037, 66130, 66362, 66548, 67152, 67848, 68452, 69149, 70588, 72585, 74210, 75697, 77926
];
//adds the debug2 events
var a=false;
var counter = 0;
_.each(moves, function(t, index){
var id = ++counter;
var r;
if(_.isObject(t)){
r = t.r;
t = t.t;
id = counter = 1;
}
if(t < 500){
t = t * 1000;
}
t = parseInt(t, 10);
muse.onPosition(t, function(){
//logs the debug
if(r){
$debug2.append($('<br /><span>' + r + '</span>'));
}
$debug2.append($('<span>').text(id % 10));
});
//moves the conductor
a = !a;
var sinceLast = (index > 0) ? moves[index-1] : 1000;
var newPos = (a ? -30 : 0);
var speed = (sinceLast > 100) ? 50 : 50 ;
var startTime = t - 30;
//adds the move position by triggering 1000ms before and setting a timeout of the difference because onPosition isnt always exact. doing this makes it sync up better
muse.onPosition(startTime - 1000, function(){
setTimeout(function(){
$conductor.stop().rotateTo(newPos, speed);
}, Math.max(1, startTime - muse.position));
});
});
//moves the conductor in from the left at the very beginning
muse.onPosition(0, function(){$conductor.animate({left:0}, 3000);});
//hides the "turn up the volume" msg after 4 seconds
muse.onPosition(4000, function(){$turnVolumeUp.remove()});
//muse.onPosition(22000, function(){$conductor.setStatus('angry');});
//moving missiles in from right
muse.onPosition(11000, function(){$missileContainer.animate({left:'-=800'}, 10000, 'linear');});
//launching missiles upward
var missileLaunchDelay = 100;
muse.onPosition(21000, function(){
$missileContainer
.animate({left:'-=800'}, 3000, 'linear')
.animate({left:'-=500'}, 2000, 'linear')
.animate({left:'-=200'}, 1000, 'linear')
;
});
muse.onPosition(21446 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[0], 500);});
muse.onPosition(21894 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[1], 500);});
muse.onPosition(22312 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[2], 500);});
muse.onPosition(22591 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[3], 500);});
muse.onPosition(23009 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[4], 500);});
muse.onPosition(23334 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[5], 500);});
muse.onPosition(23613 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[6], 500);});
muse.onPosition(24774 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[7], 500);});
muse.onPosition(25052 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[8], 500);});
muse.onPosition(25377 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[9], 500);});
muse.onPosition(25795 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[10], 500);});
muse.onPosition(26074 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[11], 500);});
muse.onPosition(26399 - missileLaunchDelay, function(){Missiles.launchUp(Missiles.els[12], 500);});
//todo: 27-32. missiles flying in random directions across the screen maybe?
//makes the conductor angry
muse.onPosition(32476, function(){$conductor.setStatus('angry');});
//missiles falling
var fallingDuration = 1200;
muse.onPosition(32476 - fallingDuration, function(){Missiles.fallDown(0, 0, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(33870 - fallingDuration, function(){Missiles.fallDown(0, 0, null, null, 1, 4, fallingDuration, 10);});
muse.onPosition(35309 - fallingDuration, function(){Missiles.fallDown(0, 0, null, null, 2, 6, fallingDuration, 10);});
muse.onPosition(36424 - fallingDuration, function(){Missiles.fallDown(0, 0, null, null, 1, 4, fallingDuration, 10);});
muse.onPosition(36702 - fallingDuration, function(){Missiles.fallDown(0, 0, null, null, 2, 3, fallingDuration, 10);});
//changes screens and makes more missiles fall
muse.onPosition(37200, function(){Screens.hideAll();Screens.showScreenId(1);});
muse.onPosition(38066 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(39413 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(40017 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(40760 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(42130 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(43616 - fallingDuration, function(){Missiles.fallDown(0, 1, null, null, 2, 3, fallingDuration, 10);});
//more!
muse.onPosition(45139, function(){Screens.hideAll();Screens.showScreenId(2);});
muse.onPosition(45743 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(46439 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(47322 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(47647 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(47832 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(48158 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(48436 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(48761 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
//more! more!
muse.onPosition(49133 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(49318 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(49504 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(49829 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(50061 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(50247 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(50433 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(50665 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(50851 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(51037 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 1, 3, fallingDuration, 10);});
muse.onPosition(51269 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
muse.onPosition(51455 - fallingDuration, function(){Missiles.fallDown(0, 2, null, null, 2, 3, fallingDuration, 10);});
//rain down the fire!
muse.onPosition(48000, function(){DrStrangelove.drop($wrapper);});
muse.onPosition(51500, function(){Exps.createExplosion($wrapper, 750, 400, 2, {x:10,y:8});DrStrangelove.hide($wrapper);});
var randExplosionTimes = [54613, 54798, 55123, 55402, 55913, 56099, 56331, 56609, 56935, 57213, 57538, 57817, 58049, 58328, 58653, 59024, 59349, 59675, 59953, 60278, 60464, 60743, 61068, 61671, 61857, 61997, 62182, 62368, 62693, 63297, 63529, 63622, 63808, 63994, 64412, 64505, 64737, 64922, 65015, 65201, 65805];
_.each(randExplosionTimes, function(t){
muse.onPosition(t, function(){Exps.createExplosionRandom($wrapper);});
})
muse.onPosition(70000, function(){Exps.createCircle($wrapper);});
muse.onPosition(75000, function(){Fbi.showGuys($wrapper);});
muse.onPosition(77000, function(){Fbi.showMessage($wrapper);});
muse.onPosition(85000, function(){Fbi.hideGuys($wrapper);Fbi.hideMessage($wrapper)});
//handles the very end
muse.onPosition(85000, function(){displayEnding();});
//loads in the first "camera angle"
if(!Config.hideMost){
muse.onPosition(0, function(){
Screens.buildAll();
Screens.hideAll();
Screens.showScreenId(0);
});
}
}
function displayEnding(){
var $endingContainer = $('<div>', {id:'endingContainer'});
var $hackedByMsg = $('<div>', {id:'hackedByMsg'})
.text('Hacked by "The Hole Seekers"')
;
var $playAgainLink = $('<a>', {id:'playAgainLink', href:'#'})
.text('Play Again')
.on('click', playAgain)
;
var $closeLink = $('<a>', {id:'closeLink', href:'#'})
.text('Close')
.on('click', close)
;
var $closeAndDisableLink = $('<a>', {id:'closeAndDisableLink', href:'#'})
.text('Close and never play this monstrosity again')
.on('click', function(){
close();
control.disable();
})
;
var $speechLink = $('<a>', {id:'speechLink', href:'#'})
.text('***A SPECIAL MESSAGE FROM SATOSHI***')
.on('click', function(){
Speech.create($wrapper, $endingContainer);
})
;
var $ytLink = $('<a>', {id:'ytLink', href:'http://www.youtube.com/watch?v=2meowzEwIdw', target:'_blank'})
.css({fontSize:'12px'})
.text('Music taken from the V for Vendetta explosion scene. Click HERE to watch the scene on youtube.')
;
$endingContainer.append(
$hackedByMsg,
$playAgainLink,
$closeLink,
$closeAndDisableLink,
$speechLink,
$ytLink
);
$endingContainer.appendTo($mainWrapper);
//todo: re-enable this later
Song.createSong($endingContainer);
$endingContainer.append($('<div style="clear:both;height:164px;display:block;">'));
function close(){
$mainWrapper.remove();
}
}
function playAgain(){
muse.stop();
muse.destruct();
muse.unload();
soundManager.destroySound('muse');
muse = null;
Screens.els = [];
Missiles.els = [];
$mainWrapper.remove();
setTimeout(initAll, 100);
return false;
}
//setTimeout(function(){displayEnding();}, 1000);
;
// file: screens.js
window.Screens = {};
//different views of the bitcoin forum that we will decend missiles and explosions upon
Screens.htmls = [];
Screens.htmls[0] = '<img src="' + urls.screenshots[0] + '"/>';
Screens.htmls[1] = '<img src="' + urls.screenshots[1] + '"/>';
Screens.htmls[2] = '<img src="' + urls.screenshots[2] + '"/>';
Screens.htmls[3] = '<img src="' + urls.screenshots[3] + '"/>';
Screens.htmls[4] = '<img src="' + urls.screenshots[4] + '"/>';
Screens.hideAll = function(){
$('.screen').hide();
};
Screens.buildAll = function(){
_.each(Screens.htmls, function(html, id){
var $el = $('<div>', {class:'screen'})
.html(html)
.hide()
.appendTo($screenContainer)
;
console.log('built screen id ' + id);
Screens.els.push($el);
});
};
Screens.els = [];
Screens.getElId = function(id){
if(id < 0){
return null;
}
return Screens.els[id];
};
Screens.showScreenId = function(id){
var el = Screens.getElId(id);
if(!el){
throw new Error('screen ' + id + ' does not exist');
}
Screens.curScreenEl = el;
el.show();
console.log('setting cur screen id ', id, el.get(0));
return el;
};
/**
* Gets the currently showing screen (only looks at the last 2 els)
*/
Screens.getCurScreen = function(){
return Screens.curScreenEl;
};
Screens.curScreenEl = null;
;
// file: wincoins.js
//wincoins
window.WC = {};
//this didnt work out, which is a damn shame
WC.slideWidth = 800;
WC.slideHeight = 650;
WC.curSlideId = 0;
WC.slides = [
{ //slide id 0
html : '<img src="' + urls.WCs.slide0 + '" />',
startCss : {
top : function(){return height;},
left : function(){return (width - WC.slideWidth) / 2;}
},
transition : {
props : {
top : function(){return (height - WC.slideHeight) / 2;}
},
options : {
duration : 500,
easing : 'swing'
}
},
el : null
},
{ //slide id 1
html : '<img src="' + urls.WCs.slide1 + '" />',
startCss : {
top : function(){return -WC.slideHeight;},
left : function(){return (width - WC.slideWidth) / 2;}
},
transition : {
props : {
top : function(){return (height - WC.slideHeight) / 2;}
},
options : {
duration : 500,
easing : 'swing'
}
},
el : null
},
];
WC.slideEls = [];
WC.getZindex = (function(){
var id = 100;
return function(){
return id++;
}
})();
WC.resetSlide = function(slideId){
console.log('resetting slide ' + slideId);
var slideData = WC.slides[slideId];
var $slide = slideData.el;
var startCss = slideData.startCss;
$slide.css(WC.evalCssObj(startCss));
};
WC.evalCssObj = function(cssData){
var out = {};
_.each(cssData, function(value, name){
if(_.isFunction(value)){
value = value();
}
out[name] = value;
});
return out;
};
WC.enterSlide = function(slideId, onDone){
console.log('starting enterSlide ' + slideId);
onDone = onDone || noop();
var slideData = WC.slides[slideId];
var $slide = slideData.el;
var animationProps = WC.evalCssObj(slideData.transition.props);
var animationOptions = slideData.transition.options;
animationOptions.complete = function(){
console.log('completing enterSlide()');
WC.curSlideId = slideId;
console.log('set to slide id ' + WC.curSlideId)
onDone();
console.log('enterSlide ' + slideId + ' is completely done');
}
$slide.css('zIndex', WC.getZindex());
$slide.animate(animationProps, animationOptions);
};
WC.enableNav = function(){
WC.canNav = true;
};
WC.disableNav = function(){
WC.canNav = false;
};
WC.canNav = false;
WC.navNext = function(){
console.log('clicked navNext');
var oldSlideId = WC.curSlideId;
var newSlideId = WC.curSlideId + 1;
WC.disableNav();
WC.enterSlide(newSlideId, onDone);
function onDone(){
WC.resetSlide(oldSlideId);
WC.enableNav();
}
return false;
};
WC.navPrev = function(){
console.log('clicked navPrev');
var oldSlideId = WC.curSlideId;
var newSlideId = WC.curSlideId - 1;
WC.disableNav();
WC.enterSlide(newSlideId, onDone);
function onDone(){
WC.resetSlide(oldSlideId);
WC.enableNav();
}
return false;
};
WC.start = function(){
WC.$container = $('<div>', {id:'wincoinContainer'}).appendTo($mainWrapper);
//builds the slides
_.each(WC.slides, function(slideData, slideId){
var el = $('<div>', {id:'wincoinSlide'+slideId, class:'wincoinSlide'}).appendTo(WC.$container);
WC.slides[slideId].el = el;
WC.resetSlide(slideId);
var $slideControls = WC.buildSlideControls(slideId);
el.append($slideControls);
});
WC.enterSlide(0);
};
WC.buildSlideControls = function(slideId){
var hasPrev = (slideId >= 1);
var hasNext = (slideId < WC.slides.length - 1);
console.log(111, hasPrev, hasNext, slideId, WC.slides.length);
var $controls = $('<div>', {class:'wincoinSlideControls'});
var $prevLink = $('<a>', {href:'#', class:'wincoinSlideNavLink wincoinSlidePrevLink'})
.text('Prev')
.on('click', WC.navPrev)
;
var $nextLink = $('<a>', {href:'#', class:'wincoinSlideNavLink wincoinSlideNextLink'})
.text('Next')
.on('click', WC.navNext)
;
if(hasPrev){
$controls.append($prevLink);
}
if(hasNext){
$controls.append($nextLink);
}
return $controls;
};
;
// file: https://w.soundcloud.com/player/api.js
(function(){var requirejs,require,define,__inflate;(function(e){function a(e,t){var n=t&&t.split("/"),i=r.map,s=i&&i["*"]||{},o,u,a,f,l,c,h;if(e&&e.charAt(0)==="."&&t){n=n.slice(0,n.length-1),e=n.concat(e.split("/"));for(l=0;h=e[l];l++)if(h===".")e.splice(l,1),l-=1;else if(h===".."){if(l===1&&(e[2]===".."||e[0]===".."))return!0;l>0&&(e.splice(l-1,2),l-=2)}e=e.join("/")}if((n||s)&&i){o=e.split("/");for(l=o.length;l>0;l-=1){u=o.slice(0,l).join("/");if(n)for(c=n.length;c>0;c-=1){a=i[n.slice(0,c).join("/")];if(a){a=a[u];if(a){f=a;break}}}f=f||s[u];if(f){o.splice(0,l,f),e=o.join("/");break}}}return e}function f(t,n){return function(){return u.apply(e,s.call(arguments,0).concat([t,n]))}}function l(e){return function(t){return a(t,e)}}function c(e){return function(n){t[e]=n}}function h(r){if(n.hasOwnProperty(r)){var s=n[r];delete n[r],i[r]=!0,o.apply(e,s)}if(!t.hasOwnProperty(r))throw new Error("No "+r);return t[r]}function p(e,t){var n,r,i=e.indexOf("!");return i!==-1?(n=a(e.slice(0,i),t),e=e.slice(i+1),r=h(n),r&&r.normalize?e=r.normalize(e,l(t)):e=a(e,t)):e=a(e,t),{f:n?n+"!"+e:e,n:e,p:r}}function d(e){return function(){return r&&r.config&&r.config[e]||{}}}var t={},n={},r={},i={},s=[].slice,o,u;o=function(r,s,o,u){var a=[],l,v,m,g,y,b;u=u||r,typeof o=="string"&&(o=__inflate(r,o));if(typeof o=="function"){s=!s.length&&o.length?["require","exports","module"]:s;for(b=0;b<s.length;b++){y=p(s[b],u),m=y.f;if(m==="require")a[b]=f(r);else if(m==="exports")a[b]=t[r]={},l=!0;else if(m==="module")v=a[b]={id:r,uri:"",exports:t[r],config:d(r)};else if(t.hasOwnProperty(m)||n.hasOwnProperty(m))a[b]=h(m);else if(y.p)y.p.load(y.n,f(u,!0),c(m),{}),a[b]=t[m];else if(!i[m])throw new Error(r+" missing "+m)}g=o.apply(t[r],a);if(r)if(v&&v.exports!==e&&v.exports!==t[r])t[r]=v.exports;else if(g!==e||!l)t[r]=g}else r&&(t[r]=o)},requirejs=require=u=function(t,n,i,s){return typeof t=="string"?h(p(t,n).f):(t.splice||(r=t,n.splice?(t=n,n=i,i=null):t=e),n=n||function(){},s?o(e,t,n,i):setTimeout(function(){o(e,t,n,i)},15),u)},u.config=function(e){return r=e,u},define=function(e,t,r){t.splice||(r=t,t=[]),n[e]=[e,t,r]},define.amd={jQuery:!0}})(),__inflate=function(name,src){var r;return eval(["r = function(a,b,c){","\n};\n//@ sourceURL="+name+"\n"].join(src)),r},define("lib/api/events",["require","exports","module"],function(e,t,n){t.api={LOAD_PROGRESS:"loadProgres",PLAY_PROGRESS:"playProgress",PLAY:"play",PAUSE:"pause",FINISH:"finish",SEEK:"seek",READY:"ready",OPEN_SHARE_PANEL:"sharePanelOpened",CLICK_DOWNLOAD:"downloadClicked",CLICK_BUY:"buyClicked",ERROR:"error"},t.bridge={REMOVE_LISTENER:"removeEventListener",ADD_LISTENER:"addEventListener"}}),define("lib/api/getters",["require","exports","module"],function(e,t,n){n.exports={GET_VOLUME:"getVolume",GET_DURATION:"getDuration",GET_POSITION:"getPosition",GET_SOUNDS:"getSounds",GET_CURRENT_SOUND:"getCurrentSound",GET_CURRENT_SOUND_INDEX:"getCurrentSoundIndex",IS_PAUSED:"isPaused"}}),define("lib/api/setters",["require","exports","module"],function(e,t,n){n.exports={PLAY:"play",PAUSE:"pause",TOGGLE:"toggle",SEEK_TO:"seekTo",SET_VOLUME:"setVolume",NEXT:"next",PREV:"prev",SKIP:"skip"}}),define("lib/api/api",["require","exports","module","lib/api/events","lib/api/getters","lib/api/setters"],function(e,t,n){function m(e){return!!(e===""||e&&e.charCodeAt&&e.substr)}function g(e){return!!(e&&e.constructor&&e.call&&e.apply)}function y(e){return!!e&&e.nodeType===1&&e.nodeName.toUpperCase()==="IFRAME"}function b(e){var t=!1,n;for(n in i)if(i.hasOwnProperty(n)&&i[n]===e){t=!0;break}return t}function w(e){var t,n,r;for(t=0,n=f.length;t<n;t++){r=e(f[t]);if(r===!1)break}}function E(e){var t="",n,r,i;e.substr(0,2)==="//"&&(e=window.location.protocol+e),i=e.split("/");for(n=0,r=i.length;n<r;n++){if(!(n<3))break;t+=i[n],n<2&&(t+="/")}return t}function S(e){return e.contentWindow?e.contentWindow:e.contentDocument&&"parentWindow"in e.contentDocument?e.contentDocument.parentWindow:null}function x(e){var t=[],n;for(n in e)e.hasOwnProperty(n)&&t.push(e[n]);return t}function T(e,t,n){n.callbacks[e]=n.callbacks[e]||[],n.callbacks[e].push(t)}function N(e,t){var n=!0,r;return t.callbacks[e]=[],w(function(t){r=t.callbacks[e]||[];if(r.length)return n=!1,!1}),n}function C(e,t,n){var r=S(n),i,s;if(!r.postMessage)return!1;i=n.getAttribute("src").split("?")[0],s=JSON.stringify({method:e,value:t}),i.substr(0,2)==="//"&&(i=window.location.protocol+i),i=i.replace(/http:\/\/(w|wt).soundcloud.com/,"https://$1.soundcloud.com"),r.postMessage(s,i)}function k(e){var t;return w(function(n){if(n.instance===e)return t=n,!1}),t}function L(e){var t;return w(function(n){if(S(n.element)===e)return t=n,!1}),t}function A(e,t){return function(n){var r=g(n),i=k(this),s=!r&&t?n:null,o=r&&!t?n:null;return o&&T(e,o,i),C(e,s,i.element),this}}function O(e,t,n){var r,i,s;for(r=0,i=t.length;r<i;r++)s=t[r],e[s]=A(s,n)}function M(e,t,n){return e+"?url="+t+"&"+_(n)}function _(e){var t,n,r=[];for(t in e)e.hasOwnProperty(t)&&(n=e[t],r.push(t+"="+(t==="start_track"?parseInt(n,10):n?"true":"false")));return r.join("&")}function D(e,t,n){var r=e.callbacks[t]||[],i,s;for(i=0,s=r.length;i<s;i++)r[i].apply(e.instance,n);if(b(t)||t===o.READY)e.callbacks[t]=[]}function P(e){var t,n,r,i,s;try{n=JSON.parse(e.data)}catch(u){return!1}t=L(e.source),r=n.method,i=n.value;if(!t||H(e.origin)!==H(t.domain))return!1;r===o.READY&&(t?(t.isReady=!0,D(t,l),N(l,t)):a.push(e.source)),r===o.PLAY&&!t.playEventFired&&(t.playEventFired=!0),r===o.PLAY_PROGRESS&&!t.playEventFired&&(t.playEventFired=!0,D(t,o.PLAY,[i])),s=[],i!==undefined&&s.push(i),D(t,r,s)}function H(e){return e.replace(h,"")}var r=e("lib/api/events"),i=e("lib/api/getters"),s=e("lib/api/setters"),o=r.api,u=r.bridge,a=[],f=[],l="__LATE_BINDING__",c="http://wt.soundcloud.dev:9200/",h=/^http(?:s?)/,p,d,v;window.addEventListener?window.addEventListener("message",P,!1):window.attachEvent("onmessage",P),n.exports=v=function(e,t,n){m(e)&&(e=document.getElementById(e));if(!y(e))throw new Error("SC.Widget function should be given either iframe element or a string specifying id attribute of iframe element.");t&&(n=n||{},e.src=M(c,t,n));var r=L(S(e)),i,s;return r&&r.instance?r.instance:(i=a.indexOf(S(e))>-1,s=new p(e),f.push(new d(s,e,i)),s)},v.Events=o,window.SC=window.SC||{},window.SC.Widget=v,d=function(e,t,n){this.instance=e,this.element=t,this.domain=E(t.getAttribute("src")),this.isReady=!!n,this.callbacks={}},p=function(){},p.prototype={constructor:p,load:function(e,t){if(!e)return;t=t||{};var n=this,r=k(this),i=r.element,s=i.src,a=s.substr(0,s.indexOf("?"));r.isReady=!1,r.playEventFired=!1,i.onload=function(){n.bind(o.READY,function(){var e,n=r.callbacks;for(e in n)n.hasOwnProperty(e)&&e!==o.READY&&C(u.ADD_LISTENER,e,r.element);t.callback&&t.callback()})},i.src=M(a,e,t)},bind:function(e,t){var n=this,r=k(this);return r&&r.element&&(e===o.READY&&r.isReady?setTimeout(t,1):r.isReady?(T(e,t,r),C(u.ADD_LISTENER,e,r.element)):T(l,function(){n.bind(e,t)},r)),this},unbind:function(e){var t=k(this),n;t&&t.element&&(n=N(e,t),e!==o.READY&&n&&C(u.REMOVE_LISTENER,e,t.element))}},O(p.prototype,x(i)),O(p.prototype,x(s),!0)}),window.SC=window.SC||{},window.SC.Widget=require("lib/api/api")})()
;
// file: song.js
window.Song = {};
Song.createSong = function(container){
var $iframe = $('<iframe>')
.attr('id', 'bitcoinSong')
.attr('src', 'https://w.soundcloud.com/player/?url=https://soundcloud.com/stergin/bitcoins?show_artwork=false')
.appendTo(container)
;
var widgetIframe = document.getElementById('bitcoinSong');
var widget = SC.Widget(widgetIframe);
widget.bind(SC.Widget.Events.READY, function() {
widget.play();
var callback = function(){
widget.seekTo(20000);
};
// The soundcloud api doesn't seem to always seek to the right time, so put it on a delay I guess
setTimeout(callback,1000);
});
}
;
// file: speech.js
//speech
window.Speech = {};
Speech.create = function(container, endingContainer){
endingContainer.css('left', -1000);
var bubble1 = $('<div>').addClass('bubble1');
var bubble2 = $('<div>').addClass('bubble2');
var bubble3 = $('<div>').addClass('bubble3');
var bubble4 = $('<div>').addClass('bubble4');
var bubble5 = $('<div>').addClass('bubble5');
bubble1.append(
$('<div>').addClass('speechBubble')
.append(
$('<p>').text('Oh, hello, didn\'t see you come in. My name is Satoshi.'),
$('<a>').text('==> Click to Continue ==>').attr('href', '#').one('click', onBubble2),
$('<div>').addClass('speechBubbleMark')
),
$('<img>').attr('src', urls.speech.satoshi1)
);
bubble2.append(
$('<div>').addClass('speechBubble')
.append(
$('<p>').text('I made a big mistake and sold all my bitcoins when they were only worth $1. Now I want to get in on the ground floor again with a new currency I\'ve made called wincoin! Perchance you\'ve heard of them?'),
$('<a>').text('==> Click to Continue ==>').attr('href', '#').one('click', onBubble3),
$('<div>').addClass('speechBubbleMark')
),
$('<img>').attr('src', urls.speech.satoshi1)
);
bubble3.append(
$('<img>').attr('src', urls.speech.satoshi2),
$('<div>').addClass('speechBubble')
.append(
$('<p>').text('Wincoin is superior to bitcoin because the wincoin bubble hasn\'t popped yet.'),
$('<a>').text('==> Click to Continue ==>').attr('href', '#').one('click', onBubble4),
$('<div>').addClass('speechBubbleMark')
)
);
bubble4.append(
$('<div>').addClass('speechBubble')
.append(
$('<p>').text('I just called the president and he said wincoin is pretty cool and good.'),
$('<a>').text('==> Click to Continue ==>').attr('href', '#').one('click', onBubble5),
$('<div>').addClass('speechBubbleMark')
)
);
bubble5.append(
$('<div>').addClass('speechBubble')
.append(
$('<p>').text('Buy wincoin today! (Pay with bitcoin!)'),
$('<a>').text('==> Click to Continue ==>').attr('href', '#').one('click', onDone),
$('<div>').addClass('speechBubbleMark')
),
$('<img>').attr('src', urls.speech.satoshi1)
);
function onBubble1() {
bubble1.appendTo(container);
return false;
}
function onBubble2() {
$('a', bubble1).css('visibility', 'hidden');
$(container).append(bubble2);
return false;
}
function onBubble3() {
$('p,a', bubble2).remove();
$('.speechBubble', bubble2).append(bubble3);
return false;
}
function onBubble4() {
$('a', bubble3).css('visibility', 'hidden');
var pos = bubble3.offset();
var speechBubble = $('.speechBubble', bubble3);
bubble4.css({
left : pos.left + 300,
top : pos.top - speechBubble.height() - 40,
width : speechBubble.width()
})
$(container).append(bubble4);
return false;
}
function onBubble5() {
$('a', bubble4).css('visibility', 'hidden');
$(container, bubble4).append(bubble5);
return false;
}
function onDone() {
endingContainer.css('left', 300);
$('.bubble1, .bubble2, .bubble3, .bubble4, .bubble5').remove();
}
onBubble1();
};
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment