a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.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;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.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",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.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,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){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===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.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=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],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=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.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&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.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)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.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 Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=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 l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.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,Fn.push(o)),s&&x.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){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.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,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.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,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.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||(x.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?x.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=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.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)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.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=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._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=x.timers,a=x._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)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),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}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.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,x.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},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.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?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.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?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
diff --git a/trunk/research/players/js/jquery-1.10.2.min.map b/trunk/research/players/js/jquery-1.10.2.min.map
deleted file mode 100644
index 4dc4920bb..000000000
--- a/trunk/research/players/js/jquery-1.10.2.min.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"jquery-1.10.2.min.js","sources":["jquery-1.10.2.js"],"names":["window","undefined","readyList","rootjQuery","core_strundefined","location","document","docElem","documentElement","_jQuery","jQuery","_$","$","class2type","core_deletedIds","core_version","core_concat","concat","core_push","push","core_slice","slice","core_indexOf","indexOf","core_toString","toString","core_hasOwn","hasOwnProperty","core_trim","trim","selector","context","fn","init","core_pnum","source","core_rnotwhite","rtrim","rquickExpr","rsingleTag","rvalidchars","rvalidbraces","rvalidescape","rvalidtokens","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","completed","event","addEventListener","type","readyState","detach","ready","removeEventListener","detachEvent","prototype","jquery","constructor","match","elem","this","charAt","length","exec","find","merge","parseHTML","nodeType","ownerDocument","test","isPlainObject","isFunction","attr","getElementById","parentNode","id","makeArray","toArray","call","get","num","pushStack","elems","ret","prevObject","each","callback","args","promise","done","apply","arguments","first","eq","last","i","len","j","map","end","sort","splice","extend","src","copyIsArray","copy","name","options","clone","target","deep","isArray","expando","Math","random","replace","noConflict","isReady","readyWait","holdReady","hold","wait","body","setTimeout","resolveWith","trigger","off","obj","Array","isWindow","isNumeric","isNaN","parseFloat","isFinite","String","key","e","support","ownLast","isEmptyObject","error","msg","Error","data","keepScripts","parsed","scripts","createElement","buildFragment","remove","childNodes","parseJSON","JSON","parse","Function","parseXML","xml","tmp","DOMParser","parseFromString","ActiveXObject","async","loadXML","getElementsByTagName","noop","globalEval","execScript","camelCase","string","nodeName","toLowerCase","value","isArraylike","text","arr","results","Object","inArray","max","second","l","grep","inv","retVal","arg","guid","proxy","access","chainable","emptyGet","raw","bulk","now","Date","getTime","swap","old","style","Deferred","attachEvent","top","frameElement","doScroll","doScrollCheck","split","cachedruns","Expr","getText","isXML","compile","outermostContext","sortInput","setDocument","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","hasDuplicate","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","RegExp","rcomma","rcombinators","rsibling","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rnative","rinputs","rheader","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","fromCharCode","els","Sizzle","seed","m","groups","nid","newContext","newSelector","getElementsByClassName","qsa","tokenize","getAttribute","setAttribute","toSelector","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","removeChild","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","node","doc","parent","defaultView","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","dirkey","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","matcherCachedRuns","bySet","byElement","superMatcher","expandContext","setMatched","matchedCount","outermost","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","optionsCache","createOptions","object","flag","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","list","stack","once","fire","stopOnFalse","self","disable","add","index","lock","locked","fireWith","func","tuples","state","always","deferred","fail","then","fns","newDefer","tuple","action","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","progressContexts","resolveContexts","fragment","opt","eventName","isSupported","cssText","getSetAttribute","leadingWhitespace","tbody","htmlSerialize","hrefNormalized","opacity","cssFloat","checkOn","optSelected","enctype","html5Clone","cloneNode","outerHTML","inlineBlockNeedsLayout","shrinkWrapBlocks","pixelPosition","deleteExpando","noCloneEvent","reliableMarginRight","boxSizingReliable","noCloneChecked","optDisabled","radioValue","createDocumentFragment","appendChecked","checkClone","click","change","focusin","backgroundClip","clearCloneStyle","container","marginDiv","tds","divReset","offsetHeight","display","reliableHiddenOffsets","zoom","boxSizing","offsetWidth","getComputedStyle","width","marginRight","rbrace","rmultiDash","internalData","pvt","acceptData","thisCache","internalKey","isNode","toJSON","internalRemoveData","isEmptyDataObject","cleanData","noData","applet","embed","hasData","removeData","_data","_removeData","dataAttr","queue","dequeue","startLength","hooks","_queueHooks","next","stop","setter","delay","time","fx","speeds","timeout","clearTimeout","clearQueue","count","defer","nodeHook","boolHook","rclass","rreturn","rfocusable","rclickable","ruseDefault","getSetInput","removeAttr","prop","removeProp","propFix","addClass","classes","clazz","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","valHooks","set","option","one","optionSet","nType","attrHooks","propName","attrNames","for","class","notxml","propHooks","tabindex","parseInt","getter","setAttributeNode","createAttribute","coords","contenteditable","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","global","types","events","t","handleObjIn","special","eventHandle","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","props","srcElement","metaKey","original","which","charCode","keyCode","eventDoc","fromElement","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","relatedTarget","toElement","load","blur","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","cancelBubble","stopImmediatePropagation","mouseenter","mouseleave","orig","related","submitBubbles","form","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","on","origFn","triggerHandler","isSimple","rparentsprev","rneedsContext","guaranteedUnique","children","contents","prev","targets","winnow","is","closest","pos","prevAll","addBack","sibling","parents","parentsUntil","until","nextAll","nextUntil","prevUntil","siblings","contentDocument","contentWindow","reverse","n","r","qualifier","createSafeFragment","nodeNames","safeFrag","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","manipulation_rcheckableType","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","legend","area","param","thead","tr","col","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","th","append","createTextNode","domManip","manipulationTarget","prepend","insertBefore","before","after","keepData","getAll","setGlobalEval","dataAndEvents","deepDataAndEvents","html","replaceWith","allowIntersection","hasScripts","iNoClone","disableScript","restoreScript","_evalUrl","content","refElements","cloneCopyEvent","dest","oldData","curData","fixCloneNodeIssues","defaultChecked","defaultSelected","appendTo","prependTo","insertAfter","replaceAll","insert","found","fixDefaultChecked","destElements","srcElements","inPage","selection","wrap","safe","nodes","url","ajax","dataType","throws","wrapAll","wrapInner","unwrap","iframe","getStyles","curCSS","ralpha","ropacity","rposition","rdisplayswap","rmargin","rnumsplit","rnumnonpx","rrelNum","elemdisplay","BODY","cssShow","position","visibility","cssNormalTransform","letterSpacing","fontWeight","cssExpand","cssPrefixes","vendorPropName","capName","origName","isHidden","el","css","showHide","show","hidden","css_defaultDisplay","styles","hide","toggle","cssHooks","computed","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","extra","_computed","minWidth","maxWidth","getPropertyValue","currentStyle","left","rs","rsLeft","runtimeStyle","pixelLeft","setPositiveNumber","subtract","augmentWidthOrHeight","isBorderBox","getWidthOrHeight","valueIsBorderBox","actualDisplay","write","close","$1","visible","margin","padding","border","prefix","suffix","expand","expanded","parts","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","serialize","serializeArray","traditional","s","encodeURIComponent","ajaxSettings","buildParams","v","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","ajaxLocParts","ajaxLocation","ajax_nonce","ajax_rquery","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","_load","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataTypes","inspectPrefiltersOrTransports","originalOptions","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","params","response","responseText","complete","status","active","lastModified","etag","isLocal","processData","contentType","accepts","*","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","cacheURL","responseHeadersString","timeoutTimer","fireGlobals","transport","responseHeaders","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","mimeType","code","abort","statusText","finalText","success","method","crossDomain","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","responses","isSuccess","modified","ajaxHandleResponses","ajaxConvert","rejectWith","getJSON","getScript","firstDataType","ct","finalDataType","conv2","current","conv","dataFilter","script","text script","head","scriptCharset","charset","onload","onreadystatechange","isAbort","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","xhrCallbacks","xhrSupported","xhrId","xhrOnUnloadAbort","createStandardXHR","XMLHttpRequest","createActiveXHR","xhr","cors","username","open","xhrFields","firefoxAccessException","unload","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","tween","createTween","unit","scale","maxIterations","createFxNow","animation","collection","Animation","properties","stopped","tick","currentTime","startTime","duration","percent","tweens","run","opts","specialEasing","originalProperties","Tween","easing","gotoEnd","propFilter","timer","anim","tweener","prefilter","oldfire","dataShow","unqueued","overflow","overflowX","overflowY","eased","step","cssFn","speed","animate","genFx","fadeTo","to","optall","doAnimation","finish","stopQueue","timers","includeWidth","height","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","linear","p","swing","cos","PI","interval","setInterval","clearInterval","slow","fast","animated","offset","setOffset","win","box","getBoundingClientRect","getWindow","pageYOffset","pageXOffset","curElem","curOffset","curCSSTop","curCSSLeft","calculatePosition","curPosition","curTop","curLeft","using","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","module","exports","define","amd"],"mappings":";;;CAaA,SAAWA,EAAQC,GAOnB,GAECC,GAGAC,EAIAC,QAA2BH,GAG3BI,EAAWL,EAAOK,SAClBC,EAAWN,EAAOM,SAClBC,EAAUD,EAASE,gBAGnBC,EAAUT,EAAOU,OAGjBC,EAAKX,EAAOY,EAGZC,KAGAC,KAEAC,EAAe,SAGfC,EAAcF,EAAgBG,OAC9BC,EAAYJ,EAAgBK,KAC5BC,EAAaN,EAAgBO,MAC7BC,EAAeR,EAAgBS,QAC/BC,EAAgBX,EAAWY,SAC3BC,EAAcb,EAAWc,eACzBC,EAAYb,EAAac,KAGzBnB,EAAS,SAAUoB,EAAUC,GAE5B,MAAO,IAAIrB,GAAOsB,GAAGC,KAAMH,EAAUC,EAAS5B,IAI/C+B,EAAY,sCAAsCC,OAGlDC,EAAiB,OAGjBC,EAAQ,qCAKRC,EAAa,sCAGbC,EAAa,6BAGbC,EAAc,gBACdC,EAAe,uBACfC,EAAe,qCACfC,EAAe,kEAGfC,EAAY,QACZC,EAAa,eAGbC,EAAa,SAAUC,EAAKC,GAC3B,MAAOA,GAAOC,eAIfC,EAAY,SAAUC,IAGhB7C,EAAS8C,kBAAmC,SAAfD,EAAME,MAA2C,aAAxB/C,EAASgD,cACnEC,IACA7C,EAAO8C,UAITD,EAAS,WACHjD,EAAS8C,kBACb9C,EAASmD,oBAAqB,mBAAoBP,GAAW,GAC7DlD,EAAOyD,oBAAqB,OAAQP,GAAW,KAG/C5C,EAASoD,YAAa,qBAAsBR,GAC5ClD,EAAO0D,YAAa,SAAUR,IAIjCxC,GAAOsB,GAAKtB,EAAOiD,WAElBC,OAAQ7C,EAER8C,YAAanD,EACbuB,KAAM,SAAUH,EAAUC,EAAS5B,GAClC,GAAI2D,GAAOC,CAGX,KAAMjC,EACL,MAAOkC,KAIR,IAAyB,gBAAblC,GAAwB,CAUnC,GAPCgC,EAF2B,MAAvBhC,EAASmC,OAAO,IAAyD,MAA3CnC,EAASmC,OAAQnC,EAASoC,OAAS,IAAepC,EAASoC,QAAU,GAE7F,KAAMpC,EAAU,MAGlBQ,EAAW6B,KAAMrC,IAIrBgC,IAAUA,EAAM,IAAO/B,EAqDrB,OAAMA,GAAWA,EAAQ6B,QACtB7B,GAAW5B,GAAaiE,KAAMtC,GAKhCkC,KAAKH,YAAa9B,GAAUqC,KAAMtC,EAxDzC,IAAKgC,EAAM,GAAK,CAWf,GAVA/B,EAAUA,YAAmBrB,GAASqB,EAAQ,GAAKA,EAGnDrB,EAAO2D,MAAOL,KAAMtD,EAAO4D,UAC1BR,EAAM,GACN/B,GAAWA,EAAQwC,SAAWxC,EAAQyC,eAAiBzC,EAAUzB,GACjE,IAIIiC,EAAWkC,KAAMX,EAAM,KAAQpD,EAAOgE,cAAe3C,GACzD,IAAM+B,IAAS/B,GAETrB,EAAOiE,WAAYX,KAAMF,IAC7BE,KAAMF,GAAS/B,EAAS+B,IAIxBE,KAAKY,KAAMd,EAAO/B,EAAS+B,GAK9B,OAAOE,MAQP,GAJAD,EAAOzD,EAASuE,eAAgBf,EAAM,IAIjCC,GAAQA,EAAKe,WAAa,CAG9B,GAAKf,EAAKgB,KAAOjB,EAAM,GACtB,MAAO3D,GAAWiE,KAAMtC,EAIzBkC,MAAKE,OAAS,EACdF,KAAK,GAAKD,EAKX,MAFAC,MAAKjC,QAAUzB,EACf0D,KAAKlC,SAAWA,EACTkC,KAcH,MAAKlC,GAASyC,UACpBP,KAAKjC,QAAUiC,KAAK,GAAKlC,EACzBkC,KAAKE,OAAS,EACPF,MAIItD,EAAOiE,WAAY7C,GACvB3B,EAAWqD,MAAO1B,IAGrBA,EAASA,WAAa7B,IAC1B+D,KAAKlC,SAAWA,EAASA,SACzBkC,KAAKjC,QAAUD,EAASC,SAGlBrB,EAAOsE,UAAWlD,EAAUkC,QAIpClC,SAAU,GAGVoC,OAAQ,EAERe,QAAS,WACR,MAAO7D,GAAW8D,KAAMlB,OAKzBmB,IAAK,SAAUC,GACd,MAAc,OAAPA,EAGNpB,KAAKiB,UAGG,EAANG,EAAUpB,KAAMA,KAAKE,OAASkB,GAAQpB,KAAMoB,IAKhDC,UAAW,SAAUC,GAGpB,GAAIC,GAAM7E,EAAO2D,MAAOL,KAAKH,cAAeyB,EAO5C,OAJAC,GAAIC,WAAaxB,KACjBuB,EAAIxD,QAAUiC,KAAKjC,QAGZwD,GAMRE,KAAM,SAAUC,EAAUC,GACzB,MAAOjF,GAAO+E,KAAMzB,KAAM0B,EAAUC,IAGrCnC,MAAO,SAAUxB,GAIhB,MAFAtB,GAAO8C,MAAMoC,UAAUC,KAAM7D,GAEtBgC,MAGR3C,MAAO,WACN,MAAO2C,MAAKqB,UAAWjE,EAAW0E,MAAO9B,KAAM+B,aAGhDC,MAAO,WACN,MAAOhC,MAAKiC,GAAI,IAGjBC,KAAM,WACL,MAAOlC,MAAKiC,GAAI,KAGjBA,GAAI,SAAUE,GACb,GAAIC,GAAMpC,KAAKE,OACdmC,GAAKF,GAAU,EAAJA,EAAQC,EAAM,EAC1B,OAAOpC,MAAKqB,UAAWgB,GAAK,GAASD,EAAJC,GAAYrC,KAAKqC,SAGnDC,IAAK,SAAUZ,GACd,MAAO1B,MAAKqB,UAAW3E,EAAO4F,IAAItC,KAAM,SAAUD,EAAMoC,GACvD,MAAOT,GAASR,KAAMnB,EAAMoC,EAAGpC,OAIjCwC,IAAK,WACJ,MAAOvC,MAAKwB,YAAcxB,KAAKH,YAAY,OAK5C1C,KAAMD,EACNsF,QAASA,KACTC,UAAWA,QAIZ/F,EAAOsB,GAAGC,KAAK0B,UAAYjD,EAAOsB,GAElCtB,EAAOgG,OAAShG,EAAOsB,GAAG0E,OAAS,WAClC,GAAIC,GAAKC,EAAaC,EAAMC,EAAMC,EAASC,EAC1CC,EAASlB,UAAU,OACnBI,EAAI,EACJjC,EAAS6B,UAAU7B,OACnBgD,GAAO,CAqBR,KAlBuB,iBAAXD,KACXC,EAAOD,EACPA,EAASlB,UAAU,OAEnBI,EAAI,GAIkB,gBAAXc,IAAwBvG,EAAOiE,WAAWsC,KACrDA,MAII/C,IAAWiC,IACfc,EAASjD,OACPmC,GAGSjC,EAAJiC,EAAYA,IAEnB,GAAmC,OAA7BY,EAAUhB,UAAWI,IAE1B,IAAMW,IAAQC,GACbJ,EAAMM,EAAQH,GACdD,EAAOE,EAASD,GAGXG,IAAWJ,IAKXK,GAAQL,IAAUnG,EAAOgE,cAAcmC,KAAUD,EAAclG,EAAOyG,QAAQN,MAC7ED,GACJA,GAAc,EACdI,EAAQL,GAAOjG,EAAOyG,QAAQR,GAAOA,MAGrCK,EAAQL,GAAOjG,EAAOgE,cAAciC,GAAOA,KAI5CM,EAAQH,GAASpG,EAAOgG,OAAQQ,EAAMF,EAAOH,IAGlCA,IAAS5G,IACpBgH,EAAQH,GAASD,GAOrB,OAAOI,IAGRvG,EAAOgG,QAGNU,QAAS,UAAarG,EAAesG,KAAKC,UAAWC,QAAS,MAAO,IAErEC,WAAY,SAAUN,GASrB,MARKlH,GAAOY,IAAMF,IACjBV,EAAOY,EAAID,GAGPuG,GAAQlH,EAAOU,SAAWA,IAC9BV,EAAOU,OAASD,GAGVC,GAIR+G,SAAS,EAITC,UAAW,EAGXC,UAAW,SAAUC,GACfA,EACJlH,EAAOgH,YAEPhH,EAAO8C,OAAO,IAKhBA,MAAO,SAAUqE,GAGhB,GAAKA,KAAS,KAASnH,EAAOgH,WAAYhH,EAAO+G,QAAjD,CAKA,IAAMnH,EAASwH,KACd,MAAOC,YAAYrH,EAAO8C,MAI3B9C,GAAO+G,SAAU,EAGZI,KAAS,KAAUnH,EAAOgH,UAAY,IAK3CxH,EAAU8H,YAAa1H,GAAYI,IAG9BA,EAAOsB,GAAGiG,SACdvH,EAAQJ,GAAW2H,QAAQ,SAASC,IAAI,YAO1CvD,WAAY,SAAUwD,GACrB,MAA4B,aAArBzH,EAAO2C,KAAK8E,IAGpBhB,QAASiB,MAAMjB,SAAW,SAAUgB,GACnC,MAA4B,UAArBzH,EAAO2C,KAAK8E,IAGpBE,SAAU,SAAUF,GAEnB,MAAc,OAAPA,GAAeA,GAAOA,EAAInI,QAGlCsI,UAAW,SAAUH,GACpB,OAAQI,MAAOC,WAAWL,KAAUM,SAAUN,IAG/C9E,KAAM,SAAU8E,GACf,MAAY,OAAPA,EACWA,EAARO,GAEc,gBAARP,IAAmC,kBAARA,GACxCtH,EAAYW,EAAc0D,KAAKiD,KAAU,eAClCA,IAGTzD,cAAe,SAAUyD,GACxB,GAAIQ,EAKJ,KAAMR,GAA4B,WAArBzH,EAAO2C,KAAK8E,IAAqBA,EAAI5D,UAAY7D,EAAO2H,SAAUF,GAC9E,OAAO,CAGR,KAEC,GAAKA,EAAItE,cACPnC,EAAYwD,KAAKiD,EAAK,iBACtBzG,EAAYwD,KAAKiD,EAAItE,YAAYF,UAAW,iBAC7C,OAAO,EAEP,MAAQiF,GAET,OAAO,EAKR,GAAKlI,EAAOmI,QAAQC,QACnB,IAAMH,IAAOR,GACZ,MAAOzG,GAAYwD,KAAMiD,EAAKQ,EAMhC,KAAMA,IAAOR,IAEb,MAAOQ,KAAQ1I,GAAayB,EAAYwD,KAAMiD,EAAKQ,IAGpDI,cAAe,SAAUZ,GACxB,GAAIrB,EACJ,KAAMA,IAAQqB,GACb,OAAO,CAER,QAAO,GAGRa,MAAO,SAAUC,GAChB,KAAUC,OAAOD,IAMlB3E,UAAW,SAAU6E,EAAMpH,EAASqH,GACnC,IAAMD,GAAwB,gBAATA,GACpB,MAAO,KAEgB,kBAAZpH,KACXqH,EAAcrH,EACdA,GAAU,GAEXA,EAAUA,GAAWzB,CAErB,IAAI+I,GAAS9G,EAAW4B,KAAMgF,GAC7BG,GAAWF,KAGZ,OAAKC,IACKtH,EAAQwH,cAAeF,EAAO,MAGxCA,EAAS3I,EAAO8I,eAAiBL,GAAQpH,EAASuH,GAC7CA,GACJ5I,EAAQ4I,GAAUG,SAEZ/I,EAAO2D,SAAWgF,EAAOK,cAGjCC,UAAW,SAAUR,GAEpB,MAAKnJ,GAAO4J,MAAQ5J,EAAO4J,KAAKC,MACxB7J,EAAO4J,KAAKC,MAAOV,GAGb,OAATA,EACGA,EAGa,gBAATA,KAGXA,EAAOzI,EAAOmB,KAAMsH,GAEfA,GAGC3G,EAAYiC,KAAM0E,EAAK5B,QAAS7E,EAAc,KACjD6E,QAAS5E,EAAc,KACvB4E,QAAS9E,EAAc,MAEXqH,SAAU,UAAYX,MAKtCzI,EAAOsI,MAAO,iBAAmBG,GAAjCzI,IAIDqJ,SAAU,SAAUZ,GACnB,GAAIa,GAAKC,CACT,KAAMd,GAAwB,gBAATA,GACpB,MAAO,KAER,KACMnJ,EAAOkK,WACXD,EAAM,GAAIC,WACVF,EAAMC,EAAIE,gBAAiBhB,EAAO,cAElCa,EAAM,GAAII,eAAe,oBACzBJ,EAAIK,MAAQ,QACZL,EAAIM,QAASnB,IAEb,MAAOP,GACRoB,EAAM/J,EAKP,MAHM+J,IAAQA,EAAIxJ,kBAAmBwJ,EAAIO,qBAAsB,eAAgBrG,QAC9ExD,EAAOsI,MAAO,gBAAkBG,GAE1Ba,GAGRQ,KAAM,aAKNC,WAAY,SAAUtB,GAChBA,GAAQzI,EAAOmB,KAAMsH,KAIvBnJ,EAAO0K,YAAc,SAAUvB,GAChCnJ,EAAe,KAAEkF,KAAMlF,EAAQmJ,KAC3BA,IAMPwB,UAAW,SAAUC,GACpB,MAAOA,GAAOrD,QAAS3E,EAAW,OAAQ2E,QAAS1E,EAAYC,IAGhE+H,SAAU,SAAU9G,EAAM+C,GACzB,MAAO/C,GAAK8G,UAAY9G,EAAK8G,SAASC,gBAAkBhE,EAAKgE,eAI9DrF,KAAM,SAAU0C,EAAKzC,EAAUC,GAC9B,GAAIoF,GACH5E,EAAI,EACJjC,EAASiE,EAAIjE,OACbiD,EAAU6D,EAAa7C,EAExB,IAAKxC,GACJ,GAAKwB,GACJ,KAAYjD,EAAJiC,EAAYA,IAGnB,GAFA4E,EAAQrF,EAASI,MAAOqC,EAAKhC,GAAKR,GAE7BoF,KAAU,EACd,UAIF,KAAM5E,IAAKgC,GAGV,GAFA4C,EAAQrF,EAASI,MAAOqC,EAAKhC,GAAKR,GAE7BoF,KAAU,EACd,UAOH,IAAK5D,GACJ,KAAYjD,EAAJiC,EAAYA,IAGnB,GAFA4E,EAAQrF,EAASR,KAAMiD,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpC4E,KAAU,EACd,UAIF,KAAM5E,IAAKgC,GAGV,GAFA4C,EAAQrF,EAASR,KAAMiD,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpC4E,KAAU,EACd,KAMJ,OAAO5C,IAIRtG,KAAMD,IAAcA,EAAUsD,KAAK,gBAClC,SAAU+F,GACT,MAAe,OAARA,EACN,GACArJ,EAAUsD,KAAM+F,IAIlB,SAAUA,GACT,MAAe,OAARA,EACN,IACEA,EAAO,IAAK1D,QAASlF,EAAO,KAIjC2C,UAAW,SAAUkG,EAAKC,GACzB,GAAI5F,GAAM4F,KAaV,OAXY,OAAPD,IACCF,EAAaI,OAAOF,IACxBxK,EAAO2D,MAAOkB,EACE,gBAAR2F,IACLA,GAAQA,GAGXhK,EAAUgE,KAAMK,EAAK2F,IAIhB3F,GAGR8F,QAAS,SAAUtH,EAAMmH,EAAK/E,GAC7B,GAAIC,EAEJ,IAAK8E,EAAM,CACV,GAAK5J,EACJ,MAAOA,GAAa4D,KAAMgG,EAAKnH,EAAMoC,EAMtC,KAHAC,EAAM8E,EAAIhH,OACViC,EAAIA,EAAQ,EAAJA,EAAQkB,KAAKiE,IAAK,EAAGlF,EAAMD,GAAMA,EAAI,EAEjCC,EAAJD,EAASA,IAEhB,GAAKA,IAAK+E,IAAOA,EAAK/E,KAAQpC,EAC7B,MAAOoC,GAKV,MAAO,IAGR9B,MAAO,SAAU2B,EAAOuF,GACvB,GAAIC,GAAID,EAAOrH,OACdiC,EAAIH,EAAM9B,OACVmC,EAAI,CAEL,IAAkB,gBAANmF,GACX,KAAYA,EAAJnF,EAAOA,IACdL,EAAOG,KAAQoF,EAAQlF,OAGxB,OAAQkF,EAAOlF,KAAOpG,EACrB+F,EAAOG,KAAQoF,EAAQlF,IAMzB,OAFAL,GAAM9B,OAASiC,EAERH,GAGRyF,KAAM,SAAUnG,EAAOI,EAAUgG,GAChC,GAAIC,GACHpG,KACAY,EAAI,EACJjC,EAASoB,EAAMpB,MAKhB,KAJAwH,IAAQA,EAIIxH,EAAJiC,EAAYA,IACnBwF,IAAWjG,EAAUJ,EAAOa,GAAKA,GAC5BuF,IAAQC,GACZpG,EAAIpE,KAAMmE,EAAOa,GAInB,OAAOZ,IAIRe,IAAK,SAAUhB,EAAOI,EAAUkG,GAC/B,GAAIb,GACH5E,EAAI,EACJjC,EAASoB,EAAMpB,OACfiD,EAAU6D,EAAa1F,GACvBC,IAGD,IAAK4B,EACJ,KAAYjD,EAAJiC,EAAYA,IACnB4E,EAAQrF,EAAUJ,EAAOa,GAAKA,EAAGyF,GAEnB,MAATb,IACJxF,EAAKA,EAAIrB,QAAW6G,OAMtB,KAAM5E,IAAKb,GACVyF,EAAQrF,EAAUJ,EAAOa,GAAKA,EAAGyF,GAEnB,MAATb,IACJxF,EAAKA,EAAIrB,QAAW6G,EAMvB,OAAO/J,GAAY8E,SAAWP,IAI/BsG,KAAM,EAINC,MAAO,SAAU9J,EAAID,GACpB,GAAI4D,GAAMmG,EAAO7B,CAUjB,OARwB,gBAAZlI,KACXkI,EAAMjI,EAAID,GACVA,EAAUC,EACVA,EAAKiI,GAKAvJ,EAAOiE,WAAY3C,IAKzB2D,EAAOvE,EAAW8D,KAAMa,UAAW,GACnC+F,EAAQ,WACP,MAAO9J,GAAG8D,MAAO/D,GAAWiC,KAAM2B,EAAK1E,OAAQG,EAAW8D,KAAMa,cAIjE+F,EAAMD,KAAO7J,EAAG6J,KAAO7J,EAAG6J,MAAQnL,EAAOmL,OAElCC,GAZC7L,GAiBT8L,OAAQ,SAAUzG,EAAOtD,EAAI2G,EAAKoC,EAAOiB,EAAWC,EAAUC,GAC7D,GAAI/F,GAAI,EACPjC,EAASoB,EAAMpB,OACfiI,EAAc,MAAPxD,CAGR,IAA4B,WAAvBjI,EAAO2C,KAAMsF,GAAqB,CACtCqD,GAAY,CACZ,KAAM7F,IAAKwC,GACVjI,EAAOqL,OAAQzG,EAAOtD,EAAImE,EAAGwC,EAAIxC,IAAI,EAAM8F,EAAUC,OAIhD,IAAKnB,IAAU9K,IACrB+L,GAAY,EAENtL,EAAOiE,WAAYoG,KACxBmB,GAAM,GAGFC,IAECD,GACJlK,EAAGkD,KAAMI,EAAOyF,GAChB/I,EAAK,OAILmK,EAAOnK,EACPA,EAAK,SAAU+B,EAAM4E,EAAKoC,GACzB,MAAOoB,GAAKjH,KAAMxE,EAAQqD,GAAQgH,MAKhC/I,GACJ,KAAYkC,EAAJiC,EAAYA,IACnBnE,EAAIsD,EAAMa,GAAIwC,EAAKuD,EAAMnB,EAAQA,EAAM7F,KAAMI,EAAMa,GAAIA,EAAGnE,EAAIsD,EAAMa,GAAIwC,IAK3E,OAAOqD,GACN1G,EAGA6G,EACCnK,EAAGkD,KAAMI,GACTpB,EAASlC,EAAIsD,EAAM,GAAIqD,GAAQsD,GAGlCG,IAAK,WACJ,OAAO,GAAMC,OAASC,WAMvBC,KAAM,SAAUxI,EAAMgD,EAASrB,EAAUC,GACxC,GAAIJ,GAAKuB,EACR0F,IAGD,KAAM1F,IAAQC,GACbyF,EAAK1F,GAAS/C,EAAK0I,MAAO3F,GAC1B/C,EAAK0I,MAAO3F,GAASC,EAASD,EAG/BvB,GAAMG,EAASI,MAAO/B,EAAM4B,MAG5B,KAAMmB,IAAQC,GACbhD,EAAK0I,MAAO3F,GAAS0F,EAAK1F,EAG3B,OAAOvB,MAIT7E,EAAO8C,MAAMoC,QAAU,SAAUuC,GAChC,IAAMjI,EAOL,GALAA,EAAYQ,EAAOgM,WAKU,aAAxBpM,EAASgD,WAEbyE,WAAYrH,EAAO8C,WAGb,IAAKlD,EAAS8C,iBAEpB9C,EAAS8C,iBAAkB,mBAAoBF,GAAW,GAG1DlD,EAAOoD,iBAAkB,OAAQF,GAAW,OAGtC,CAEN5C,EAASqM,YAAa,qBAAsBzJ,GAG5ClD,EAAO2M,YAAa,SAAUzJ,EAI9B,IAAI0J,IAAM,CAEV,KACCA,EAA6B,MAAvB5M,EAAO6M,cAAwBvM,EAASE,gBAC7C,MAAMoI,IAEHgE,GAAOA,EAAIE,UACf,QAAUC,KACT,IAAMrM,EAAO+G,QAAU,CAEtB,IAGCmF,EAAIE,SAAS,QACZ,MAAMlE,GACP,MAAOb,YAAYgF,EAAe,IAInCxJ,IAGA7C,EAAO8C,YAMZ,MAAOtD,GAAU0F,QAASuC,IAI3BzH,EAAO+E,KAAK,gEAAgEuH,MAAM,KAAM,SAAS7G,EAAGW,GACnGjG,EAAY,WAAaiG,EAAO,KAAQA,EAAKgE,eAG9C,SAASE,GAAa7C,GACrB,GAAIjE,GAASiE,EAAIjE,OAChBb,EAAO3C,EAAO2C,KAAM8E,EAErB,OAAKzH,GAAO2H,SAAUF,IACd,EAGc,IAAjBA,EAAI5D,UAAkBL,GACnB,EAGQ,UAATb,GAA6B,aAATA,IACb,IAAXa,GACgB,gBAAXA,IAAuBA,EAAS,GAAOA,EAAS,IAAOiE,IAIhEhI,EAAaO,EAAOJ,GAWpB,SAAWN,EAAQC,GAEnB,GAAIkG,GACH0C,EACAoE,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAlN,EACAC,EACAkN,EACAC,EACAC,EACAC,EACAC,EAGAzG,EAAU,UAAY,GAAKiF,MAC3ByB,EAAe9N,EAAOM,SACtByN,EAAU,EACVlI,EAAO,EACPmI,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,GAAe,EACfC,EAAY,SAAUC,EAAGC,GACxB,MAAKD,KAAMC,GACVH,GAAe,EACR,GAED,GAIRI,QAAsBvO,GACtBwO,EAAe,GAAK,GAGpBC,KAAc/M,eACduJ,KACAyD,EAAMzD,EAAIyD,IACVC,EAAc1D,EAAI/J,KAClBA,EAAO+J,EAAI/J,KACXE,EAAQ6J,EAAI7J,MAEZE,EAAU2J,EAAI3J,SAAW,SAAUwC,GAClC,GAAIoC,GAAI,EACPC,EAAMpC,KAAKE,MACZ,MAAYkC,EAAJD,EAASA,IAChB,GAAKnC,KAAKmC,KAAOpC,EAChB,MAAOoC,EAGT,OAAO,IAGR0I,EAAW,6HAKXC,EAAa,sBAEbC,EAAoB,mCAKpBC,EAAaD,EAAkBxH,QAAS,IAAK,MAG7C0H,EAAa,MAAQH,EAAa,KAAOC,EAAoB,IAAMD,EAClE,mBAAqBA,EAAa,wCAA0CE,EAAa,QAAUF,EAAa,OAQjHI,EAAU,KAAOH,EAAoB,mEAAqEE,EAAW1H,QAAS,EAAG,GAAM,eAGvIlF,EAAY8M,OAAQ,IAAML,EAAa,8BAAgCA,EAAa,KAAM,KAE1FM,EAAaD,OAAQ,IAAML,EAAa,KAAOA,EAAa,KAC5DO,EAAmBF,OAAQ,IAAML,EAAa,WAAaA,EAAa,IAAMA,EAAa,KAE3FQ,EAAeH,OAAQL,EAAa,SACpCS,EAAuBJ,OAAQ,IAAML,EAAa,gBAAkBA,EAAa,OAAQ,KAEzFU,EAAcL,OAAQD,GACtBO,EAAkBN,OAAQ,IAAMH,EAAa,KAE7CU,GACCC,GAAUR,OAAQ,MAAQJ,EAAoB,KAC9Ca,MAAaT,OAAQ,QAAUJ,EAAoB,KACnDc,IAAWV,OAAQ,KAAOJ,EAAkBxH,QAAS,IAAK,MAAS,KACnEuI,KAAYX,OAAQ,IAAMF,GAC1Bc,OAAcZ,OAAQ,IAAMD,GAC5Bc,MAAab,OAAQ,yDAA2DL,EAC/E,+BAAiCA,EAAa,cAAgBA,EAC9D,aAAeA,EAAa,SAAU,KACvCmB,KAAYd,OAAQ,OAASN,EAAW,KAAM,KAG9CqB,aAAoBf,OAAQ,IAAML,EAAa,mDAC9CA,EAAa,mBAAqBA,EAAa,mBAAoB,MAGrEqB,EAAU,yBAGV7N,EAAa,mCAEb8N,GAAU,sCACVC,GAAU,SAEVC,GAAU,QAGVC,GAAgBpB,OAAQ,qBAAuBL,EAAa,MAAQA,EAAa,OAAQ,MACzF0B,GAAY,SAAUC,EAAGC,EAASC,GACjC,GAAIC,GAAO,KAAOF,EAAU,KAI5B,OAAOE,KAASA,GAAQD,EACvBD,EAEO,EAAPE,EACClI,OAAOmI,aAAcD,EAAO,OAE5BlI,OAAOmI,aAA2B,MAAbD,GAAQ,GAA4B,MAAR,KAAPA,GAI9C,KACCzP,EAAK2E,MACHoF,EAAM7J,EAAM6D,KAAM4I,EAAapE,YAChCoE,EAAapE,YAIdwB,EAAK4C,EAAapE,WAAWxF,QAASK,SACrC,MAAQqE,IACTzH,GAAS2E,MAAOoF,EAAIhH,OAGnB,SAAU+C,EAAQ6J,GACjBlC,EAAY9I,MAAOmB,EAAQ5F,EAAM6D,KAAK4L,KAKvC,SAAU7J,EAAQ6J,GACjB,GAAIzK,GAAIY,EAAO/C,OACdiC,EAAI,CAEL,OAASc,EAAOZ,KAAOyK,EAAI3K,MAC3Bc,EAAO/C,OAASmC,EAAI,IAKvB,QAAS0K,IAAQjP,EAAUC,EAASoJ,EAAS6F,GAC5C,GAAIlN,GAAOC,EAAMkN,EAAG1M,EAEnB4B,EAAG+K,EAAQ1E,EAAK2E,EAAKC,EAAYC,CASlC,KAPOtP,EAAUA,EAAQyC,eAAiBzC,EAAU+L,KAAmBxN,GACtEkN,EAAazL,GAGdA,EAAUA,GAAWzB,EACrB6K,EAAUA,OAEJrJ,GAAgC,gBAAbA,GACxB,MAAOqJ,EAGR,IAAuC,KAAjC5G,EAAWxC,EAAQwC,WAAgC,IAAbA,EAC3C,QAGD,IAAKkJ,IAAmBuD,EAAO,CAG9B,GAAMlN,EAAQxB,EAAW6B,KAAMrC,GAE9B,GAAMmP,EAAInN,EAAM,IACf,GAAkB,IAAbS,EAAiB,CAIrB,GAHAR,EAAOhC,EAAQ8C,eAAgBoM,IAG1BlN,IAAQA,EAAKe,WAQjB,MAAOqG,EALP,IAAKpH,EAAKgB,KAAOkM,EAEhB,MADA9F,GAAQhK,KAAM4C,GACPoH,MAOT,IAAKpJ,EAAQyC,gBAAkBT,EAAOhC,EAAQyC,cAAcK,eAAgBoM,KAC3EpD,EAAU9L,EAASgC,IAAUA,EAAKgB,KAAOkM,EAEzC,MADA9F,GAAQhK,KAAM4C,GACPoH,MAKH,CAAA,GAAKrH,EAAM,GAEjB,MADA3C,GAAK2E,MAAOqF,EAASpJ,EAAQwI,qBAAsBzI,IAC5CqJ,CAGD,KAAM8F,EAAInN,EAAM,KAAO+E,EAAQyI,wBAA0BvP,EAAQuP,uBAEvE,MADAnQ,GAAK2E,MAAOqF,EAASpJ,EAAQuP,uBAAwBL,IAC9C9F,EAKT,GAAKtC,EAAQ0I,OAAS7D,IAAcA,EAAUjJ,KAAM3C,IAAc,CASjE,GARAqP,EAAM3E,EAAMpF,EACZgK,EAAarP,EACbsP,EAA2B,IAAb9M,GAAkBzC,EAMd,IAAbyC,GAAqD,WAAnCxC,EAAQ8I,SAASC,cAA6B,CACpEoG,EAASM,GAAU1P,IAEb0K,EAAMzK,EAAQ0P,aAAa,OAChCN,EAAM3E,EAAIjF,QAAS+I,GAAS,QAE5BvO,EAAQ2P,aAAc,KAAMP,GAE7BA,EAAM,QAAUA,EAAM,MAEtBhL,EAAI+K,EAAOhN,MACX,OAAQiC,IACP+K,EAAO/K,GAAKgL,EAAMQ,GAAYT,EAAO/K,GAEtCiL,GAAa9B,EAAS7K,KAAM3C,IAAcC,EAAQ+C,YAAc/C,EAChEsP,EAAcH,EAAOU,KAAK,KAG3B,GAAKP,EACJ,IAIC,MAHAlQ,GAAK2E,MAAOqF,EACXiG,EAAWS,iBAAkBR,IAEvBlG,EACN,MAAM2G,IACN,QACKtF,GACLzK,EAAQgQ,gBAAgB,QAQ7B,MAAOC,IAAQlQ,EAASyF,QAASlF,EAAO,MAAQN,EAASoJ,EAAS6F,GASnE,QAAS/C,MACR,GAAIgE,KAEJ,SAASC,GAAOvJ,EAAKoC,GAMpB,MAJKkH,GAAK9Q,KAAMwH,GAAO,KAAQuE,EAAKiF,mBAE5BD,GAAOD,EAAKG,SAEZF,EAAOvJ,GAAQoC,EAExB,MAAOmH,GAOR,QAASG,IAAcrQ,GAEtB,MADAA,GAAIoF,IAAY,EACTpF,EAOR,QAASsQ,IAAQtQ,GAChB,GAAIuQ,GAAMjS,EAASiJ,cAAc,MAEjC,KACC,QAASvH,EAAIuQ,GACZ,MAAO3J,GACR,OAAO,EACN,QAEI2J,EAAIzN,YACRyN,EAAIzN,WAAW0N,YAAaD,GAG7BA,EAAM,MASR,QAASE,IAAWC,EAAOC,GAC1B,GAAIzH,GAAMwH,EAAM1F,MAAM,KACrB7G,EAAIuM,EAAMxO,MAEX,OAAQiC,IACP+G,EAAK0F,WAAY1H,EAAI/E,IAAOwM,EAU9B,QAASE,IAAcvE,EAAGC,GACzB,GAAIuE,GAAMvE,GAAKD,EACdyE,EAAOD,GAAsB,IAAfxE,EAAE/J,UAAiC,IAAfgK,EAAEhK,YAChCgK,EAAEyE,aAAevE,KACjBH,EAAE0E,aAAevE,EAGtB,IAAKsE,EACJ,MAAOA,EAIR,IAAKD,EACJ,MAASA,EAAMA,EAAIG,YAClB,GAAKH,IAAQvE,EACZ,MAAO,EAKV,OAAOD,GAAI,EAAI,GAOhB,QAAS4E,IAAmB7P,GAC3B,MAAO,UAAUU,GAChB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,OAAgB,UAAThE,GAAoB/C,EAAKV,OAASA,GAQ3C,QAAS8P,IAAoB9P,GAC5B,MAAO,UAAUU,GAChB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,QAAiB,UAAThE,GAA6B,WAATA,IAAsB/C,EAAKV,OAASA,GAQlE,QAAS+P,IAAwBpR,GAChC,MAAOqQ,IAAa,SAAUgB,GAE7B,MADAA,IAAYA,EACLhB,GAAa,SAAUrB,EAAMpD,GACnC,GAAIvH,GACHiN,EAAetR,KAAQgP,EAAK9M,OAAQmP,GACpClN,EAAImN,EAAapP,MAGlB,OAAQiC,IACF6K,EAAO3K,EAAIiN,EAAanN,MAC5B6K,EAAK3K,KAAOuH,EAAQvH,GAAK2K,EAAK3K,SAWnC+G,EAAQ2D,GAAO3D,MAAQ,SAAUrJ,GAGhC,GAAIvD,GAAkBuD,IAASA,EAAKS,eAAiBT,GAAMvD,eAC3D,OAAOA,GAA+C,SAA7BA,EAAgBqK,UAAsB,GAIhEhC,EAAUkI,GAAOlI,WAOjB2E,EAAcuD,GAAOvD,YAAc,SAAU+F,GAC5C,GAAIC,GAAMD,EAAOA,EAAK/O,eAAiB+O,EAAOzF,EAC7C2F,EAASD,EAAIE,WAGd,OAAKF,KAAQlT,GAA6B,IAAjBkT,EAAIjP,UAAmBiP,EAAIhT,iBAKpDF,EAAWkT,EACXjT,EAAUiT,EAAIhT,gBAGdiN,GAAkBL,EAAOoG,GAMpBC,GAAUA,EAAO9G,aAAe8G,IAAWA,EAAO7G,KACtD6G,EAAO9G,YAAa,iBAAkB,WACrCa,MASF3E,EAAQoG,WAAaqD,GAAO,SAAUC,GAErC,MADAA,GAAIoB,UAAY,KACRpB,EAAId,aAAa,eAO1B5I,EAAQ0B,qBAAuB+H,GAAO,SAAUC,GAE/C,MADAA,GAAIqB,YAAaJ,EAAIK,cAAc,MAC3BtB,EAAIhI,qBAAqB,KAAKrG,SAIvC2E,EAAQyI,uBAAyBgB,GAAO,SAAUC,GAQjD,MAPAA,GAAIuB,UAAY,+CAIhBvB,EAAIwB,WAAWJ,UAAY,IAGuB,IAA3CpB,EAAIjB,uBAAuB,KAAKpN,SAOxC2E,EAAQmL,QAAU1B,GAAO,SAAUC,GAElC,MADAhS,GAAQqT,YAAarB,GAAMxN,GAAKqC,GACxBoM,EAAIS,oBAAsBT,EAAIS,kBAAmB7M,GAAUlD,SAI/D2E,EAAQmL,SACZ9G,EAAK9I,KAAS,GAAI,SAAUW,EAAIhD,GAC/B,SAAYA,GAAQ8C,iBAAmB2J,GAAgBf,EAAiB,CACvE,GAAIwD,GAAIlP,EAAQ8C,eAAgBE,EAGhC,OAAOkM,IAAKA,EAAEnM,YAAcmM,QAG9B/D,EAAKgH,OAAW,GAAI,SAAUnP,GAC7B,GAAIoP,GAASpP,EAAGwC,QAASgJ,GAAWC,GACpC,OAAO,UAAUzM,GAChB,MAAOA,GAAK0N,aAAa,QAAU0C,YAM9BjH,GAAK9I,KAAS,GAErB8I,EAAKgH,OAAW,GAAK,SAAUnP,GAC9B,GAAIoP,GAASpP,EAAGwC,QAASgJ,GAAWC,GACpC,OAAO,UAAUzM,GAChB,GAAIwP,SAAcxP,GAAKqQ,mBAAqB5F,GAAgBzK,EAAKqQ,iBAAiB,KAClF,OAAOb,IAAQA,EAAKxI,QAAUoJ,KAMjCjH,EAAK9I,KAAU,IAAIyE,EAAQ0B,qBAC1B,SAAU8J,EAAKtS,GACd,aAAYA,GAAQwI,uBAAyBiE,EACrCzM,EAAQwI,qBAAsB8J,GADtC,GAID,SAAUA,EAAKtS,GACd,GAAIgC,GACHkG,KACA9D,EAAI,EACJgF,EAAUpJ,EAAQwI,qBAAsB8J,EAGzC,IAAa,MAARA,EAAc,CAClB,MAAStQ,EAAOoH,EAAQhF,KACA,IAAlBpC,EAAKQ,UACT0F,EAAI9I,KAAM4C,EAIZ,OAAOkG,GAER,MAAOkB,IAIT+B,EAAK9I,KAAY,MAAIyE,EAAQyI,wBAA0B,SAAUqC,EAAW5R,GAC3E,aAAYA,GAAQuP,yBAA2B9C,GAAgBf,EACvD1L,EAAQuP,uBAAwBqC,GADxC,GAWDhG,KAOAD,MAEM7E,EAAQ0I,IAAMpB,EAAQ1L,KAAM+O,EAAI3B,qBAGrCS,GAAO,SAAUC,GAMhBA,EAAIuB,UAAY,iDAIVvB,EAAIV,iBAAiB,cAAc3N,QACxCwJ,EAAUvM,KAAM,MAAQ2N,EAAa,aAAeD,EAAW,KAM1D0D,EAAIV,iBAAiB,YAAY3N,QACtCwJ,EAAUvM,KAAK,cAIjBmR,GAAO,SAAUC,GAOhB,GAAI+B,GAAQd,EAAIjK,cAAc,QAC9B+K,GAAM5C,aAAc,OAAQ,UAC5Ba,EAAIqB,YAAaU,GAAQ5C,aAAc,IAAK,IAEvCa,EAAIV,iBAAiB,WAAW3N,QACpCwJ,EAAUvM,KAAM,SAAW2N,EAAa,gBAKnCyD,EAAIV,iBAAiB,YAAY3N,QACtCwJ,EAAUvM,KAAM,WAAY,aAI7BoR,EAAIV,iBAAiB,QACrBnE,EAAUvM,KAAK,YAIX0H,EAAQ0L,gBAAkBpE,EAAQ1L,KAAOmJ,EAAUrN,EAAQiU,uBAChEjU,EAAQkU,oBACRlU,EAAQmU,kBACRnU,EAAQoU,qBAERrC,GAAO,SAAUC,GAGhB1J,EAAQ+L,kBAAoBhH,EAAQ1I,KAAMqN,EAAK,OAI/C3E,EAAQ1I,KAAMqN,EAAK,aACnB5E,EAAcxM,KAAM,KAAM+N,KAI5BxB,EAAYA,EAAUxJ,QAAciL,OAAQzB,EAAUkE,KAAK,MAC3DjE,EAAgBA,EAAczJ,QAAciL,OAAQxB,EAAciE,KAAK,MAQvE/D,EAAWsC,EAAQ1L,KAAMlE,EAAQsN,WAActN,EAAQsU,wBACtD,SAAUvG,EAAGC,GACZ,GAAIuG,GAAuB,IAAfxG,EAAE/J,SAAiB+J,EAAE9N,gBAAkB8N,EAClDyG,EAAMxG,GAAKA,EAAEzJ,UACd,OAAOwJ,KAAMyG,MAAWA,GAAwB,IAAjBA,EAAIxQ,YAClCuQ,EAAMjH,SACLiH,EAAMjH,SAAUkH,GAChBzG,EAAEuG,yBAA8D,GAAnCvG,EAAEuG,wBAAyBE,MAG3D,SAAUzG,EAAGC,GACZ,GAAKA,EACJ,MAASA,EAAIA,EAAEzJ,WACd,GAAKyJ,IAAMD,EACV,OAAO,CAIV,QAAO,GAOTD,EAAY9N,EAAQsU,wBACpB,SAAUvG,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGR,IAAI4G,GAAUzG,EAAEsG,yBAA2BvG,EAAEuG,yBAA2BvG,EAAEuG,wBAAyBtG,EAEnG,OAAKyG,GAEW,EAAVA,IACFnM,EAAQoM,cAAgB1G,EAAEsG,wBAAyBvG,KAAQ0G,EAGxD1G,IAAMkF,GAAO3F,EAASC,EAAcQ,GACjC,GAEHC,IAAMiF,GAAO3F,EAASC,EAAcS,GACjC,EAIDhB,EACJhM,EAAQ2D,KAAMqI,EAAWe,GAAM/M,EAAQ2D,KAAMqI,EAAWgB,GAC1D,EAGe,EAAVyG,EAAc,GAAK,EAIpB1G,EAAEuG,wBAA0B,GAAK,GAEzC,SAAUvG,EAAGC,GACZ,GAAIuE,GACH3M,EAAI,EACJ+O,EAAM5G,EAAExJ,WACRiQ,EAAMxG,EAAEzJ,WACRqQ,GAAO7G,GACP8G,GAAO7G,EAGR,IAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGD,KAAM8G,IAAQH,EACpB,MAAOzG,KAAMkF,EAAM,GAClBjF,IAAMiF,EAAM,EACZ0B,EAAM,GACNH,EAAM,EACNxH,EACEhM,EAAQ2D,KAAMqI,EAAWe,GAAM/M,EAAQ2D,KAAMqI,EAAWgB,GAC1D,CAGK,IAAK2G,IAAQH,EACnB,MAAOlC,IAAcvE,EAAGC,EAIzBuE,GAAMxE,CACN,OAASwE,EAAMA,EAAIhO,WAClBqQ,EAAGE,QAASvC,EAEbA,GAAMvE,CACN,OAASuE,EAAMA,EAAIhO,WAClBsQ,EAAGC,QAASvC,EAIb,OAAQqC,EAAGhP,KAAOiP,EAAGjP,GACpBA,GAGD,OAAOA,GAEN0M,GAAcsC,EAAGhP,GAAIiP,EAAGjP,IAGxBgP,EAAGhP,KAAO2H,EAAe,GACzBsH,EAAGjP,KAAO2H,EAAe,EACzB,GAGK0F,GA1UClT,GA6UTyQ,GAAOnD,QAAU,SAAU0H,EAAMC,GAChC,MAAOxE,IAAQuE,EAAM,KAAM,KAAMC,IAGlCxE,GAAOwD,gBAAkB,SAAUxQ,EAAMuR,GASxC,IAPOvR,EAAKS,eAAiBT,KAAWzD,GACvCkN,EAAazJ,GAIduR,EAAOA,EAAK/N,QAASgI,EAAkB,aAElC1G,EAAQ0L,kBAAmB9G,GAC5BE,GAAkBA,EAAclJ,KAAM6Q,IACtC5H,GAAkBA,EAAUjJ,KAAM6Q,IAErC,IACC,GAAI/P,GAAMqI,EAAQ1I,KAAMnB,EAAMuR,EAG9B,IAAK/P,GAAOsD,EAAQ+L,mBAGlB7Q,EAAKzD,UAAuC,KAA3ByD,EAAKzD,SAASiE,SAChC,MAAOgB,GAEP,MAAMqD,IAGT,MAAOmI,IAAQuE,EAAMhV,EAAU,MAAOyD,IAAQG,OAAS,GAGxD6M,GAAOlD,SAAW,SAAU9L,EAASgC,GAKpC,OAHOhC,EAAQyC,eAAiBzC,KAAczB,GAC7CkN,EAAazL,GAEP8L,EAAU9L,EAASgC,IAG3BgN,GAAOnM,KAAO,SAAUb,EAAM+C,IAEtB/C,EAAKS,eAAiBT,KAAWzD,GACvCkN,EAAazJ,EAGd,IAAI/B,GAAKkL,EAAK0F,WAAY9L,EAAKgE,eAE9B0K,EAAMxT,GAAM0M,EAAOxJ,KAAMgI,EAAK0F,WAAY9L,EAAKgE,eAC9C9I,EAAI+B,EAAM+C,GAAO2G,GACjBxN,CAEF,OAAOuV,KAAQvV,EACd4I,EAAQoG,aAAexB,EACtB1J,EAAK0N,aAAc3K,IAClB0O,EAAMzR,EAAKqQ,iBAAiBtN,KAAU0O,EAAIC,UAC1CD,EAAIzK,MACJ,KACFyK,GAGFzE,GAAO/H,MAAQ,SAAUC,GACxB,KAAUC,OAAO,0CAA4CD,IAO9D8H,GAAO2E,WAAa,SAAUvK,GAC7B,GAAIpH,GACH4R,KACAtP,EAAI,EACJF,EAAI,CAOL,IAJAiI,GAAgBvF,EAAQ+M,iBACxBrI,GAAa1E,EAAQgN,YAAc1K,EAAQ9J,MAAO,GAClD8J,EAAQ3E,KAAM6H,GAETD,EAAe,CACnB,MAASrK,EAAOoH,EAAQhF,KAClBpC,IAASoH,EAAShF,KACtBE,EAAIsP,EAAWxU,KAAMgF,GAGvB,OAAQE,IACP8E,EAAQ1E,OAAQkP,EAAYtP,GAAK,GAInC,MAAO8E,IAORgC,EAAU4D,GAAO5D,QAAU,SAAUpJ,GACpC,GAAIwP,GACHhO,EAAM,GACNY,EAAI,EACJ5B,EAAWR,EAAKQ,QAEjB,IAAMA,GAMC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAGjE,GAAiC,gBAArBR,GAAK+R,YAChB,MAAO/R,GAAK+R,WAGZ,KAAM/R,EAAOA,EAAKgQ,WAAYhQ,EAAMA,EAAOA,EAAKkP,YAC/C1N,GAAO4H,EAASpJ,OAGZ,IAAkB,IAAbQ,GAA+B,IAAbA,EAC7B,MAAOR,GAAKgS,cAhBZ,MAASxC,EAAOxP,EAAKoC,GAAKA,IAEzBZ,GAAO4H,EAASoG,EAkBlB,OAAOhO,IAGR2H,EAAO6D,GAAOiF,WAGb7D,YAAa,GAEb8D,aAAc5D,GAEdvO,MAAO4L,EAEPkD,cAEAxO,QAEA8R,UACCC,KAAOC,IAAK,aAAcpQ,OAAO,GACjCqQ,KAAOD,IAAK,cACZE,KAAOF,IAAK,kBAAmBpQ,OAAO,GACtCuQ,KAAOH,IAAK,oBAGbI,WACC1G,KAAQ,SAAUhM,GAUjB,MATAA,GAAM,GAAKA,EAAM,GAAGyD,QAASgJ,GAAWC,IAGxC1M,EAAM,IAAOA,EAAM,IAAMA,EAAM,IAAM,IAAKyD,QAASgJ,GAAWC,IAE5C,OAAb1M,EAAM,KACVA,EAAM,GAAK,IAAMA,EAAM,GAAK,KAGtBA,EAAMzC,MAAO,EAAG,IAGxB2O,MAAS,SAAUlM,GA6BlB,MAlBAA,GAAM,GAAKA,EAAM,GAAGgH,cAEY,QAA3BhH,EAAM,GAAGzC,MAAO,EAAG,IAEjByC,EAAM,IACXiN,GAAO/H,MAAOlF,EAAM,IAKrBA,EAAM,KAAQA,EAAM,GAAKA,EAAM,IAAMA,EAAM,IAAM,GAAK,GAAmB,SAAbA,EAAM,IAA8B,QAAbA,EAAM,KACzFA,EAAM,KAAUA,EAAM,GAAKA,EAAM,IAAqB,QAAbA,EAAM,KAGpCA,EAAM,IACjBiN,GAAO/H,MAAOlF,EAAM,IAGdA,GAGRiM,OAAU,SAAUjM,GACnB,GAAI2S,GACHC,GAAY5S,EAAM,IAAMA,EAAM,EAE/B,OAAK4L,GAAiB,MAAEjL,KAAMX,EAAM,IAC5B,MAIHA,EAAM,IAAMA,EAAM,KAAO7D,EAC7B6D,EAAM,GAAKA,EAAM,GAGN4S,GAAYlH,EAAQ/K,KAAMiS,KAEpCD,EAASjF,GAAUkF,GAAU,MAE7BD,EAASC,EAASnV,QAAS,IAAKmV,EAASxS,OAASuS,GAAWC,EAASxS,UAGvEJ,EAAM,GAAKA,EAAM,GAAGzC,MAAO,EAAGoV,GAC9B3S,EAAM,GAAK4S,EAASrV,MAAO,EAAGoV,IAIxB3S,EAAMzC,MAAO,EAAG,MAIzB6S,QAECrE,IAAO,SAAU8G,GAChB,GAAI9L,GAAW8L,EAAiBpP,QAASgJ,GAAWC,IAAY1F,aAChE,OAA4B,MAArB6L,EACN,WAAa,OAAO,GACpB,SAAU5S,GACT,MAAOA,GAAK8G,UAAY9G,EAAK8G,SAASC,gBAAkBD,IAI3D+E,MAAS,SAAU+D,GAClB,GAAIiD,GAAU5I,EAAY2F,EAAY,IAEtC,OAAOiD,KACLA,EAAczH,OAAQ,MAAQL,EAAa,IAAM6E,EAAY,IAAM7E,EAAa,SACjFd,EAAY2F,EAAW,SAAU5P,GAChC,MAAO6S,GAAQnS,KAAgC,gBAAnBV,GAAK4P,WAA0B5P,EAAK4P,iBAAoB5P,GAAK0N,eAAiBjD,GAAgBzK,EAAK0N,aAAa,UAAY,OAI3J3B,KAAQ,SAAUhJ,EAAM+P,EAAUC,GACjC,MAAO,UAAU/S,GAChB,GAAIgT,GAAShG,GAAOnM,KAAMb,EAAM+C,EAEhC,OAAe,OAAViQ,EACgB,OAAbF,EAEFA,GAINE,GAAU,GAEU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAOxV,QAASuV,GAChC,OAAbD,EAAoBC,GAASC,EAAOxV,QAASuV,GAAU,GAC1C,OAAbD,EAAoBC,GAASC,EAAO1V,OAAQyV,EAAM5S,UAAa4S,EAClD,OAAbD,GAAsB,IAAME,EAAS,KAAMxV,QAASuV,GAAU,GACjD,OAAbD,EAAoBE,IAAWD,GAASC,EAAO1V,MAAO,EAAGyV,EAAM5S,OAAS,KAAQ4S,EAAQ,KACxF,IAZO,IAgBV9G,MAAS,SAAU3M,EAAM2T,EAAM3D,EAAUrN,EAAOE,GAC/C,GAAI+Q,GAAgC,QAAvB5T,EAAKhC,MAAO,EAAG,GAC3B6V,EAA+B,SAArB7T,EAAKhC,MAAO,IACtB8V,EAAkB,YAATH,CAEV,OAAiB,KAAVhR,GAAwB,IAATE,EAGrB,SAAUnC,GACT,QAASA,EAAKe,YAGf,SAAUf,EAAMhC,EAASiI,GACxB,GAAIkI,GAAOkF,EAAY7D,EAAMR,EAAMsE,EAAWC,EAC7ClB,EAAMa,IAAWC,EAAU,cAAgB,kBAC3CzD,EAAS1P,EAAKe,WACdgC,EAAOqQ,GAAUpT,EAAK8G,SAASC,cAC/ByM,GAAYvN,IAAQmN,CAErB,IAAK1D,EAAS,CAGb,GAAKwD,EAAS,CACb,MAAQb,EAAM,CACb7C,EAAOxP,CACP,OAASwP,EAAOA,EAAM6C,GACrB,GAAKe,EAAS5D,EAAK1I,SAASC,gBAAkBhE,EAAyB,IAAlByM,EAAKhP,SACzD,OAAO,CAIT+S,GAAQlB,EAAe,SAAT/S,IAAoBiU,GAAS,cAE5C,OAAO,EAMR,GAHAA,GAAUJ,EAAUzD,EAAOM,WAAaN,EAAO+D,WAG1CN,GAAWK,EAAW,CAE1BH,EAAa3D,EAAQrM,KAAcqM,EAAQrM,OAC3C8K,EAAQkF,EAAY/T,OACpBgU,EAAYnF,EAAM,KAAOnE,GAAWmE,EAAM,GAC1Ca,EAAOb,EAAM,KAAOnE,GAAWmE,EAAM,GACrCqB,EAAO8D,GAAa5D,EAAO/J,WAAY2N,EAEvC,OAAS9D,IAAS8D,GAAa9D,GAAQA,EAAM6C,KAG3CrD,EAAOsE,EAAY,IAAMC,EAAM3I,MAGhC,GAAuB,IAAlB4E,EAAKhP,YAAoBwO,GAAQQ,IAASxP,EAAO,CACrDqT,EAAY/T,IAAW0K,EAASsJ,EAAWtE,EAC3C,YAKI,IAAKwE,IAAarF,GAASnO,EAAMqD,KAAcrD,EAAMqD,QAAkB/D,KAAW6O,EAAM,KAAOnE,EACrGgF,EAAOb,EAAM,OAKb,OAASqB,IAAS8D,GAAa9D,GAAQA,EAAM6C,KAC3CrD,EAAOsE,EAAY,IAAMC,EAAM3I,MAEhC,IAAOwI,EAAS5D,EAAK1I,SAASC,gBAAkBhE,EAAyB,IAAlByM,EAAKhP,aAAsBwO,IAE5EwE,KACHhE,EAAMnM,KAAcmM,EAAMnM,QAAkB/D,IAAW0K,EAASgF,IAG7DQ,IAASxP,GACb,KAQJ,OADAgP,IAAQ7M,EACD6M,IAAS/M,GAA4B,IAAjB+M,EAAO/M,GAAe+M,EAAO/M,GAAS,KAKrE+J,OAAU,SAAU0H,EAAQpE,GAK3B,GAAI1N,GACH3D,EAAKkL,EAAKgC,QAASuI,IAAYvK,EAAKwK,WAAYD,EAAO3M,gBACtDiG,GAAO/H,MAAO,uBAAyByO,EAKzC,OAAKzV,GAAIoF,GACDpF,EAAIqR,GAIPrR,EAAGkC,OAAS,GAChByB,GAAS8R,EAAQA,EAAQ,GAAIpE,GACtBnG,EAAKwK,WAAW/V,eAAgB8V,EAAO3M,eAC7CuH,GAAa,SAAUrB,EAAMpD,GAC5B,GAAI+J,GACHC,EAAU5V,EAAIgP,EAAMqC,GACpBlN,EAAIyR,EAAQ1T,MACb,OAAQiC,IACPwR,EAAMpW,EAAQ2D,KAAM8L,EAAM4G,EAAQzR,IAClC6K,EAAM2G,KAAW/J,EAAS+J,GAAQC,EAAQzR,MAG5C,SAAUpC,GACT,MAAO/B,GAAI+B,EAAM,EAAG4B,KAIhB3D,IAITkN,SAEC2I,IAAOxF,GAAa,SAAUvQ,GAI7B,GAAIwS,MACHnJ,KACA2M,EAAUzK,EAASvL,EAASyF,QAASlF,EAAO,MAE7C,OAAOyV,GAAS1Q,GACfiL,GAAa,SAAUrB,EAAMpD,EAAS7L,EAASiI,GAC9C,GAAIjG,GACHgU,EAAYD,EAAS9G,EAAM,KAAMhH,MACjC7D,EAAI6K,EAAK9M,MAGV,OAAQiC,KACDpC,EAAOgU,EAAU5R,MACtB6K,EAAK7K,KAAOyH,EAAQzH,GAAKpC,MAI5B,SAAUA,EAAMhC,EAASiI,GAGxB,MAFAsK,GAAM,GAAKvQ,EACX+T,EAASxD,EAAO,KAAMtK,EAAKmB,IACnBA,EAAQwD,SAInBqJ,IAAO3F,GAAa,SAAUvQ,GAC7B,MAAO,UAAUiC,GAChB,MAAOgN,IAAQjP,EAAUiC,GAAOG,OAAS,KAI3C2J,SAAYwE,GAAa,SAAUpH,GAClC,MAAO,UAAUlH,GAChB,OAASA,EAAK+R,aAAe/R,EAAKkU,WAAa9K,EAASpJ,IAASxC,QAAS0J,GAAS,MAWrFiN,KAAQ7F,GAAc,SAAU6F,GAM/B,MAJMzI,GAAYhL,KAAKyT,GAAQ,KAC9BnH,GAAO/H,MAAO,qBAAuBkP,GAEtCA,EAAOA,EAAK3Q,QAASgJ,GAAWC,IAAY1F,cACrC,SAAU/G,GAChB,GAAIoU,EACJ,GACC,IAAMA,EAAW1K,EAChB1J,EAAKmU,KACLnU,EAAK0N,aAAa,aAAe1N,EAAK0N,aAAa,QAGnD,MADA0G,GAAWA,EAASrN,cACbqN,IAAaD,GAA2C,IAAnCC,EAAS5W,QAAS2W,EAAO,YAE5CnU,EAAOA,EAAKe,aAAiC,IAAlBf,EAAKQ,SAC3C,QAAO,KAKT0C,OAAU,SAAUlD,GACnB,GAAIqU,GAAOpY,EAAOK,UAAYL,EAAOK,SAAS+X,IAC9C,OAAOA,IAAQA,EAAK/W,MAAO,KAAQ0C,EAAKgB,IAGzCsT,KAAQ,SAAUtU,GACjB,MAAOA,KAASxD,GAGjB+X,MAAS,SAAUvU,GAClB,MAAOA,KAASzD,EAASiY,iBAAmBjY,EAASkY,UAAYlY,EAASkY,gBAAkBzU,EAAKV,MAAQU,EAAK0U,OAAS1U,EAAK2U,WAI7HC,QAAW,SAAU5U,GACpB,MAAOA,GAAK6U,YAAa,GAG1BA,SAAY,SAAU7U,GACrB,MAAOA,GAAK6U,YAAa,GAG1BC,QAAW,SAAU9U,GAGpB,GAAI8G,GAAW9G,EAAK8G,SAASC,aAC7B,OAAqB,UAAbD,KAA0B9G,EAAK8U,SAA0B,WAAbhO,KAA2B9G,EAAK+U,UAGrFA,SAAY,SAAU/U,GAOrB,MAJKA,GAAKe,YACTf,EAAKe,WAAWiU,cAGVhV,EAAK+U,YAAa,GAI1BE,MAAS,SAAUjV,GAMlB,IAAMA,EAAOA,EAAKgQ,WAAYhQ,EAAMA,EAAOA,EAAKkP,YAC/C,GAAKlP,EAAK8G,SAAW,KAAyB,IAAlB9G,EAAKQ,UAAoC,IAAlBR,EAAKQ,SACvD,OAAO,CAGT,QAAO,GAGRkP,OAAU,SAAU1P,GACnB,OAAQmJ,EAAKgC,QAAe,MAAGnL,IAIhCkV,OAAU,SAAUlV,GACnB,MAAOsM,IAAQ5L,KAAMV,EAAK8G,WAG3ByJ,MAAS,SAAUvQ,GAClB,MAAOqM,IAAQ3L,KAAMV,EAAK8G,WAG3BqO,OAAU,SAAUnV,GACnB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,OAAgB,UAAThE,GAAkC,WAAd/C,EAAKV,MAA8B,WAATyD,GAGtDmE,KAAQ,SAAUlH,GACjB,GAAIa,EAGJ,OAAuC,UAAhCb,EAAK8G,SAASC,eACN,SAAd/G,EAAKV,OACmC,OAArCuB,EAAOb,EAAK0N,aAAa,UAAoB7M,EAAKkG,gBAAkB/G,EAAKV,OAI9E2C,MAASoN,GAAuB,WAC/B,OAAS,KAGVlN,KAAQkN,GAAuB,SAAUE,EAAcpP,GACtD,OAASA,EAAS,KAGnB+B,GAAMmN,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,OAAoB,EAAXA,EAAeA,EAAWnP,EAASmP,KAG7C8F,KAAQ/F,GAAuB,SAAUE,EAAcpP,GACtD,GAAIiC,GAAI,CACR,MAAYjC,EAAJiC,EAAYA,GAAK,EACxBmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGR8F,IAAOhG,GAAuB,SAAUE,EAAcpP,GACrD,GAAIiC,GAAI,CACR,MAAYjC,EAAJiC,EAAYA,GAAK,EACxBmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGR+F,GAAMjG,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,GAAIlN,GAAe,EAAXkN,EAAeA,EAAWnP,EAASmP,CAC3C,QAAUlN,GAAK,GACdmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGRgG,GAAMlG,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,GAAIlN,GAAe,EAAXkN,EAAeA,EAAWnP,EAASmP,CAC3C,MAAcnP,IAAJiC,GACTmN,EAAanS,KAAMgF,EAEpB,OAAOmN,OAKVpG,EAAKgC,QAAa,IAAIhC,EAAKgC,QAAY,EAGvC,KAAM/I,KAAOoT,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5EzM,EAAKgC,QAAS/I,GAAM+M,GAAmB/M,EAExC,KAAMA,KAAOyT,QAAQ,EAAMC,OAAO,GACjC3M,EAAKgC,QAAS/I,GAAMgN,GAAoBhN,EAIzC,SAASuR,OACTA,GAAW/T,UAAYuJ,EAAK4M,QAAU5M,EAAKgC,QAC3ChC,EAAKwK,WAAa,GAAIA,GAEtB,SAASlG,IAAU1P,EAAUiY,GAC5B,GAAInC,GAAS9T,EAAOkW,EAAQ3W,EAC3B4W,EAAO/I,EAAQgJ,EACfC,EAASjM,EAAYpM,EAAW,IAEjC,IAAKqY,EACJ,MAAOJ,GAAY,EAAII,EAAO9Y,MAAO,EAGtC4Y,GAAQnY,EACRoP,KACAgJ,EAAahN,EAAKsJ,SAElB,OAAQyD,EAAQ,GAGTrC,IAAY9T,EAAQsL,EAAOjL,KAAM8V,OACjCnW,IAEJmW,EAAQA,EAAM5Y,MAAOyC,EAAM,GAAGI,SAAY+V,GAE3C/I,EAAO/P,KAAM6Y,OAGdpC,GAAU,GAGJ9T,EAAQuL,EAAalL,KAAM8V,MAChCrC,EAAU9T,EAAMsO,QAChB4H,EAAO7Y,MACN4J,MAAO6M,EAEPvU,KAAMS,EAAM,GAAGyD,QAASlF,EAAO,OAEhC4X,EAAQA,EAAM5Y,MAAOuW,EAAQ1T,QAI9B,KAAMb,IAAQ6J,GAAKgH,SACZpQ,EAAQ4L,EAAWrM,GAAOc,KAAM8V,KAAcC,EAAY7W,MAC9DS,EAAQoW,EAAY7W,GAAQS,MAC7B8T,EAAU9T,EAAMsO,QAChB4H,EAAO7Y,MACN4J,MAAO6M,EACPvU,KAAMA,EACNuK,QAAS9J,IAEVmW,EAAQA,EAAM5Y,MAAOuW,EAAQ1T,QAI/B,KAAM0T,EACL,MAOF,MAAOmC,GACNE,EAAM/V,OACN+V,EACClJ,GAAO/H,MAAOlH,GAEdoM,EAAYpM,EAAUoP,GAAS7P,MAAO,GAGzC,QAASsQ,IAAYqI,GACpB,GAAI7T,GAAI,EACPC,EAAM4T,EAAO9V,OACbpC,EAAW,EACZ,MAAYsE,EAAJD,EAASA,IAChBrE,GAAYkY,EAAO7T,GAAG4E,KAEvB,OAAOjJ,GAGR,QAASsY,IAAetC,EAASuC,EAAYC,GAC5C,GAAIlE,GAAMiE,EAAWjE,IACpBmE,EAAmBD,GAAgB,eAARlE,EAC3BoE,EAAW3U,GAEZ,OAAOwU,GAAWrU,MAEjB,SAAUjC,EAAMhC,EAASiI,GACxB,MAASjG,EAAOA,EAAMqS,GACrB,GAAuB,IAAlBrS,EAAKQ,UAAkBgW,EAC3B,MAAOzC,GAAS/T,EAAMhC,EAASiI,IAMlC,SAAUjG,EAAMhC,EAASiI,GACxB,GAAIb,GAAM+I,EAAOkF,EAChBqD,EAAS1M,EAAU,IAAMyM,CAG1B,IAAKxQ,GACJ,MAASjG,EAAOA,EAAMqS,GACrB,IAAuB,IAAlBrS,EAAKQ,UAAkBgW,IACtBzC,EAAS/T,EAAMhC,EAASiI,GAC5B,OAAO,MAKV,OAASjG,EAAOA,EAAMqS,GACrB,GAAuB,IAAlBrS,EAAKQ,UAAkBgW,EAE3B,GADAnD,EAAarT,EAAMqD,KAAcrD,EAAMqD,QACjC8K,EAAQkF,EAAYhB,KAAUlE,EAAM,KAAOuI,GAChD,IAAMtR,EAAO+I,EAAM,OAAQ,GAAQ/I,IAAS8D,EAC3C,MAAO9D,MAAS,MAKjB,IAFA+I,EAAQkF,EAAYhB,IAAUqE,GAC9BvI,EAAM,GAAK4F,EAAS/T,EAAMhC,EAASiI,IAASiD,EACvCiF,EAAM,MAAO,EACjB,OAAO,GASf,QAASwI,IAAgBC,GACxB,MAAOA,GAASzW,OAAS,EACxB,SAAUH,EAAMhC,EAASiI,GACxB,GAAI7D,GAAIwU,EAASzW,MACjB,OAAQiC,IACP,IAAMwU,EAASxU,GAAIpC,EAAMhC,EAASiI,GACjC,OAAO,CAGT,QAAO,GAER2Q,EAAS,GAGX,QAASC,IAAU7C,EAAWzR,EAAK4N,EAAQnS,EAASiI,GACnD,GAAIjG,GACH8W,KACA1U,EAAI,EACJC,EAAM2R,EAAU7T,OAChB4W,EAAgB,MAAPxU,CAEV,MAAYF,EAAJD,EAASA,KACVpC,EAAOgU,EAAU5R,OAChB+N,GAAUA,EAAQnQ,EAAMhC,EAASiI,MACtC6Q,EAAa1Z,KAAM4C,GACd+W,GACJxU,EAAInF,KAAMgF,GAMd,OAAO0U,GAGR,QAASE,IAAYvE,EAAW1U,EAAUgW,EAASkD,EAAYC,EAAYC,GAO1E,MANKF,KAAeA,EAAY5T,KAC/B4T,EAAaD,GAAYC,IAErBC,IAAeA,EAAY7T,KAC/B6T,EAAaF,GAAYE,EAAYC,IAE/B7I,GAAa,SAAUrB,EAAM7F,EAASpJ,EAASiI,GACrD,GAAImR,GAAMhV,EAAGpC,EACZqX,KACAC,KACAC,EAAcnQ,EAAQjH,OAGtBoB,EAAQ0L,GAAQuK,GAAkBzZ,GAAY,IAAKC,EAAQwC,UAAaxC,GAAYA,MAGpFyZ,GAAYhF,IAAexF,GAASlP,EAEnCwD,EADAsV,GAAUtV,EAAO8V,EAAQ5E,EAAWzU,EAASiI,GAG9CyR,EAAa3D,EAEZmD,IAAgBjK,EAAOwF,EAAY8E,GAAeN,MAMjD7P,EACDqQ,CAQF,IALK1D,GACJA,EAAS0D,EAAWC,EAAY1Z,EAASiI,GAIrCgR,EAAa,CACjBG,EAAOP,GAAUa,EAAYJ,GAC7BL,EAAYG,KAAUpZ,EAASiI,GAG/B7D,EAAIgV,EAAKjX,MACT,OAAQiC,KACDpC,EAAOoX,EAAKhV,MACjBsV,EAAYJ,EAAQlV,MAASqV,EAAWH,EAAQlV,IAAOpC,IAK1D,GAAKiN,GACJ,GAAKiK,GAAczE,EAAY,CAC9B,GAAKyE,EAAa,CAEjBE,KACAhV,EAAIsV,EAAWvX,MACf,OAAQiC,KACDpC,EAAO0X,EAAWtV,KAEvBgV,EAAKha,KAAOqa,EAAUrV,GAAKpC,EAG7BkX,GAAY,KAAOQ,KAAkBN,EAAMnR,GAI5C7D,EAAIsV,EAAWvX,MACf,OAAQiC,KACDpC,EAAO0X,EAAWtV,MACtBgV,EAAOF,EAAa1Z,EAAQ2D,KAAM8L,EAAMjN,GAASqX,EAAOjV,IAAM,KAE/D6K,EAAKmK,KAAUhQ,EAAQgQ,GAAQpX,SAOlC0X,GAAab,GACZa,IAAetQ,EACdsQ,EAAWhV,OAAQ6U,EAAaG,EAAWvX,QAC3CuX,GAEGR,EACJA,EAAY,KAAM9P,EAASsQ,EAAYzR,GAEvC7I,EAAK2E,MAAOqF,EAASsQ,KAMzB,QAASC,IAAmB1B,GAC3B,GAAI2B,GAAc7D,EAASzR,EAC1BD,EAAM4T,EAAO9V,OACb0X,EAAkB1O,EAAKgJ,SAAU8D,EAAO,GAAG3W,MAC3CwY,EAAmBD,GAAmB1O,EAAKgJ,SAAS,KACpD/P,EAAIyV,EAAkB,EAAI,EAG1BE,EAAe1B,GAAe,SAAUrW,GACvC,MAAOA,KAAS4X,GACdE,GAAkB,GACrBE,EAAkB3B,GAAe,SAAUrW,GAC1C,MAAOxC,GAAQ2D,KAAMyW,EAAc5X,GAAS,IAC1C8X,GAAkB,GACrBlB,GAAa,SAAU5W,EAAMhC,EAASiI,GACrC,OAAU4R,IAAqB5R,GAAOjI,IAAYuL,MAChDqO,EAAe5Z,GAASwC,SACxBuX,EAAc/X,EAAMhC,EAASiI,GAC7B+R,EAAiBhY,EAAMhC,EAASiI,KAGpC,MAAY5D,EAAJD,EAASA,IAChB,GAAM2R,EAAU5K,EAAKgJ,SAAU8D,EAAO7T,GAAG9C,MACxCsX,GAAaP,GAAcM,GAAgBC,GAAY7C,QACjD,CAIN,GAHAA,EAAU5K,EAAKgH,OAAQ8F,EAAO7T,GAAG9C,MAAOyC,MAAO,KAAMkU,EAAO7T,GAAGyH,SAG1DkK,EAAS1Q,GAAY,CAGzB,IADAf,IAAMF,EACMC,EAAJC,EAASA,IAChB,GAAK6G,EAAKgJ,SAAU8D,EAAO3T,GAAGhD,MAC7B,KAGF,OAAO0X,IACN5U,EAAI,GAAKuU,GAAgBC,GACzBxU,EAAI,GAAKwL,GAERqI,EAAO3Y,MAAO,EAAG8E,EAAI,GAAIlF,QAAS8J,MAAgC,MAAzBiP,EAAQ7T,EAAI,GAAI9C,KAAe,IAAM,MAC7EkE,QAASlF,EAAO,MAClByV,EACIzR,EAAJF,GAASuV,GAAmB1B,EAAO3Y,MAAO8E,EAAGE,IACzCD,EAAJC,GAAWqV,GAAoB1B,EAASA,EAAO3Y,MAAOgF,IAClDD,EAAJC,GAAWsL,GAAYqI,IAGzBW,EAASxZ,KAAM2W,GAIjB,MAAO4C,IAAgBC,GAGxB,QAASqB,IAA0BC,EAAiBC,GAEnD,GAAIC,GAAoB,EACvBC,EAAQF,EAAYhY,OAAS,EAC7BmY,EAAYJ,EAAgB/X,OAAS,EACrCoY,EAAe,SAAUtL,EAAMjP,EAASiI,EAAKmB,EAASoR,GACrD,GAAIxY,GAAMsC,EAAGyR,EACZ0E,KACAC,EAAe,EACftW,EAAI,IACJ4R,EAAY/G,MACZ0L,EAA6B,MAAjBH,EACZI,EAAgBrP,EAEhBhI,EAAQ0L,GAAQqL,GAAanP,EAAK9I,KAAU,IAAG,IAAKmY,GAAiBxa,EAAQ+C,YAAc/C,GAE3F6a,EAAiB7O,GAA4B,MAAjB4O,EAAwB,EAAItV,KAAKC,UAAY,EAS1E,KAPKoV,IACJpP,EAAmBvL,IAAYzB,GAAYyB,EAC3CkL,EAAakP,GAKe,OAApBpY,EAAOuB,EAAMa,IAAaA,IAAM,CACxC,GAAKkW,GAAatY,EAAO,CACxBsC,EAAI,CACJ,OAASyR,EAAUmE,EAAgB5V,KAClC,GAAKyR,EAAS/T,EAAMhC,EAASiI,GAAQ,CACpCmB,EAAQhK,KAAM4C,EACd,OAGG2Y,IACJ3O,EAAU6O,EACV3P,IAAekP,GAKZC,KAEErY,GAAQ+T,GAAW/T,IACxB0Y,IAIIzL,GACJ+G,EAAU5W,KAAM4C,IAOnB,GADA0Y,GAAgBtW,EACXiW,GAASjW,IAAMsW,EAAe,CAClCpW,EAAI,CACJ,OAASyR,EAAUoE,EAAY7V,KAC9ByR,EAASC,EAAWyE,EAAYza,EAASiI,EAG1C,IAAKgH,EAAO,CAEX,GAAKyL,EAAe,EACnB,MAAQtW,IACA4R,EAAU5R,IAAMqW,EAAWrW,KACjCqW,EAAWrW,GAAKwI,EAAIzJ,KAAMiG,GAM7BqR,GAAa5B,GAAU4B,GAIxBrb,EAAK2E,MAAOqF,EAASqR,GAGhBE,IAAc1L,GAAQwL,EAAWtY,OAAS,GAC5CuY,EAAeP,EAAYhY,OAAW,GAExC6M,GAAO2E,WAAYvK,GAUrB,MALKuR,KACJ3O,EAAU6O,EACVtP,EAAmBqP,GAGb5E,EAGT,OAAOqE,GACN/J,GAAciK,GACdA,EAGFjP,EAAU0D,GAAO1D,QAAU,SAAUvL,EAAU+a,GAC9C,GAAI1W,GACH+V,KACAD,KACA9B,EAAShM,EAAerM,EAAW,IAEpC,KAAMqY,EAAS,CAER0C,IACLA,EAAQrL,GAAU1P,IAEnBqE,EAAI0W,EAAM3Y,MACV,OAAQiC,IACPgU,EAASuB,GAAmBmB,EAAM1W,IAC7BgU,EAAQ/S,GACZ8U,EAAY/a,KAAMgZ,GAElB8B,EAAgB9a,KAAMgZ,EAKxBA,GAAShM,EAAerM,EAAUka,GAA0BC,EAAiBC,IAE9E,MAAO/B,GAGR,SAASoB,IAAkBzZ,EAAUgb,EAAU3R,GAC9C,GAAIhF,GAAI,EACPC,EAAM0W,EAAS5Y,MAChB,MAAYkC,EAAJD,EAASA,IAChB4K,GAAQjP,EAAUgb,EAAS3W,GAAIgF,EAEhC,OAAOA,GAGR,QAAS6G,IAAQlQ,EAAUC,EAASoJ,EAAS6F,GAC5C,GAAI7K,GAAG6T,EAAQ+C,EAAO1Z,EAAMe,EAC3BN,EAAQ0N,GAAU1P,EAEnB,KAAMkP,GAEiB,IAAjBlN,EAAMI,OAAe,CAIzB,GADA8V,EAASlW,EAAM,GAAKA,EAAM,GAAGzC,MAAO,GAC/B2Y,EAAO9V,OAAS,GAAkC,QAA5B6Y,EAAQ/C,EAAO,IAAI3W,MAC5CwF,EAAQmL,SAAgC,IAArBjS,EAAQwC,UAAkBkJ,GAC7CP,EAAKgJ,SAAU8D,EAAO,GAAG3W,MAAS,CAGnC,GADAtB,GAAYmL,EAAK9I,KAAS,GAAG2Y,EAAMnP,QAAQ,GAAGrG,QAAQgJ,GAAWC,IAAYzO,QAAkB,IACzFA,EACL,MAAOoJ,EAERrJ,GAAWA,EAAST,MAAO2Y,EAAO5H,QAAQrH,MAAM7G,QAIjDiC,EAAIuJ,EAAwB,aAAEjL,KAAM3C,GAAa,EAAIkY,EAAO9V,MAC5D,OAAQiC,IAAM,CAIb,GAHA4W,EAAQ/C,EAAO7T,GAGV+G,EAAKgJ,SAAW7S,EAAO0Z,EAAM1Z,MACjC,KAED,KAAMe,EAAO8I,EAAK9I,KAAMf,MAEjB2N,EAAO5M,EACZ2Y,EAAMnP,QAAQ,GAAGrG,QAASgJ,GAAWC,IACrClB,EAAS7K,KAAMuV,EAAO,GAAG3W,OAAUtB,EAAQ+C,YAAc/C,IACrD,CAKJ,GAFAiY,EAAOvT,OAAQN,EAAG,GAClBrE,EAAWkP,EAAK9M,QAAUyN,GAAYqI,IAChClY,EAEL,MADAX,GAAK2E,MAAOqF,EAAS6F,GACd7F,CAGR,SAgBL,MAPAkC,GAASvL,EAAUgC,GAClBkN,EACAjP,GACC0L,EACDtC,EACAmE,EAAS7K,KAAM3C,IAETqJ,EAMRtC,EAAQgN,WAAazO,EAAQ4F,MAAM,IAAIxG,KAAM6H,GAAYuD,KAAK,MAAQxK,EAItEyB,EAAQ+M,iBAAmBxH,EAG3BZ,IAIA3E,EAAQoM,aAAe3C,GAAO,SAAU0K,GAEvC,MAAuE,GAAhEA,EAAKnI,wBAAyBvU,EAASiJ,cAAc,UAMvD+I,GAAO,SAAUC,GAEtB,MADAA,GAAIuB,UAAY,mBAC+B,MAAxCvB,EAAIwB,WAAWtC,aAAa,WAEnCgB,GAAW,yBAA0B,SAAU1O,EAAM+C,EAAMsG,GAC1D,MAAMA,GAAN,EACQrJ,EAAK0N,aAAc3K,EAA6B,SAAvBA,EAAKgE,cAA2B,EAAI,KAOjEjC,EAAQoG,YAAeqD,GAAO,SAAUC,GAG7C,MAFAA,GAAIuB,UAAY,WAChBvB,EAAIwB,WAAWrC,aAAc,QAAS,IACY,KAA3Ca,EAAIwB,WAAWtC,aAAc,YAEpCgB,GAAW,QAAS,SAAU1O,EAAM+C,EAAMsG,GACzC,MAAMA,IAAyC,UAAhCrJ,EAAK8G,SAASC,cAA7B,EACQ/G,EAAKkZ,eAOT3K,GAAO,SAAUC,GACtB,MAAuC,OAAhCA,EAAId,aAAa,eAExBgB,GAAW5D,EAAU,SAAU9K,EAAM+C,EAAMsG,GAC1C,GAAIoI,EACJ,OAAMpI,GAAN,GACSoI,EAAMzR,EAAKqQ,iBAAkBtN,KAAW0O,EAAIC,UACnDD,EAAIzK,MACJhH,EAAM+C,MAAW,EAAOA,EAAKgE,cAAgB,OAKjDpK,EAAO0D,KAAO2M,GACdrQ,EAAO4U,KAAOvE,GAAOiF,UACrBtV,EAAO4U,KAAK,KAAO5U,EAAO4U,KAAKpG,QAC/BxO,EAAOwc,OAASnM,GAAO2E,WACvBhV,EAAOuK,KAAO8F,GAAO5D,QACrBzM,EAAOyc,SAAWpM,GAAO3D,MACzB1M,EAAOmN,SAAWkD,GAAOlD,UAGrB7N,EAEJ,IAAIod,KAGJ,SAASC,GAAetW,GACvB,GAAIuW,GAASF,EAAcrW,KAI3B,OAHArG,GAAO+E,KAAMsB,EAAQjD,MAAO1B,OAAwB,SAAUqO,EAAG8M,GAChED,EAAQC,IAAS,IAEXD,EAyBR5c,EAAO8c,UAAY,SAAUzW,GAI5BA,EAA6B,gBAAZA,GACdqW,EAAcrW,IAAasW,EAAetW,GAC5CrG,EAAOgG,UAAYK,EAEpB,IACC0W,GAEAC,EAEAC,EAEAC,EAEAC,EAEAC,EAEAC,KAEAC,GAASjX,EAAQkX,SAEjBC,EAAO,SAAU/U,GAOhB,IANAuU,EAAS3W,EAAQ2W,QAAUvU,EAC3BwU,GAAQ,EACRE,EAAcC,GAAe,EAC7BA,EAAc,EACdF,EAAeG,EAAK7Z,OACpBuZ,GAAS,EACDM,GAAsBH,EAAdC,EAA4BA,IAC3C,GAAKE,EAAMF,GAAc/X,MAAOqD,EAAM,GAAKA,EAAM,OAAU,GAASpC,EAAQoX,YAAc,CACzFT,GAAS,CACT,OAGFD,GAAS,EACJM,IACCC,EACCA,EAAM9Z,QACVga,EAAMF,EAAM5L,SAEFsL,EACXK,KAEAK,EAAKC,YAKRD,GAECE,IAAK,WACJ,GAAKP,EAAO,CAEX,GAAIzG,GAAQyG,EAAK7Z,QACjB,QAAUoa,GAAK3Y,GACdjF,EAAO+E,KAAME,EAAM,SAAU8K,EAAG7E,GAC/B,GAAIvI,GAAO3C,EAAO2C,KAAMuI,EACV,cAATvI,EACE0D,EAAQmW,QAAWkB,EAAKpG,IAAKpM,IAClCmS,EAAK5c,KAAMyK,GAEDA,GAAOA,EAAI1H,QAAmB,WAATb,GAEhCib,EAAK1S,OAGJ7F,WAGC0X,EACJG,EAAeG,EAAK7Z,OAGTwZ,IACXI,EAAcxG,EACd4G,EAAMR,IAGR,MAAO1Z,OAGRyF,OAAQ,WAkBP,MAjBKsU,IACJrd,EAAO+E,KAAMM,UAAW,SAAU0K,EAAG7E,GACpC,GAAI2S,EACJ,QAASA,EAAQ7d,EAAO2K,QAASO,EAAKmS,EAAMQ,IAAY,GACvDR,EAAKtX,OAAQ8X,EAAO,GAEfd,IACUG,GAATW,GACJX,IAEaC,GAATU,GACJV,OAME7Z,MAIRgU,IAAK,SAAUhW,GACd,MAAOA,GAAKtB,EAAO2K,QAASrJ,EAAI+b,GAAS,MAASA,IAAQA,EAAK7Z,SAGhE8U,MAAO,WAGN,MAFA+E,MACAH,EAAe,EACR5Z,MAGRqa,QAAS,WAER,MADAN,GAAOC,EAAQN,EAASzd,EACjB+D,MAGR4U,SAAU,WACT,OAAQmF,GAGTS,KAAM,WAKL,MAJAR,GAAQ/d,EACFyd,GACLU,EAAKC,UAECra,MAGRya,OAAQ,WACP,OAAQT,GAGTU,SAAU,SAAU3c,EAAS4D,GAU5B,OATKoY,GAAWJ,IAASK,IACxBrY,EAAOA,MACPA,GAAS5D,EAAS4D,EAAKtE,MAAQsE,EAAKtE,QAAUsE,GACzC8X,EACJO,EAAM7c,KAAMwE,GAEZuY,EAAMvY,IAGD3B,MAGRka,KAAM,WAEL,MADAE,GAAKM,SAAU1a,KAAM+B,WACd/B,MAGR2Z,MAAO,WACN,QAASA,GAIZ,OAAOS,IAER1d,EAAOgG,QAENgG,SAAU,SAAUiS,GACnB,GAAIC,KAEA,UAAW,OAAQle,EAAO8c,UAAU,eAAgB,aACpD,SAAU,OAAQ9c,EAAO8c,UAAU,eAAgB,aACnD,SAAU,WAAY9c,EAAO8c,UAAU,YAE1CqB,EAAQ,UACRjZ,GACCiZ,MAAO,WACN,MAAOA,IAERC,OAAQ,WAEP,MADAC,GAASlZ,KAAME,WAAYiZ,KAAMjZ,WAC1B/B,MAERib,KAAM,WACL,GAAIC,GAAMnZ,SACV,OAAOrF,GAAOgM,SAAS,SAAUyS,GAChCze,EAAO+E,KAAMmZ,EAAQ,SAAUzY,EAAGiZ,GACjC,GAAIC,GAASD,EAAO,GACnBpd,EAAKtB,EAAOiE,WAAYua,EAAK/Y,KAAS+Y,EAAK/Y,EAE5C4Y,GAAUK,EAAM,IAAK,WACpB,GAAIE,GAAWtd,GAAMA,EAAG8D,MAAO9B,KAAM+B,UAChCuZ,IAAY5e,EAAOiE,WAAY2a,EAAS1Z,SAC5C0Z,EAAS1Z,UACPC,KAAMsZ,EAASI,SACfP,KAAMG,EAASK,QACfC,SAAUN,EAASO,QAErBP,EAAUE,EAAS,QAAUrb,OAAS4B,EAAUuZ,EAASvZ,UAAY5B,KAAMhC,GAAOsd,GAAavZ,eAIlGmZ,EAAM,OACJtZ,WAIJA,QAAS,SAAUuC,GAClB,MAAc,OAAPA,EAAczH,EAAOgG,OAAQyB,EAAKvC,GAAYA,IAGvDmZ,IAwCD,OArCAnZ,GAAQ+Z,KAAO/Z,EAAQqZ,KAGvBve,EAAO+E,KAAMmZ,EAAQ,SAAUzY,EAAGiZ,GACjC,GAAIrB,GAAOqB,EAAO,GACjBQ,EAAcR,EAAO,EAGtBxZ,GAASwZ,EAAM,IAAOrB,EAAKO,IAGtBsB,GACJ7B,EAAKO,IAAI,WAERO,EAAQe,GAGNhB,EAAY,EAAJzY,GAAS,GAAIkY,QAASO,EAAQ,GAAK,GAAIJ,MAInDO,EAAUK,EAAM,IAAO,WAEtB,MADAL,GAAUK,EAAM,GAAK,QAAUpb,OAAS+a,EAAWnZ,EAAU5B,KAAM+B,WAC5D/B,MAER+a,EAAUK,EAAM,GAAK,QAAWrB,EAAKW,WAItC9Y,EAAQA,QAASmZ,GAGZJ,GACJA,EAAKzZ,KAAM6Z,EAAUA,GAIfA,GAIRc,KAAM,SAAUC,GACf,GAAI3Z,GAAI,EACP4Z,EAAgB3e,EAAW8D,KAAMa,WACjC7B,EAAS6b,EAAc7b,OAGvB8b,EAAuB,IAAX9b,GAAkB4b,GAAepf,EAAOiE,WAAYmb,EAAYla,SAAc1B,EAAS,EAGnG6a,EAAyB,IAAdiB,EAAkBF,EAAcpf,EAAOgM,WAGlDuT,EAAa,SAAU9Z,EAAG2W,EAAUoD,GACnC,MAAO,UAAUnV,GAChB+R,EAAU3W,GAAMnC,KAChBkc,EAAQ/Z,GAAMJ,UAAU7B,OAAS,EAAI9C,EAAW8D,KAAMa,WAAcgF,EAChEmV,IAAWC,EACdpB,EAASqB,WAAYtD,EAAUoD,KACfF,GAChBjB,EAAS/W,YAAa8U,EAAUoD,KAKnCC,EAAgBE,EAAkBC,CAGnC,IAAKpc,EAAS,EAIb,IAHAic,EAAqB/X,MAAOlE,GAC5Bmc,EAAuBjY,MAAOlE,GAC9Boc,EAAsBlY,MAAOlE,GACjBA,EAAJiC,EAAYA,IACd4Z,EAAe5Z,IAAOzF,EAAOiE,WAAYob,EAAe5Z,GAAIP,SAChEma,EAAe5Z,GAAIP,UACjBC,KAAMoa,EAAY9Z,EAAGma,EAAiBP,IACtCf,KAAMD,EAASS,QACfC,SAAUQ,EAAY9Z,EAAGka,EAAkBF,MAE3CH,CAUL,OAJMA,IACLjB,EAAS/W,YAAasY,EAAiBP,GAGjChB,EAASnZ,aAGlBlF,EAAOmI,QAAU,SAAWA,GAE3B,GAAI9F,GAAKuL,EAAGgG,EAAOtC,EAAQuO,EAAUC,EAAKC,EAAWC,EAAava,EACjEoM,EAAMjS,EAASiJ,cAAc,MAS9B,IANAgJ,EAAIb,aAAc,YAAa,KAC/Ba,EAAIuB,UAAY,qEAGhB/Q,EAAMwP,EAAIhI,qBAAqB,SAC/B+D,EAAIiE,EAAIhI,qBAAqB,KAAM,IAC7B+D,IAAMA,EAAE7B,QAAU1J,EAAImB,OAC3B,MAAO2E,EAIRmJ,GAAS1R,EAASiJ,cAAc,UAChCiX,EAAMxO,EAAO4B,YAAatT,EAASiJ,cAAc,WACjD+K,EAAQ/B,EAAIhI,qBAAqB,SAAU,GAE3C+D,EAAE7B,MAAMkU,QAAU,gCAGlB9X,EAAQ+X,gBAAoC,MAAlBrO,EAAIoB,UAG9B9K,EAAQgY,kBAAgD,IAA5BtO,EAAIwB,WAAWxP,SAI3CsE,EAAQiY,OAASvO,EAAIhI,qBAAqB,SAASrG,OAInD2E,EAAQkY,gBAAkBxO,EAAIhI,qBAAqB,QAAQrG,OAI3D2E,EAAQ4D,MAAQ,MAAMhI,KAAM6J,EAAEmD,aAAa,UAI3C5I,EAAQmY,eAA4C,OAA3B1S,EAAEmD,aAAa,QAKxC5I,EAAQoY,QAAU,OAAOxc,KAAM6J,EAAE7B,MAAMwU,SAIvCpY,EAAQqY,WAAa5S,EAAE7B,MAAMyU,SAG7BrY,EAAQsY,UAAY7M,EAAMvJ,MAI1BlC,EAAQuY,YAAcZ,EAAI1H,SAG1BjQ,EAAQwY,UAAY/gB,EAASiJ,cAAc,QAAQ8X,QAInDxY,EAAQyY,WAA2E,kBAA9DhhB,EAASiJ,cAAc,OAAOgY,WAAW,GAAOC,UAGrE3Y,EAAQ4Y,wBAAyB,EACjC5Y,EAAQ6Y,kBAAmB,EAC3B7Y,EAAQ8Y,eAAgB,EACxB9Y,EAAQ+Y,eAAgB,EACxB/Y,EAAQgZ,cAAe,EACvBhZ,EAAQiZ,qBAAsB,EAC9BjZ,EAAQkZ,mBAAoB,EAG5BzN,EAAMuE,SAAU,EAChBhQ,EAAQmZ,eAAiB1N,EAAMiN,WAAW,GAAO1I,QAIjD7G,EAAO4G,UAAW,EAClB/P,EAAQoZ,aAAezB,EAAI5H,QAG3B,WACQrG,GAAI9N,KACV,MAAOmE,GACRC,EAAQ+Y,eAAgB,EAIzBtN,EAAQhU,EAASiJ,cAAc,SAC/B+K,EAAM5C,aAAc,QAAS,IAC7B7I,EAAQyL,MAA0C,KAAlCA,EAAM7C,aAAc,SAGpC6C,EAAMvJ,MAAQ,IACduJ,EAAM5C,aAAc,OAAQ,SAC5B7I,EAAQqZ,WAA6B,MAAhB5N,EAAMvJ,MAG3BuJ,EAAM5C,aAAc,UAAW,KAC/B4C,EAAM5C,aAAc,OAAQ,KAE5B6O,EAAWjgB,EAAS6hB,yBACpB5B,EAAS3M,YAAaU,GAItBzL,EAAQuZ,cAAgB9N,EAAMuE,QAG9BhQ,EAAQwZ,WAAa9B,EAASgB,WAAW,GAAOA,WAAW,GAAO/J,UAAUqB,QAKvEtG,EAAI5F,cACR4F,EAAI5F,YAAa,UAAW,WAC3B9D,EAAQgZ,cAAe,IAGxBtP,EAAIgP,WAAW,GAAOe,QAKvB,KAAMnc,KAAOyT,QAAQ,EAAM2I,QAAQ,EAAMC,SAAS,GACjDjQ,EAAIb,aAAc+O,EAAY,KAAOta,EAAG,KAExC0C,EAAS1C,EAAI,WAAcsa,IAAazgB,IAAUuS,EAAItD,WAAYwR,GAAYrZ,WAAY,CAG3FmL,GAAI9F,MAAMgW,eAAiB,cAC3BlQ,EAAIgP,WAAW,GAAO9U,MAAMgW,eAAiB,GAC7C5Z,EAAQ6Z,gBAA+C,gBAA7BnQ,EAAI9F,MAAMgW,cAIpC,KAAMtc,IAAKzF,GAAQmI,GAClB,KAoGD,OAlGAA,GAAQC,QAAgB,MAAN3C,EAGlBzF,EAAO,WACN,GAAIiiB,GAAWC,EAAWC,EACzBC,EAAW,+HACXhb,EAAOxH,EAASiK,qBAAqB,QAAQ,EAExCzC,KAKN6a,EAAYriB,EAASiJ,cAAc,OACnCoZ,EAAUlW,MAAMkU,QAAU,gFAE1B7Y,EAAK8L,YAAa+O,GAAY/O,YAAarB,GAS3CA,EAAIuB,UAAY,8CAChB+O,EAAMtQ,EAAIhI,qBAAqB,MAC/BsY,EAAK,GAAIpW,MAAMkU,QAAU,2CACzBD,EAA0C,IAA1BmC,EAAK,GAAIE,aAEzBF,EAAK,GAAIpW,MAAMuW,QAAU,GACzBH,EAAK,GAAIpW,MAAMuW,QAAU,OAIzBna,EAAQoa,sBAAwBvC,GAA2C,IAA1BmC,EAAK,GAAIE,aAG1DxQ,EAAIuB,UAAY,GAChBvB,EAAI9F,MAAMkU,QAAU,wKAIpBjgB,EAAO6L,KAAMzE,EAAyB,MAAnBA,EAAK2E,MAAMyW,MAAiBA,KAAM,MAAU,WAC9Dra,EAAQsa,UAAgC,IAApB5Q,EAAI6Q,cAIpBpjB,EAAOqjB,mBACXxa,EAAQ8Y,cAAuE,QAArD3hB,EAAOqjB,iBAAkB9Q,EAAK,WAAe3F,IACvE/D,EAAQkZ,kBAA2F,SAArE/hB,EAAOqjB,iBAAkB9Q,EAAK,QAAY+Q,MAAO,QAAUA,MAMzFV,EAAYrQ,EAAIqB,YAAatT,EAASiJ,cAAc,QACpDqZ,EAAUnW,MAAMkU,QAAUpO,EAAI9F,MAAMkU,QAAUmC,EAC9CF,EAAUnW,MAAM8W,YAAcX,EAAUnW,MAAM6W,MAAQ,IACtD/Q,EAAI9F,MAAM6W,MAAQ,MAElBza,EAAQiZ,qBACNtZ,YAAcxI,EAAOqjB,iBAAkBT,EAAW,WAAeW,oBAGxDhR,GAAI9F,MAAMyW,OAAS9iB,IAK9BmS,EAAIuB,UAAY,GAChBvB,EAAI9F,MAAMkU,QAAUmC,EAAW,8CAC/Bja,EAAQ4Y,uBAA+C,IAApBlP,EAAI6Q,YAIvC7Q,EAAI9F,MAAMuW,QAAU,QACpBzQ,EAAIuB,UAAY,cAChBvB,EAAIwB,WAAWtH,MAAM6W,MAAQ,MAC7Bza,EAAQ6Y,iBAAyC,IAApBnP,EAAI6Q,YAE5Bva,EAAQ4Y,yBAIZ3Z,EAAK2E,MAAMyW,KAAO,IAIpBpb,EAAK0K,YAAamQ,GAGlBA,EAAYpQ,EAAMsQ,EAAMD,EAAY,QAIrC7f,EAAMiP,EAASuO,EAAWC,EAAMlS,EAAIgG,EAAQ,KAErCzL;KAGR,IAAI2a,GAAS,+BACZC,EAAa,UAEd,SAASC,GAAc3f,EAAM+C,EAAMqC,EAAMwa,GACxC,GAAMjjB,EAAOkjB,WAAY7f,GAAzB,CAIA,GAAIwB,GAAKse,EACRC,EAAcpjB,EAAO0G,QAIrB2c,EAAShgB,EAAKQ,SAId2N,EAAQ6R,EAASrjB,EAAOwR,MAAQnO,EAIhCgB,EAAKgf,EAAShgB,EAAM+f,GAAgB/f,EAAM+f,IAAiBA,CAI5D,IAAO/e,GAAOmN,EAAMnN,KAAS4e,GAAQzR,EAAMnN,GAAIoE,OAAUA,IAASlJ,GAA6B,gBAAT6G,GAgEtF,MA5DM/B,KAIJA,EADIgf,EACChgB,EAAM+f,GAAgBhjB,EAAgB6N,OAASjO,EAAOmL,OAEtDiY,GAID5R,EAAOnN,KAGZmN,EAAOnN,GAAOgf,MAAgBC,OAAQtjB,EAAO8J,QAKzB,gBAAT1D,IAAqC,kBAATA,MAClC6c,EACJzR,EAAOnN,GAAOrE,EAAOgG,OAAQwL,EAAOnN,GAAM+B,GAE1CoL,EAAOnN,GAAKoE,KAAOzI,EAAOgG,OAAQwL,EAAOnN,GAAKoE,KAAMrC,IAItD+c,EAAY3R,EAAOnN,GAKb4e,IACCE,EAAU1a,OACf0a,EAAU1a,SAGX0a,EAAYA,EAAU1a,MAGlBA,IAASlJ,IACb4jB,EAAWnjB,EAAOiK,UAAW7D,IAAWqC,GAKpB,gBAATrC,IAGXvB,EAAMse,EAAW/c,GAGL,MAAPvB,IAGJA,EAAMse,EAAWnjB,EAAOiK,UAAW7D,MAGpCvB,EAAMse,EAGAte,GAGR,QAAS0e,GAAoBlgB,EAAM+C,EAAM6c,GACxC,GAAMjjB,EAAOkjB,WAAY7f,GAAzB,CAIA,GAAI8f,GAAW1d,EACd4d,EAAShgB,EAAKQ,SAGd2N,EAAQ6R,EAASrjB,EAAOwR,MAAQnO,EAChCgB,EAAKgf,EAAShgB,EAAMrD,EAAO0G,SAAY1G,EAAO0G,OAI/C,IAAM8K,EAAOnN,GAAb,CAIA,GAAK+B,IAEJ+c,EAAYF,EAAMzR,EAAOnN,GAAOmN,EAAOnN,GAAKoE,MAE3B,CAGVzI,EAAOyG,QAASL,GAsBrBA,EAAOA,EAAK7F,OAAQP,EAAO4F,IAAKQ,EAAMpG,EAAOiK,YAnBxC7D,IAAQ+c,GACZ/c,GAASA,IAITA,EAAOpG,EAAOiK,UAAW7D,GAExBA,EADIA,IAAQ+c,IACH/c,GAEFA,EAAKkG,MAAM,MAarB7G,EAAIW,EAAK5C,MACT,OAAQiC,UACA0d,GAAW/c,EAAKX,GAKxB,IAAKwd,GAAOO,EAAkBL,IAAcnjB,EAAOqI,cAAc8a,GAChE,QAMGF,UACEzR,GAAOnN,GAAKoE,KAIb+a,EAAmBhS,EAAOnN,QAM5Bgf,EACJrjB,EAAOyjB,WAAapgB,IAAQ,GAIjBrD,EAAOmI,QAAQ+Y,eAAiB1P,GAASA,EAAMlS,aAEnDkS,GAAOnN,GAIdmN,EAAOnN,GAAO,QAIhBrE,EAAOgG,QACNwL,SAIAkS,QACCC,QAAU,EACVC,OAAS,EAEThH,OAAU,8CAGXiH,QAAS,SAAUxgB,GAElB,MADAA,GAAOA,EAAKQ,SAAW7D,EAAOwR,MAAOnO,EAAKrD,EAAO0G,UAAarD,EAAMrD,EAAO0G,WAClErD,IAASmgB,EAAmBngB,IAGtCoF,KAAM,SAAUpF,EAAM+C,EAAMqC,GAC3B,MAAOua,GAAc3f,EAAM+C,EAAMqC,IAGlCqb,WAAY,SAAUzgB,EAAM+C,GAC3B,MAAOmd,GAAoBlgB,EAAM+C,IAIlC2d,MAAO,SAAU1gB,EAAM+C,EAAMqC,GAC5B,MAAOua,GAAc3f,EAAM+C,EAAMqC,GAAM,IAGxCub,YAAa,SAAU3gB,EAAM+C,GAC5B,MAAOmd,GAAoBlgB,EAAM+C,GAAM,IAIxC8c,WAAY,SAAU7f,GAErB,GAAKA,EAAKQ,UAA8B,IAAlBR,EAAKQ,UAAoC,IAAlBR,EAAKQ,SACjD,OAAO,CAGR,IAAI6f,GAASrgB,EAAK8G,UAAYnK,EAAO0jB,OAAQrgB,EAAK8G,SAASC,cAG3D,QAAQsZ,GAAUA,KAAW,GAAQrgB,EAAK0N,aAAa,aAAe2S,KAIxE1jB,EAAOsB,GAAG0E,QACTyC,KAAM,SAAUR,EAAKoC,GACpB,GAAI2H,GAAO5L,EACVqC,EAAO,KACPhD,EAAI,EACJpC,EAAOC,KAAK,EAMb,IAAK2E,IAAQ1I,EAAY,CACxB,GAAK+D,KAAKE,SACTiF,EAAOzI,EAAOyI,KAAMpF,GAEG,IAAlBA,EAAKQ,WAAmB7D,EAAO+jB,MAAO1gB,EAAM,gBAAkB,CAElE,IADA2O,EAAQ3O,EAAKkL,WACDyD,EAAMxO,OAAViC,EAAkBA,IACzBW,EAAO4L,EAAMvM,GAAGW,KAEe,IAA1BA,EAAKvF,QAAQ,WACjBuF,EAAOpG,EAAOiK,UAAW7D,EAAKzF,MAAM,IAEpCsjB,EAAU5gB,EAAM+C,EAAMqC,EAAMrC,IAG9BpG,GAAO+jB,MAAO1gB,EAAM,eAAe,GAIrC,MAAOoF,GAIR,MAAoB,gBAARR,GACJ3E,KAAKyB,KAAK,WAChB/E,EAAOyI,KAAMnF,KAAM2E,KAId5C,UAAU7B,OAAS,EAGzBF,KAAKyB,KAAK,WACT/E,EAAOyI,KAAMnF,KAAM2E,EAAKoC,KAKzBhH,EAAO4gB,EAAU5gB,EAAM4E,EAAKjI,EAAOyI,KAAMpF,EAAM4E,IAAU,MAG3D6b,WAAY,SAAU7b,GACrB,MAAO3E,MAAKyB,KAAK,WAChB/E,EAAO8jB,WAAYxgB,KAAM2E,OAK5B,SAASgc,GAAU5gB,EAAM4E,EAAKQ,GAG7B,GAAKA,IAASlJ,GAA+B,IAAlB8D,EAAKQ,SAAiB,CAEhD,GAAIuC,GAAO,QAAU6B,EAAIpB,QAASkc,EAAY,OAAQ3Y,aAItD,IAFA3B,EAAOpF,EAAK0N,aAAc3K,GAEL,gBAATqC,GAAoB,CAC/B,IACCA,EAAgB,SAATA,GAAkB,EACf,UAATA,GAAmB,EACV,SAATA,EAAkB,MAEjBA,EAAO,KAAOA,GAAQA,EACvBqa,EAAO/e,KAAM0E,GAASzI,EAAOiJ,UAAWR,GACvCA,EACD,MAAOP,IAGTlI,EAAOyI,KAAMpF,EAAM4E,EAAKQ,OAGxBA,GAAOlJ,EAIT,MAAOkJ,GAIR,QAAS+a,GAAmB/b,GAC3B,GAAIrB,EACJ,KAAMA,IAAQqB,GAGb,IAAc,SAATrB,IAAmBpG,EAAOqI,cAAeZ,EAAIrB,MAGpC,WAATA,EACJ,OAAO,CAIT,QAAO,EAERpG,EAAOgG,QACNke,MAAO,SAAU7gB,EAAMV,EAAM8F,GAC5B,GAAIyb,EAEJ,OAAK7gB,IACJV,GAASA,GAAQ,MAAS,QAC1BuhB,EAAQlkB,EAAO+jB,MAAO1gB,EAAMV,GAGvB8F,KACEyb,GAASlkB,EAAOyG,QAAQgC,GAC7Byb,EAAQlkB,EAAO+jB,MAAO1gB,EAAMV,EAAM3C,EAAOsE,UAAUmE,IAEnDyb,EAAMzjB,KAAMgI,IAGPyb,OAZR,GAgBDC,QAAS,SAAU9gB,EAAMV,GACxBA,EAAOA,GAAQ,IAEf,IAAIuhB,GAAQlkB,EAAOkkB,MAAO7gB,EAAMV,GAC/ByhB,EAAcF,EAAM1gB,OACpBlC,EAAK4iB,EAAMxS,QACX2S,EAAQrkB,EAAOskB,YAAajhB,EAAMV,GAClC4hB,EAAO,WACNvkB,EAAOmkB,QAAS9gB,EAAMV,GAIZ,gBAAPrB,IACJA,EAAK4iB,EAAMxS,QACX0S,KAGI9iB,IAIU,OAATqB,GACJuhB,EAAMvP,QAAS,oBAIT0P,GAAMG,KACbljB,EAAGkD,KAAMnB,EAAMkhB,EAAMF,KAGhBD,GAAeC,GACpBA,EAAM/L,MAAMkF,QAKd8G,YAAa,SAAUjhB,EAAMV,GAC5B,GAAIsF,GAAMtF,EAAO,YACjB,OAAO3C,GAAO+jB,MAAO1gB,EAAM4E,IAASjI,EAAO+jB,MAAO1gB,EAAM4E,GACvDqQ,MAAOtY,EAAO8c,UAAU,eAAec,IAAI,WAC1C5d,EAAOgkB,YAAa3gB,EAAMV,EAAO,SACjC3C,EAAOgkB,YAAa3gB,EAAM4E,UAM9BjI,EAAOsB,GAAG0E,QACTke,MAAO,SAAUvhB,EAAM8F,GACtB,GAAIgc,GAAS,CAQb,OANqB,gBAAT9hB,KACX8F,EAAO9F,EACPA,EAAO,KACP8hB,KAGuBA,EAAnBpf,UAAU7B,OACPxD,EAAOkkB,MAAO5gB,KAAK,GAAIX,GAGxB8F,IAASlJ,EACf+D,KACAA,KAAKyB,KAAK,WACT,GAAImf,GAAQlkB,EAAOkkB,MAAO5gB,KAAMX,EAAM8F,EAGtCzI,GAAOskB,YAAahhB,KAAMX,GAEZ,OAATA,GAA8B,eAAbuhB,EAAM,IAC3BlkB,EAAOmkB,QAAS7gB,KAAMX,MAI1BwhB,QAAS,SAAUxhB,GAClB,MAAOW,MAAKyB,KAAK,WAChB/E,EAAOmkB,QAAS7gB,KAAMX,MAKxB+hB,MAAO,SAAUC,EAAMhiB,GAItB,MAHAgiB,GAAO3kB,EAAO4kB,GAAK5kB,EAAO4kB,GAAGC,OAAQF,IAAUA,EAAOA,EACtDhiB,EAAOA,GAAQ,KAERW,KAAK4gB,MAAOvhB,EAAM,SAAU4hB,EAAMF,GACxC,GAAIS,GAAUzd,WAAYkd,EAAMI,EAChCN,GAAMG,KAAO,WACZO,aAAcD,OAIjBE,WAAY,SAAUriB,GACrB,MAAOW,MAAK4gB,MAAOvhB,GAAQ,UAI5BuC,QAAS,SAAUvC,EAAM8E,GACxB,GAAI8B,GACH0b,EAAQ,EACRC,EAAQllB,EAAOgM,WACf6I,EAAWvR,KACXmC,EAAInC,KAAKE,OACTqb,EAAU,aACCoG,GACTC,EAAM5d,YAAauN,GAAYA,IAIb,iBAATlS,KACX8E,EAAM9E,EACNA,EAAOpD,GAERoD,EAAOA,GAAQ,IAEf,OAAO8C,IACN8D,EAAMvJ,EAAO+jB,MAAOlP,EAAUpP,GAAK9C,EAAO,cACrC4G,GAAOA,EAAI+O,QACf2M,IACA1b,EAAI+O,MAAMsF,IAAKiB,GAIjB,OADAA,KACOqG,EAAMhgB,QAASuC,KAGxB,IAAI0d,GAAUC,EACbC,EAAS,cACTC,EAAU,MACVC,EAAa,6CACbC,EAAa,gBACbC,EAAc,0BACdvF,EAAkBlgB,EAAOmI,QAAQ+X,gBACjCwF,EAAc1lB,EAAOmI,QAAQyL,KAE9B5T,GAAOsB,GAAG0E,QACT9B,KAAM,SAAUkC,EAAMiE,GACrB,MAAOrK,GAAOqL,OAAQ/H,KAAMtD,EAAOkE,KAAMkC,EAAMiE,EAAOhF,UAAU7B,OAAS,IAG1EmiB,WAAY,SAAUvf,GACrB,MAAO9C,MAAKyB,KAAK,WAChB/E,EAAO2lB,WAAYriB,KAAM8C,MAI3Bwf,KAAM,SAAUxf,EAAMiE,GACrB,MAAOrK,GAAOqL,OAAQ/H,KAAMtD,EAAO4lB,KAAMxf,EAAMiE,EAAOhF,UAAU7B,OAAS,IAG1EqiB,WAAY,SAAUzf,GAErB,MADAA,GAAOpG,EAAO8lB,QAAS1f,IAAUA,EAC1B9C,KAAKyB,KAAK,WAEhB,IACCzB,KAAM8C,GAAS7G,QACR+D,MAAM8C,GACZ,MAAO8B,QAIX6d,SAAU,SAAU1b,GACnB,GAAI2b,GAAS3iB,EAAM+O,EAAK6T,EAAOtgB,EAC9BF,EAAI,EACJC,EAAMpC,KAAKE,OACX0iB,EAA2B,gBAAV7b,IAAsBA,CAExC,IAAKrK,EAAOiE,WAAYoG,GACvB,MAAO/G,MAAKyB,KAAK,SAAUY,GAC1B3F,EAAQsD,MAAOyiB,SAAU1b,EAAM7F,KAAMlB,KAAMqC,EAAGrC,KAAK2P,aAIrD,IAAKiT,EAIJ,IAFAF,GAAY3b,GAAS,IAAKjH,MAAO1B,OAErBgE,EAAJD,EAASA,IAOhB,GANApC,EAAOC,KAAMmC,GACb2M,EAAwB,IAAlB/O,EAAKQ,WAAoBR,EAAK4P,WACjC,IAAM5P,EAAK4P,UAAY,KAAMpM,QAASwe,EAAQ,KAChD,KAGU,CACV1f,EAAI,CACJ,OAASsgB,EAAQD,EAAQrgB,KACgB,EAAnCyM,EAAIvR,QAAS,IAAMolB,EAAQ,OAC/B7T,GAAO6T,EAAQ,IAGjB5iB,GAAK4P,UAAYjT,EAAOmB,KAAMiR,GAMjC,MAAO9O,OAGR6iB,YAAa,SAAU9b,GACtB,GAAI2b,GAAS3iB,EAAM+O,EAAK6T,EAAOtgB,EAC9BF,EAAI,EACJC,EAAMpC,KAAKE,OACX0iB,EAA+B,IAArB7gB,UAAU7B,QAAiC,gBAAV6G,IAAsBA,CAElE,IAAKrK,EAAOiE,WAAYoG,GACvB,MAAO/G,MAAKyB,KAAK,SAAUY,GAC1B3F,EAAQsD,MAAO6iB,YAAa9b,EAAM7F,KAAMlB,KAAMqC,EAAGrC,KAAK2P,aAGxD,IAAKiT,EAGJ,IAFAF,GAAY3b,GAAS,IAAKjH,MAAO1B,OAErBgE,EAAJD,EAASA,IAQhB,GAPApC,EAAOC,KAAMmC,GAEb2M,EAAwB,IAAlB/O,EAAKQ,WAAoBR,EAAK4P,WACjC,IAAM5P,EAAK4P,UAAY,KAAMpM,QAASwe,EAAQ,KAChD,IAGU,CACV1f,EAAI,CACJ,OAASsgB,EAAQD,EAAQrgB,KAExB,MAAQyM,EAAIvR,QAAS,IAAMolB,EAAQ,MAAS,EAC3C7T,EAAMA,EAAIvL,QAAS,IAAMof,EAAQ,IAAK,IAGxC5iB,GAAK4P,UAAY5I,EAAQrK,EAAOmB,KAAMiR,GAAQ,GAKjD,MAAO9O,OAGR8iB,YAAa,SAAU/b,EAAOgc,GAC7B,GAAI1jB,SAAc0H,EAElB,OAAyB,iBAAbgc,IAAmC,WAAT1jB,EAC9B0jB,EAAW/iB,KAAKyiB,SAAU1b,GAAU/G,KAAK6iB,YAAa9b,GAGzDrK,EAAOiE,WAAYoG,GAChB/G,KAAKyB,KAAK,SAAUU,GAC1BzF,EAAQsD,MAAO8iB,YAAa/b,EAAM7F,KAAKlB,KAAMmC,EAAGnC,KAAK2P,UAAWoT,GAAWA,KAItE/iB,KAAKyB,KAAK,WAChB,GAAc,WAATpC,EAAoB,CAExB,GAAIsQ,GACHxN,EAAI,EACJiY,EAAO1d,EAAQsD,MACfgjB,EAAajc,EAAMjH,MAAO1B,MAE3B,OAASuR,EAAYqT,EAAY7gB,KAE3BiY,EAAK6I,SAAUtT,GACnByK,EAAKyI,YAAalT,GAElByK,EAAKqI,SAAU9S,QAKNtQ,IAASjD,GAA8B,YAATiD,KACpCW,KAAK2P,WAETjT,EAAO+jB,MAAOzgB,KAAM,gBAAiBA,KAAK2P,WAO3C3P,KAAK2P,UAAY3P,KAAK2P,WAAa5I,KAAU,EAAQ,GAAKrK,EAAO+jB,MAAOzgB,KAAM,kBAAqB,OAKtGijB,SAAU,SAAUnlB,GACnB,GAAI6R,GAAY,IAAM7R,EAAW,IAChCqE,EAAI,EACJqF,EAAIxH,KAAKE,MACV,MAAYsH,EAAJrF,EAAOA,IACd,GAA0B,IAArBnC,KAAKmC,GAAG5B,WAAmB,IAAMP,KAAKmC,GAAGwN,UAAY,KAAKpM,QAAQwe,EAAQ,KAAKxkB,QAASoS,IAAe,EAC3G,OAAO,CAIT,QAAO,GAGR6B,IAAK,SAAUzK,GACd,GAAIxF,GAAKwf,EAAOpgB,EACfZ,EAAOC,KAAK,EAEb,EAAA,GAAM+B,UAAU7B,OAsBhB,MAFAS,GAAajE,EAAOiE,WAAYoG,GAEzB/G,KAAKyB,KAAK,SAAUU,GAC1B,GAAIqP,EAEmB,KAAlBxR,KAAKO,WAKTiR,EADI7Q,EACEoG,EAAM7F,KAAMlB,KAAMmC,EAAGzF,EAAQsD,MAAOwR,OAEpCzK,EAIK,MAAPyK,EACJA,EAAM,GACoB,gBAARA,GAClBA,GAAO,GACI9U,EAAOyG,QAASqO,KAC3BA,EAAM9U,EAAO4F,IAAIkP,EAAK,SAAWzK,GAChC,MAAgB,OAATA,EAAgB,GAAKA,EAAQ,MAItCga,EAAQrkB,EAAOwmB,SAAUljB,KAAKX,OAAU3C,EAAOwmB,SAAUljB,KAAK6G,SAASC,eAGjEia,GAAW,OAASA,IAAUA,EAAMoC,IAAKnjB,KAAMwR,EAAK,WAAcvV,IACvE+D,KAAK+G,MAAQyK,KAjDd,IAAKzR,EAGJ,MAFAghB,GAAQrkB,EAAOwmB,SAAUnjB,EAAKV,OAAU3C,EAAOwmB,SAAUnjB,EAAK8G,SAASC,eAElEia,GAAS,OAASA,KAAUxf,EAAMwf,EAAM5f,IAAKpB,EAAM,YAAe9D,EAC/DsF,GAGRA,EAAMxB,EAAKgH,MAEW,gBAARxF,GAEbA,EAAIgC,QAAQye,EAAS,IAEd,MAAPzgB,EAAc,GAAKA,OA0CxB7E,EAAOgG,QACNwgB,UACCE,QACCjiB,IAAK,SAAUpB,GAEd,GAAIyR,GAAM9U,EAAO0D,KAAKQ,KAAMb,EAAM,QAClC,OAAc,OAAPyR,EACNA,EACAzR,EAAKkH,OAGR+G,QACC7M,IAAK,SAAUpB,GACd,GAAIgH,GAAOqc,EACVrgB,EAAUhD,EAAKgD,QACfwX,EAAQxa,EAAKgV,cACbsO,EAAoB,eAAdtjB,EAAKV,MAAiC,EAARkb,EACpC2B,EAASmH,EAAM,QACf/b,EAAM+b,EAAM9I,EAAQ,EAAIxX,EAAQ7C,OAChCiC,EAAY,EAARoY,EACHjT,EACA+b,EAAM9I,EAAQ,CAGhB,MAAYjT,EAAJnF,EAASA,IAIhB,GAHAihB,EAASrgB,EAASZ,MAGXihB,EAAOtO,UAAY3S,IAAMoY,IAE5B7d,EAAOmI,QAAQoZ,YAAemF,EAAOxO,SAA+C,OAApCwO,EAAO3V,aAAa,cACnE2V,EAAOtiB,WAAW8T,UAAalY,EAAOmK,SAAUuc,EAAOtiB,WAAY,aAAiB,CAMxF,GAHAiG,EAAQrK,EAAQ0mB,GAAS5R,MAGpB6R,EACJ,MAAOtc,EAIRmV,GAAO/e,KAAM4J,GAIf,MAAOmV,IAGRiH,IAAK,SAAUpjB,EAAMgH,GACpB,GAAIuc,GAAWF,EACdrgB,EAAUhD,EAAKgD,QACfmZ,EAASxf,EAAOsE,UAAW+F,GAC3B5E,EAAIY,EAAQ7C,MAEb,OAAQiC,IACPihB,EAASrgB,EAASZ,IACZihB,EAAOtO,SAAWpY,EAAO2K,QAAS3K,EAAO0mB,GAAQ5R,MAAO0K,IAAY,KACzEoH,GAAY,EAQd,OAHMA,KACLvjB,EAAKgV,cAAgB,IAEfmH,KAKVtb,KAAM,SAAUb,EAAM+C,EAAMiE,GAC3B,GAAIga,GAAOxf,EACVgiB,EAAQxjB,EAAKQ,QAGd,IAAMR,GAAkB,IAAVwjB,GAAyB,IAAVA,GAAyB,IAAVA,EAK5C,aAAYxjB,GAAK0N,eAAiBrR,EAC1BM,EAAO4lB,KAAMviB,EAAM+C,EAAMiE,IAKlB,IAAVwc,GAAgB7mB,EAAOyc,SAAUpZ,KACrC+C,EAAOA,EAAKgE,cACZia,EAAQrkB,EAAO8mB,UAAW1gB,KACvBpG,EAAO4U,KAAKxR,MAAMmM,KAAKxL,KAAMqC,GAASgf,EAAWD,IAGhD9a,IAAU9K,EAaH8kB,GAAS,OAASA,IAA6C,QAAnCxf,EAAMwf,EAAM5f,IAAKpB,EAAM+C,IACvDvB,GAGPA,EAAM7E,EAAO0D,KAAKQ,KAAMb,EAAM+C,GAGhB,MAAPvB,EACNtF,EACAsF,GApBc,OAAVwF,EAGOga,GAAS,OAASA,KAAUxf,EAAMwf,EAAMoC,IAAKpjB,EAAMgH,EAAOjE,MAAY7G,EAC1EsF,GAGPxB,EAAK2N,aAAc5K,EAAMiE,EAAQ,IAC1BA,IAPPrK,EAAO2lB,WAAYtiB,EAAM+C,GAAzBpG,KAuBH2lB,WAAY,SAAUtiB,EAAMgH,GAC3B,GAAIjE,GAAM2gB,EACTthB,EAAI,EACJuhB,EAAY3c,GAASA,EAAMjH,MAAO1B,EAEnC,IAAKslB,GAA+B,IAAlB3jB,EAAKQ,SACtB,MAASuC,EAAO4gB,EAAUvhB,KACzBshB,EAAW/mB,EAAO8lB,QAAS1f,IAAUA,EAGhCpG,EAAO4U,KAAKxR,MAAMmM,KAAKxL,KAAMqC,GAE5Bsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GACzD/C,EAAM0jB,IAAa,EAInB1jB,EAAMrD,EAAOiK,UAAW,WAAa7D,IACpC/C,EAAM0jB,IAAa,EAKrB/mB,EAAOkE,KAAMb,EAAM+C,EAAM,IAG1B/C,EAAKgO,gBAAiB6O,EAAkB9Z,EAAO2gB,IAKlDD,WACCnkB,MACC8jB,IAAK,SAAUpjB,EAAMgH,GACpB,IAAMrK,EAAOmI,QAAQqZ,YAAwB,UAAVnX,GAAqBrK,EAAOmK,SAAS9G,EAAM,SAAW,CAGxF,GAAIyR,GAAMzR,EAAKgH,KAKf,OAJAhH,GAAK2N,aAAc,OAAQ3G,GACtByK,IACJzR,EAAKgH,MAAQyK,GAEPzK,MAMXyb,SACCmB,MAAO,UACPC,QAAS,aAGVtB,KAAM,SAAUviB,EAAM+C,EAAMiE,GAC3B,GAAIxF,GAAKwf,EAAO8C,EACfN,EAAQxjB,EAAKQ,QAGd,IAAMR,GAAkB,IAAVwjB,GAAyB,IAAVA,GAAyB,IAAVA,EAY5C,MARAM,GAAmB,IAAVN,IAAgB7mB,EAAOyc,SAAUpZ,GAErC8jB,IAEJ/gB,EAAOpG,EAAO8lB,QAAS1f,IAAUA,EACjCie,EAAQrkB,EAAOonB,UAAWhhB,IAGtBiE,IAAU9K,EACP8kB,GAAS,OAASA,KAAUxf,EAAMwf,EAAMoC,IAAKpjB,EAAMgH,EAAOjE,MAAY7G,EAC5EsF,EACExB,EAAM+C,GAASiE,EAGXga,GAAS,OAASA,IAA6C,QAAnCxf,EAAMwf,EAAM5f,IAAKpB,EAAM+C,IACzDvB,EACAxB,EAAM+C,IAITghB,WACCpP,UACCvT,IAAK,SAAUpB,GAId,GAAIgkB,GAAWrnB,EAAO0D,KAAKQ,KAAMb,EAAM,WAEvC,OAAOgkB,GACNC,SAAUD,EAAU,IACpB9B,EAAWxhB,KAAMV,EAAK8G,WAAcqb,EAAWzhB,KAAMV,EAAK8G,WAAc9G,EAAK0U,KAC5E,EACA,QAONqN,GACCqB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAa3B,MAZKiE,MAAU,EAEdrK,EAAO2lB,WAAYtiB,EAAM+C,GACdsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GAEhE/C,EAAK2N,cAAekP,GAAmBlgB,EAAO8lB,QAAS1f,IAAUA,EAAMA,GAIvE/C,EAAMrD,EAAOiK,UAAW,WAAa7D,IAAW/C,EAAM+C,IAAS,EAGzDA,IAGTpG,EAAO+E,KAAM/E,EAAO4U,KAAKxR,MAAMmM,KAAK9N,OAAO2B,MAAO,QAAU,SAAUqC,EAAGW,GACxE,GAAImhB,GAASvnB,EAAO4U,KAAK1C,WAAY9L,IAAUpG,EAAO0D,KAAKQ,IAE3DlE,GAAO4U,KAAK1C,WAAY9L,GAASsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GACrF,SAAU/C,EAAM+C,EAAMsG,GACrB,GAAIpL,GAAKtB,EAAO4U,KAAK1C,WAAY9L,GAChCvB,EAAM6H,EACLnN,GAECS,EAAO4U,KAAK1C,WAAY9L,GAAS7G,IACjCgoB,EAAQlkB,EAAM+C,EAAMsG,GAEpBtG,EAAKgE,cACL,IAEH,OADApK,GAAO4U,KAAK1C,WAAY9L,GAAS9E,EAC1BuD,GAER,SAAUxB,EAAM+C,EAAMsG,GACrB,MAAOA,GACNnN,EACA8D,EAAMrD,EAAOiK,UAAW,WAAa7D,IACpCA,EAAKgE,cACL,QAKCsb,GAAgBxF,IACrBlgB,EAAO8mB,UAAUzc,OAChBoc,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAC3B,MAAKpG,GAAOmK,SAAU9G,EAAM,UAE3BA,EAAKkZ,aAAelS,EAApBhH,GAGO8hB,GAAYA,EAASsB,IAAKpjB,EAAMgH,EAAOjE,MAO5C8Z,IAILiF,GACCsB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAE3B,GAAIvB,GAAMxB,EAAKqQ,iBAAkBtN,EAUjC,OATMvB,IACLxB,EAAKmkB,iBACH3iB,EAAMxB,EAAKS,cAAc2jB,gBAAiBrhB,IAI7CvB,EAAIwF,MAAQA,GAAS,GAGL,UAATjE,GAAoBiE,IAAUhH,EAAK0N,aAAc3K,GACvDiE,EACA9K,IAGHS,EAAO4U,KAAK1C,WAAW7N,GAAKrE,EAAO4U,KAAK1C,WAAW9L,KAAOpG,EAAO4U,KAAK1C,WAAWwV,OAEhF,SAAUrkB,EAAM+C,EAAMsG,GACrB,GAAI7H,EACJ,OAAO6H,GACNnN,GACCsF,EAAMxB,EAAKqQ,iBAAkBtN,KAAyB,KAAdvB,EAAIwF,MAC5CxF,EAAIwF,MACJ,MAEJrK,EAAOwmB,SAAShO,QACf/T,IAAK,SAAUpB,EAAM+C,GACpB,GAAIvB,GAAMxB,EAAKqQ,iBAAkBtN,EACjC,OAAOvB,IAAOA,EAAIkQ,UACjBlQ,EAAIwF,MACJ9K,GAEFknB,IAAKtB,EAASsB,KAKfzmB,EAAO8mB,UAAUa,iBAChBlB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAC3B+e,EAASsB,IAAKpjB,EAAgB,KAAVgH,GAAe,EAAQA,EAAOjE,KAMpDpG,EAAO+E,MAAO,QAAS,UAAY,SAAUU,EAAGW,GAC/CpG,EAAO8mB,UAAW1gB,IACjBqgB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAe,KAAVA,GACJhH,EAAK2N,aAAc5K,EAAM,QAClBiE,GAFR,OAYErK,EAAOmI,QAAQmY,gBAEpBtgB,EAAO+E,MAAO,OAAQ,OAAS,SAAUU,EAAGW,GAC3CpG,EAAOonB,UAAWhhB,IACjB3B,IAAK,SAAUpB,GACd,MAAOA,GAAK0N,aAAc3K,EAAM,OAM9BpG,EAAOmI,QAAQ4D,QACpB/L,EAAO8mB,UAAU/a,OAChBtH,IAAK,SAAUpB,GAId,MAAOA,GAAK0I,MAAMkU,SAAW1gB,GAE9BknB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAShH,GAAK0I,MAAMkU,QAAU5V,EAAQ,MAOnCrK,EAAOmI,QAAQuY,cACpB1gB,EAAOonB,UAAUhP,UAChB3T,IAAK,SAAUpB,GACd,GAAI0P,GAAS1P,EAAKe,UAUlB,OARK2O,KACJA,EAAOsF,cAGFtF,EAAO3O,YACX2O,EAAO3O,WAAWiU,eAGb,QAKVrY,EAAO+E,MACN,WACA,WACA,YACA,cACA,cACA,UACA,UACA,SACA,cACA,mBACE,WACF/E,EAAO8lB,QAASxiB,KAAK8G,eAAkB9G,OAIlCtD,EAAOmI,QAAQwY,UACpB3gB,EAAO8lB,QAAQnF,QAAU,YAI1B3gB,EAAO+E,MAAO,QAAS,YAAc,WACpC/E,EAAOwmB,SAAUljB,OAChBmjB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAKrK,GAAOyG,QAAS4D,GACXhH,EAAK8U,QAAUnY,EAAO2K,QAAS3K,EAAOqD,GAAMyR,MAAOzK,IAAW,EADxE,IAKIrK,EAAOmI,QAAQsY,UACpBzgB,EAAOwmB,SAAUljB,MAAOmB,IAAM,SAAUpB,GAGvC,MAAsC,QAA/BA,EAAK0N,aAAa,SAAoB,KAAO1N,EAAKgH,SAI5D,IAAIud,GAAa,+BAChBC,GAAY,OACZC,GAAc,+BACdC,GAAc,kCACdC,GAAiB,sBAElB,SAASC,MACR,OAAO,EAGR,QAASC,MACR,OAAO,EAGR,QAASC,MACR,IACC,MAAOvoB,GAASiY,cACf,MAAQuQ,KAOXpoB,EAAOyC,OAEN4lB,UAEAzK,IAAK,SAAUva,EAAMilB,EAAOrW,EAASxJ,EAAMrH,GAC1C,GAAImI,GAAKgf,EAAQC,EAAGC,EACnBC,EAASC,EAAaC,EACtBC,EAAUlmB,EAAMmmB,EAAYC,EAC5BC,EAAWhpB,EAAO+jB,MAAO1gB,EAG1B,IAAM2lB,EAAN,CAKK/W,EAAQA,UACZwW,EAAcxW,EACdA,EAAUwW,EAAYxW,QACtB7Q,EAAWqnB,EAAYrnB,UAIlB6Q,EAAQ9G,OACb8G,EAAQ9G,KAAOnL,EAAOmL,SAIhBod,EAASS,EAAST,UACxBA,EAASS,EAAST,YAEZI,EAAcK,EAASC,UAC7BN,EAAcK,EAASC,OAAS,SAAU/gB,GAGzC,aAAclI,KAAWN,GAAuBwI,GAAKlI,EAAOyC,MAAMymB,YAAchhB,EAAEvF,KAEjFpD,EADAS,EAAOyC,MAAM0mB,SAAS/jB,MAAOujB,EAAYtlB,KAAMgC,YAIjDsjB,EAAYtlB,KAAOA,GAIpBilB,GAAUA,GAAS,IAAKllB,MAAO1B,KAAqB,IACpD8mB,EAAIF,EAAM9kB,MACV,OAAQglB,IACPjf,EAAMye,GAAevkB,KAAM6kB,EAAME,QACjC7lB,EAAOomB,EAAWxf,EAAI,GACtBuf,GAAevf,EAAI,IAAM,IAAK+C,MAAO,KAAMxG,OAGrCnD,IAKN+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAGhCA,GAASvB,EAAWsnB,EAAQU,aAAeV,EAAQW,WAAc1mB,EAGjE+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAGhCimB,EAAY5oB,EAAOgG,QAClBrD,KAAMA,EACNomB,SAAUA,EACVtgB,KAAMA,EACNwJ,QAASA,EACT9G,KAAM8G,EAAQ9G,KACd/J,SAAUA,EACVoO,aAAcpO,GAAYpB,EAAO4U,KAAKxR,MAAMoM,aAAazL,KAAM3C,GAC/DkoB,UAAWR,EAAW5X,KAAK,MACzBuX,IAGII,EAAWN,EAAQ5lB,MACzBkmB,EAAWN,EAAQ5lB,MACnBkmB,EAASU,cAAgB,EAGnBb,EAAQc,OAASd,EAAQc,MAAMhlB,KAAMnB,EAAMoF,EAAMqgB,EAAYH,MAAkB,IAE/EtlB,EAAKX,iBACTW,EAAKX,iBAAkBC,EAAMgmB,GAAa,GAE/BtlB,EAAK4I,aAChB5I,EAAK4I,YAAa,KAAOtJ,EAAMgmB,KAK7BD,EAAQ9K,MACZ8K,EAAQ9K,IAAIpZ,KAAMnB,EAAMulB,GAElBA,EAAU3W,QAAQ9G,OACvByd,EAAU3W,QAAQ9G,KAAO8G,EAAQ9G,OAK9B/J,EACJynB,EAAS9iB,OAAQ8iB,EAASU,gBAAiB,EAAGX,GAE9CC,EAASpoB,KAAMmoB,GAIhB5oB,EAAOyC,MAAM4lB,OAAQ1lB,IAAS,EAI/BU,GAAO,OAIR0F,OAAQ,SAAU1F,EAAMilB,EAAOrW,EAAS7Q,EAAUqoB,GACjD,GAAI9jB,GAAGijB,EAAWrf,EACjBmgB,EAAWlB,EAAGD,EACdG,EAASG,EAAUlmB,EACnBmmB,EAAYC,EACZC,EAAWhpB,EAAO6jB,QAASxgB,IAAUrD,EAAO+jB,MAAO1gB,EAEpD,IAAM2lB,IAAcT,EAASS,EAAST,QAAtC,CAKAD,GAAUA,GAAS,IAAKllB,MAAO1B,KAAqB,IACpD8mB,EAAIF,EAAM9kB,MACV,OAAQglB,IAMP,GALAjf,EAAMye,GAAevkB,KAAM6kB,EAAME,QACjC7lB,EAAOomB,EAAWxf,EAAI,GACtBuf,GAAevf,EAAI,IAAM,IAAK+C,MAAO,KAAMxG,OAGrCnD,EAAN,CAOA+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAChCA,GAASvB,EAAWsnB,EAAQU,aAAeV,EAAQW,WAAc1mB,EACjEkmB,EAAWN,EAAQ5lB,OACnB4G,EAAMA,EAAI,IAAUkF,OAAQ,UAAYqa,EAAW5X,KAAK,iBAAmB,WAG3EwY,EAAY/jB,EAAIkjB,EAASrlB,MACzB,OAAQmC,IACPijB,EAAYC,EAAUljB,IAEf8jB,GAAeV,IAAaH,EAAUG,UACzC9W,GAAWA,EAAQ9G,OAASyd,EAAUzd,MACtC5B,IAAOA,EAAIxF,KAAM6kB,EAAUU,YAC3BloB,GAAYA,IAAawnB,EAAUxnB,WAAyB,OAAbA,IAAqBwnB,EAAUxnB,YACjFynB,EAAS9iB,OAAQJ,EAAG,GAEfijB,EAAUxnB,UACdynB,EAASU,gBAELb,EAAQ3f,QACZ2f,EAAQ3f,OAAOvE,KAAMnB,EAAMulB,GAOzBc,KAAcb,EAASrlB,SACrBklB,EAAQiB,UAAYjB,EAAQiB,SAASnlB,KAAMnB,EAAMylB,EAAYE,EAASC,WAAa,GACxFjpB,EAAO4pB,YAAavmB,EAAMV,EAAMqmB,EAASC,cAGnCV,GAAQ5lB,QAtCf,KAAMA,IAAQ4lB,GACbvoB,EAAOyC,MAAMsG,OAAQ1F,EAAMV,EAAO2lB,EAAOE,GAAKvW,EAAS7Q,GAAU,EA0C/DpB,GAAOqI,cAAekgB,WACnBS,GAASC,OAIhBjpB,EAAOgkB,YAAa3gB,EAAM,aAI5BkE,QAAS,SAAU9E,EAAOgG,EAAMpF,EAAMwmB,GACrC,GAAIZ,GAAQa,EAAQ1X,EACnB2X,EAAYrB,EAASnf,EAAK9D,EAC1BukB,GAAc3mB,GAAQzD,GACtB+C,EAAO3B,EAAYwD,KAAM/B,EAAO,QAAWA,EAAME,KAAOF,EACxDqmB,EAAa9nB,EAAYwD,KAAM/B,EAAO,aAAgBA,EAAM6mB,UAAUhd,MAAM,OAK7E,IAHA8F,EAAM7I,EAAMlG,EAAOA,GAAQzD,EAGJ,IAAlByD,EAAKQ,UAAoC,IAAlBR,EAAKQ,WAK5BkkB,GAAYhkB,KAAMpB,EAAO3C,EAAOyC,MAAMymB,aAItCvmB,EAAK9B,QAAQ,MAAQ,IAEzBioB,EAAanmB,EAAK2J,MAAM,KACxB3J,EAAOmmB,EAAWpX,QAClBoX,EAAWhjB,QAEZgkB,EAA6B,EAApBnnB,EAAK9B,QAAQ,MAAY,KAAO8B,EAGzCF,EAAQA,EAAOzC,EAAO0G,SACrBjE,EACA,GAAIzC,GAAOiqB,MAAOtnB,EAAuB,gBAAVF,IAAsBA,GAGtDA,EAAMynB,UAAYL,EAAe,EAAI,EACrCpnB,EAAM6mB,UAAYR,EAAW5X,KAAK,KAClCzO,EAAM0nB,aAAe1nB,EAAM6mB,UACtB7a,OAAQ,UAAYqa,EAAW5X,KAAK,iBAAmB,WAC3D,KAGDzO,EAAM4T,OAAS9W,EACTkD,EAAM8D,SACX9D,EAAM8D,OAASlD,GAIhBoF,EAAe,MAARA,GACJhG,GACFzC,EAAOsE,UAAWmE,GAAQhG,IAG3BimB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAC1BknB,IAAgBnB,EAAQnhB,SAAWmhB,EAAQnhB,QAAQnC,MAAO/B,EAAMoF,MAAW,GAAjF,CAMA,IAAMohB,IAAiBnB,EAAQ0B,WAAapqB,EAAO2H,SAAUtE,GAAS,CAMrE,IAJA0mB,EAAarB,EAAQU,cAAgBzmB,EAC/BolB,GAAYhkB,KAAMgmB,EAAapnB,KACpCyP,EAAMA,EAAIhO,YAEHgO,EAAKA,EAAMA,EAAIhO,WACtB4lB,EAAUvpB,KAAM2R,GAChB7I,EAAM6I,CAIF7I,MAASlG,EAAKS,eAAiBlE,IACnCoqB,EAAUvpB,KAAM8I,EAAIyJ,aAAezJ,EAAI8gB,cAAgB/qB,GAKzDmG,EAAI,CACJ,QAAS2M,EAAM4X,EAAUvkB,QAAUhD,EAAM6nB,uBAExC7nB,EAAME,KAAO8C,EAAI,EAChBskB,EACArB,EAAQW,UAAY1mB,EAGrBsmB,GAAWjpB,EAAO+jB,MAAO3R,EAAK,eAAoB3P,EAAME,OAAU3C,EAAO+jB,MAAO3R,EAAK,UAChF6W,GACJA,EAAO7jB,MAAOgN,EAAK3J,GAIpBwgB,EAASa,GAAU1X,EAAK0X,GACnBb,GAAUjpB,EAAOkjB,WAAY9Q,IAAS6W,EAAO7jB,OAAS6jB,EAAO7jB,MAAOgN,EAAK3J,MAAW,GACxFhG,EAAM8nB,gBAMR,IAHA9nB,EAAME,KAAOA,GAGPknB,IAAiBpnB,EAAM+nB,wBAErB9B,EAAQ+B,UAAY/B,EAAQ+B,SAASrlB,MAAO4kB,EAAU/b,MAAOxF,MAAW,IAC9EzI,EAAOkjB,WAAY7f,IAKdymB,GAAUzmB,EAAMV,KAAW3C,EAAO2H,SAAUtE,GAAS,CAGzDkG,EAAMlG,EAAMymB,GAEPvgB,IACJlG,EAAMymB,GAAW,MAIlB9pB,EAAOyC,MAAMymB,UAAYvmB,CACzB,KACCU,EAAMV,KACL,MAAQuF,IAIVlI,EAAOyC,MAAMymB,UAAY3pB,EAEpBgK,IACJlG,EAAMymB,GAAWvgB,GAMrB,MAAO9G,GAAM4T,SAGd8S,SAAU,SAAU1mB,GAGnBA,EAAQzC,EAAOyC,MAAMioB,IAAKjoB,EAE1B,IAAIgD,GAAGZ,EAAK+jB,EAAW1R,EAASvR,EAC/BglB,KACA1lB,EAAOvE,EAAW8D,KAAMa,WACxBwjB,GAAa7oB,EAAO+jB,MAAOzgB,KAAM,eAAoBb,EAAME,UAC3D+lB,EAAU1oB,EAAOyC,MAAMimB,QAASjmB,EAAME,SAOvC,IAJAsC,EAAK,GAAKxC,EACVA,EAAMmoB,eAAiBtnB,MAGlBolB,EAAQmC,aAAenC,EAAQmC,YAAYrmB,KAAMlB,KAAMb,MAAY,EAAxE,CAKAkoB,EAAe3qB,EAAOyC,MAAMomB,SAASrkB,KAAMlB,KAAMb,EAAOomB,GAGxDpjB,EAAI,CACJ,QAASyR,EAAUyT,EAAcllB,QAAWhD,EAAM6nB,uBAAyB,CAC1E7nB,EAAMqoB,cAAgB5T,EAAQ7T,KAE9BsC,EAAI,CACJ,QAASijB,EAAY1R,EAAQ2R,SAAUljB,QAAWlD,EAAMsoB,kCAIjDtoB,EAAM0nB,cAAgB1nB,EAAM0nB,aAAapmB,KAAM6kB,EAAUU,cAE9D7mB,EAAMmmB,UAAYA,EAClBnmB,EAAMgG,KAAOmgB,EAAUngB,KAEvB5D,IAAS7E,EAAOyC,MAAMimB,QAASE,EAAUG,eAAkBE,QAAUL,EAAU3W,SAC5E7M,MAAO8R,EAAQ7T,KAAM4B,GAEnBJ,IAAQtF,IACNkD,EAAM4T,OAASxR,MAAS,IAC7BpC,EAAM8nB,iBACN9nB,EAAMuoB,oBAYX,MAJKtC,GAAQuC,cACZvC,EAAQuC,aAAazmB,KAAMlB,KAAMb,GAG3BA,EAAM4T,SAGdwS,SAAU,SAAUpmB,EAAOomB,GAC1B,GAAIqC,GAAKtC,EAAW1b,EAASzH,EAC5BklB,KACApB,EAAgBV,EAASU,cACzBnX,EAAM3P,EAAM8D,MAKb,IAAKgjB,GAAiBnX,EAAIvO,YAAcpB,EAAM+V,QAAyB,UAAf/V,EAAME,MAG7D,KAAQyP,GAAO9O,KAAM8O,EAAMA,EAAIhO,YAAcd,KAK5C,GAAsB,IAAjB8O,EAAIvO,WAAmBuO,EAAI8F,YAAa,GAAuB,UAAfzV,EAAME,MAAoB,CAE9E,IADAuK,KACMzH,EAAI,EAAO8jB,EAAJ9jB,EAAmBA,IAC/BmjB,EAAYC,EAAUpjB,GAGtBylB,EAAMtC,EAAUxnB,SAAW,IAEtB8L,EAASge,KAAU3rB,IACvB2N,EAASge,GAAQtC,EAAUpZ,aAC1BxP,EAAQkrB,EAAK5nB,MAAOua,MAAOzL,IAAS,EACpCpS,EAAO0D,KAAMwnB,EAAK5nB,KAAM,MAAQ8O,IAAQ5O,QAErC0J,EAASge,IACbhe,EAAQzM,KAAMmoB,EAGX1b,GAAQ1J,QACZmnB,EAAalqB,MAAO4C,KAAM+O,EAAKyW,SAAU3b,IAW7C,MAJqB2b,GAASrlB,OAAzB+lB,GACJoB,EAAalqB,MAAO4C,KAAMC,KAAMulB,SAAUA,EAASloB,MAAO4oB,KAGpDoB,GAGRD,IAAK,SAAUjoB,GACd,GAAKA,EAAOzC,EAAO0G,SAClB,MAAOjE,EAIR,IAAIgD,GAAGmgB,EAAMzf,EACZxD,EAAOF,EAAME,KACbwoB,EAAgB1oB,EAChB2oB,EAAU9nB,KAAK+nB,SAAU1oB,EAEpByoB,KACL9nB,KAAK+nB,SAAU1oB,GAASyoB,EACvBtD,GAAY/jB,KAAMpB,GAASW,KAAKgoB,WAChCzD,GAAU9jB,KAAMpB,GAASW,KAAKioB,aAGhCplB,EAAOilB,EAAQI,MAAQloB,KAAKkoB,MAAMjrB,OAAQ6qB,EAAQI,OAAUloB,KAAKkoB,MAEjE/oB,EAAQ,GAAIzC,GAAOiqB,MAAOkB,GAE1B1lB,EAAIU,EAAK3C,MACT,OAAQiC,IACPmgB,EAAOzf,EAAMV,GACbhD,EAAOmjB,GAASuF,EAAevF,EAmBhC,OAdMnjB,GAAM8D,SACX9D,EAAM8D,OAAS4kB,EAAcM,YAAc7rB,GAKb,IAA1B6C,EAAM8D,OAAO1C,WACjBpB,EAAM8D,OAAS9D,EAAM8D,OAAOnC,YAK7B3B,EAAMipB,UAAYjpB,EAAMipB,QAEjBN,EAAQ5X,OAAS4X,EAAQ5X,OAAQ/Q,EAAO0oB,GAAkB1oB,GAIlE+oB,MAAO,wHAAwHlf,MAAM,KAErI+e,YAEAE,UACCC,MAAO,4BAA4Blf,MAAM,KACzCkH,OAAQ,SAAU/Q,EAAOkpB,GAOxB,MAJoB,OAAflpB,EAAMmpB,QACVnpB,EAAMmpB,MAA6B,MAArBD,EAASE,SAAmBF,EAASE,SAAWF,EAASG,SAGjErpB,IAIT6oB,YACCE,MAAO,mGAAmGlf,MAAM,KAChHkH,OAAQ,SAAU/Q,EAAOkpB,GACxB,GAAIvkB,GAAM2kB,EAAUjZ,EACnB0F,EAASmT,EAASnT,OAClBwT,EAAcL,EAASK,WAuBxB,OApBoB,OAAfvpB,EAAMwpB,OAAqC,MAApBN,EAASO,UACpCH,EAAWtpB,EAAM8D,OAAOzC,eAAiBlE,EACzCkT,EAAMiZ,EAASjsB,gBACfsH,EAAO2kB,EAAS3kB,KAEhB3E,EAAMwpB,MAAQN,EAASO,SAAYpZ,GAAOA,EAAIqZ,YAAc/kB,GAAQA,EAAK+kB,YAAc,IAAQrZ,GAAOA,EAAIsZ,YAAchlB,GAAQA,EAAKglB,YAAc,GACnJ3pB,EAAM4pB,MAAQV,EAASW,SAAYxZ,GAAOA,EAAIyZ,WAAcnlB,GAAQA,EAAKmlB,WAAc,IAAQzZ,GAAOA,EAAI0Z,WAAcplB,GAAQA,EAAKolB,WAAc,KAI9I/pB,EAAMgqB,eAAiBT,IAC5BvpB,EAAMgqB,cAAgBT,IAAgBvpB,EAAM8D,OAASolB,EAASe,UAAYV,GAKrEvpB,EAAMmpB,OAASpT,IAAWjZ,IAC/BkD,EAAMmpB,MAAmB,EAATpT,EAAa,EAAe,EAATA,EAAa,EAAe,EAATA,EAAa,EAAI,GAGjE/V,IAITimB,SACCiE,MAECvC,UAAU,GAEXxS,OAECrQ,QAAS,WACR,GAAKjE,OAAS6kB,MAAuB7kB,KAAKsU,MACzC,IAEC,MADAtU,MAAKsU,SACE,EACN,MAAQ1P,MAOZkhB,aAAc,WAEfwD,MACCrlB,QAAS,WACR,MAAKjE,QAAS6kB,MAAuB7kB,KAAKspB,MACzCtpB,KAAKspB,QACE,GAFR,GAKDxD,aAAc,YAEfxH,OAECra,QAAS,WACR,MAAKvH,GAAOmK,SAAU7G,KAAM,UAA2B,aAAdA,KAAKX,MAAuBW,KAAKse,OACzEte,KAAKse,SACE,GAFR,GAOD6I,SAAU,SAAUhoB,GACnB,MAAOzC,GAAOmK,SAAU1H,EAAM8D,OAAQ,OAIxCsmB,cACC5B,aAAc,SAAUxoB,GAGlBA,EAAM4T,SAAW9W,IACrBkD,EAAM0oB,cAAc2B,YAAcrqB,EAAM4T,WAM5C0W,SAAU,SAAUpqB,EAAMU,EAAMZ,EAAOuqB,GAItC,GAAI9kB,GAAIlI,EAAOgG,OACd,GAAIhG,GAAOiqB,MACXxnB,GAECE,KAAMA,EACNsqB,aAAa,EACb9B,kBAGG6B,GACJhtB,EAAOyC,MAAM8E,QAASW,EAAG,KAAM7E,GAE/BrD,EAAOyC,MAAM0mB,SAAS3kB,KAAMnB,EAAM6E,GAE9BA,EAAEsiB,sBACN/nB,EAAM8nB,mBAKTvqB,EAAO4pB,YAAchqB,EAASmD,oBAC7B,SAAUM,EAAMV,EAAMsmB,GAChB5lB,EAAKN,qBACTM,EAAKN,oBAAqBJ,EAAMsmB,GAAQ,IAG1C,SAAU5lB,EAAMV,EAAMsmB,GACrB,GAAI7iB,GAAO,KAAOzD,CAEbU,GAAKL,oBAIGK,GAAM+C,KAAW1G,IAC5B2D,EAAM+C,GAAS,MAGhB/C,EAAKL,YAAaoD,EAAM6iB,KAI3BjpB,EAAOiqB,MAAQ,SAAUhkB,EAAKulB,GAE7B,MAAOloB,gBAAgBtD,GAAOiqB,OAKzBhkB,GAAOA,EAAItD,MACfW,KAAK6nB,cAAgBllB,EACrB3C,KAAKX,KAAOsD,EAAItD,KAIhBW,KAAKknB,mBAAuBvkB,EAAIinB,kBAAoBjnB,EAAI6mB,eAAgB,GACvE7mB,EAAIknB,mBAAqBlnB,EAAIknB,oBAAwBlF,GAAaC,IAInE5kB,KAAKX,KAAOsD,EAIRulB,GACJxrB,EAAOgG,OAAQ1C,KAAMkoB,GAItBloB,KAAK8pB,UAAYnnB,GAAOA,EAAImnB,WAAaptB,EAAO0L,MAGhDpI,KAAMtD,EAAO0G,UAAY,EAvBzB,GAJQ,GAAI1G,GAAOiqB,MAAOhkB,EAAKulB,IAgChCxrB,EAAOiqB,MAAMhnB,WACZunB,mBAAoBtC,GACpBoC,qBAAsBpC,GACtB6C,8BAA+B7C,GAE/BqC,eAAgB,WACf,GAAIriB,GAAI5E,KAAK6nB,aAEb7nB,MAAKknB,mBAAqBvC,GACpB/f,IAKDA,EAAEqiB,eACNriB,EAAEqiB,iBAKFriB,EAAE4kB,aAAc,IAGlB9B,gBAAiB,WAChB,GAAI9iB,GAAI5E,KAAK6nB,aAEb7nB,MAAKgnB,qBAAuBrC,GACtB/f,IAIDA,EAAE8iB,iBACN9iB,EAAE8iB,kBAKH9iB,EAAEmlB,cAAe,IAElBC,yBAA0B,WACzBhqB,KAAKynB,8BAAgC9C,GACrC3kB,KAAK0nB,oBAKPhrB,EAAO+E,MACNwoB,WAAY,YACZC,WAAY,YACV,SAAUC,EAAM/C,GAClB1qB,EAAOyC,MAAMimB,QAAS+E,IACrBrE,aAAcsB,EACdrB,SAAUqB,EAEVzB,OAAQ,SAAUxmB,GACjB,GAAIoC,GACH0B,EAASjD,KACToqB,EAAUjrB,EAAMgqB,cAChB7D,EAAYnmB,EAAMmmB,SASnB,SALM8E,GAAYA,IAAYnnB,IAAWvG,EAAOmN,SAAU5G,EAAQmnB,MACjEjrB,EAAME,KAAOimB,EAAUG,SACvBlkB,EAAM+jB,EAAU3W,QAAQ7M,MAAO9B,KAAM+B,WACrC5C,EAAME,KAAO+nB,GAEP7lB,MAMJ7E,EAAOmI,QAAQwlB,gBAEpB3tB,EAAOyC,MAAMimB,QAAQxP,QACpBsQ,MAAO,WAEN,MAAKxpB,GAAOmK,SAAU7G,KAAM,SACpB,GAIRtD,EAAOyC,MAAMmb,IAAKta,KAAM,iCAAkC,SAAU4E,GAEnE,GAAI7E,GAAO6E,EAAE3B,OACZqnB,EAAO5tB,EAAOmK,SAAU9G,EAAM,UAAarD,EAAOmK,SAAU9G,EAAM,UAAaA,EAAKuqB,KAAOruB,CACvFquB,KAAS5tB,EAAO+jB,MAAO6J,EAAM,mBACjC5tB,EAAOyC,MAAMmb,IAAKgQ,EAAM,iBAAkB,SAAUnrB,GACnDA,EAAMorB,gBAAiB,IAExB7tB,EAAO+jB,MAAO6J,EAAM,iBAAiB,MARvC5tB,IAcDirB,aAAc,SAAUxoB,GAElBA,EAAMorB,uBACHprB,GAAMorB,eACRvqB,KAAKc,aAAe3B,EAAMynB,WAC9BlqB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAKc,WAAY3B,GAAO,KAK5DknB,SAAU,WAET,MAAK3pB,GAAOmK,SAAU7G,KAAM,SACpB,GAIRtD,EAAOyC,MAAMsG,OAAQzF,KAAM,YAA3BtD,MAMGA,EAAOmI,QAAQ2lB,gBAEpB9tB,EAAOyC,MAAMimB,QAAQ7G,QAEpB2H,MAAO,WAEN,MAAK5B,GAAW7jB,KAAMT,KAAK6G,YAIP,aAAd7G,KAAKX,MAAqC,UAAdW,KAAKX,QACrC3C,EAAOyC,MAAMmb,IAAKta,KAAM,yBAA0B,SAAUb,GACjB,YAArCA,EAAM0oB,cAAc4C,eACxBzqB,KAAK0qB,eAAgB,KAGvBhuB,EAAOyC,MAAMmb,IAAKta,KAAM,gBAAiB,SAAUb,GAC7Ca,KAAK0qB,gBAAkBvrB,EAAMynB,YACjC5mB,KAAK0qB,eAAgB,GAGtBhuB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAMb,GAAO,OAGzC,IAGRzC,EAAOyC,MAAMmb,IAAKta,KAAM,yBAA0B,SAAU4E,GAC3D,GAAI7E,GAAO6E,EAAE3B,MAERqhB,GAAW7jB,KAAMV,EAAK8G,YAAenK,EAAO+jB,MAAO1gB,EAAM,mBAC7DrD,EAAOyC,MAAMmb,IAAKva,EAAM,iBAAkB,SAAUZ,IAC9Ca,KAAKc,YAAe3B,EAAMwqB,aAAgBxqB,EAAMynB,WACpDlqB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAKc,WAAY3B,GAAO,KAG3DzC,EAAO+jB,MAAO1gB,EAAM,iBAAiB,MATvCrD,IAcDipB,OAAQ,SAAUxmB,GACjB,GAAIY,GAAOZ,EAAM8D,MAGjB,OAAKjD,QAASD,GAAQZ,EAAMwqB,aAAexqB,EAAMynB,WAA4B,UAAd7mB,EAAKV,MAAkC,aAAdU,EAAKV,KACrFF,EAAMmmB,UAAU3W,QAAQ7M,MAAO9B,KAAM+B,WAD7C,GAKDskB,SAAU,WAGT,MAFA3pB,GAAOyC,MAAMsG,OAAQzF,KAAM,aAEnBskB,EAAW7jB,KAAMT,KAAK6G,aAM3BnK,EAAOmI,QAAQ8lB,gBACpBjuB,EAAO+E,MAAO6S,MAAO,UAAWgV,KAAM,YAAc,SAAUa,EAAM/C,GAGnE,GAAIwD,GAAW,EACdjc,EAAU,SAAUxP,GACnBzC,EAAOyC,MAAMsqB,SAAUrC,EAAKjoB,EAAM8D,OAAQvG,EAAOyC,MAAMioB,IAAKjoB,IAAS,GAGvEzC,GAAOyC,MAAMimB,QAASgC,IACrBlB,MAAO,WACc,IAAf0E,KACJtuB,EAAS8C,iBAAkB+qB,EAAMxb,GAAS,IAG5C0X,SAAU,WACW,MAAbuE,GACNtuB,EAASmD,oBAAqB0qB,EAAMxb,GAAS,OAOlDjS,EAAOsB,GAAG0E,QAETmoB,GAAI,SAAU7F,EAAOlnB,EAAUqH,EAAMnH,EAAiBqlB,GACrD,GAAIhkB,GAAMyrB,CAGV,IAAsB,gBAAV9F,GAAqB,CAEP,gBAAblnB,KAEXqH,EAAOA,GAAQrH,EACfA,EAAW7B,EAEZ,KAAMoD,IAAQ2lB,GACbhlB,KAAK6qB,GAAIxrB,EAAMvB,EAAUqH,EAAM6f,EAAO3lB,GAAQgkB,EAE/C,OAAOrjB,MAmBR,GAhBa,MAARmF,GAAsB,MAANnH,GAEpBA,EAAKF,EACLqH,EAAOrH,EAAW7B,GACD,MAAN+B,IACc,gBAAbF,IAEXE,EAAKmH,EACLA,EAAOlJ,IAGP+B,EAAKmH,EACLA,EAAOrH,EACPA,EAAW7B,IAGR+B,KAAO,EACXA,EAAK4mB,OACC,KAAM5mB,EACZ,MAAOgC,KAaR,OAVa,KAARqjB,IACJyH,EAAS9sB,EACTA,EAAK,SAAUmB,GAGd,MADAzC,KAASwH,IAAK/E,GACP2rB,EAAOhpB,MAAO9B,KAAM+B,YAG5B/D,EAAG6J,KAAOijB,EAAOjjB,OAAUijB,EAAOjjB,KAAOnL,EAAOmL,SAE1C7H,KAAKyB,KAAM,WACjB/E,EAAOyC,MAAMmb,IAAKta,KAAMglB,EAAOhnB,EAAImH,EAAMrH,MAG3CulB,IAAK,SAAU2B,EAAOlnB,EAAUqH,EAAMnH,GACrC,MAAOgC,MAAK6qB,GAAI7F,EAAOlnB,EAAUqH,EAAMnH,EAAI,IAE5CkG,IAAK,SAAU8gB,EAAOlnB,EAAUE,GAC/B,GAAIsnB,GAAWjmB,CACf,IAAK2lB,GAASA,EAAMiC,gBAAkBjC,EAAMM,UAQ3C,MANAA,GAAYN,EAAMM,UAClB5oB,EAAQsoB,EAAMsC,gBAAiBpjB,IAC9BohB,EAAUU,UAAYV,EAAUG,SAAW,IAAMH,EAAUU,UAAYV,EAAUG,SACjFH,EAAUxnB,SACVwnB,EAAU3W,SAEJ3O,IAER,IAAsB,gBAAVglB,GAAqB,CAEhC,IAAM3lB,IAAQ2lB,GACbhlB,KAAKkE,IAAK7E,EAAMvB,EAAUknB,EAAO3lB,GAElC,OAAOW,MAUR,OARKlC,KAAa,GAA6B,kBAAbA,MAEjCE,EAAKF,EACLA,EAAW7B,GAEP+B,KAAO,IACXA,EAAK4mB,IAEC5kB,KAAKyB,KAAK,WAChB/E,EAAOyC,MAAMsG,OAAQzF,KAAMglB,EAAOhnB,EAAIF,MAIxCmG,QAAS,SAAU5E,EAAM8F,GACxB,MAAOnF,MAAKyB,KAAK,WAChB/E,EAAOyC,MAAM8E,QAAS5E,EAAM8F,EAAMnF,SAGpC+qB,eAAgB,SAAU1rB,EAAM8F,GAC/B,GAAIpF,GAAOC,KAAK,EAChB,OAAKD,GACGrD,EAAOyC,MAAM8E,QAAS5E,EAAM8F,EAAMpF,GAAM,GADhD,IAKF,IAAIirB,IAAW,iBACdC,GAAe,iCACfC,GAAgBxuB,EAAO4U,KAAKxR,MAAMoM,aAElCif,IACCC,UAAU,EACVC,UAAU,EACVpK,MAAM,EACNqK,MAAM,EAGR5uB,GAAOsB,GAAG0E,QACTtC,KAAM,SAAUtC,GACf,GAAIqE,GACHZ,KACA6Y,EAAOpa,KACPoC,EAAMgY,EAAKla,MAEZ,IAAyB,gBAAbpC,GACX,MAAOkC,MAAKqB,UAAW3E,EAAQoB,GAAWoS,OAAO,WAChD,IAAM/N,EAAI,EAAOC,EAAJD,EAASA,IACrB,GAAKzF,EAAOmN,SAAUuQ,EAAMjY,GAAKnC,MAChC,OAAO,IAMX,KAAMmC,EAAI,EAAOC,EAAJD,EAASA,IACrBzF,EAAO0D,KAAMtC,EAAUsc,EAAMjY,GAAKZ,EAMnC,OAFAA,GAAMvB,KAAKqB,UAAWe,EAAM,EAAI1F,EAAOwc,OAAQ3X,GAAQA,GACvDA,EAAIzD,SAAWkC,KAAKlC,SAAWkC,KAAKlC,SAAW,IAAMA,EAAWA,EACzDyD,GAGRyS,IAAK,SAAU/Q,GACd,GAAId,GACHopB,EAAU7uB,EAAQuG,EAAQjD,MAC1BoC,EAAMmpB,EAAQrrB,MAEf,OAAOF,MAAKkQ,OAAO,WAClB,IAAM/N,EAAI,EAAOC,EAAJD,EAASA,IACrB,GAAKzF,EAAOmN,SAAU7J,KAAMurB,EAAQppB,IACnC,OAAO,KAMX0R,IAAK,SAAU/V,GACd,MAAOkC,MAAKqB,UAAWmqB,GAAOxrB,KAAMlC,OAAgB,KAGrDoS,OAAQ,SAAUpS,GACjB,MAAOkC,MAAKqB,UAAWmqB,GAAOxrB,KAAMlC,OAAgB,KAGrD2tB,GAAI,SAAU3tB,GACb,QAAS0tB,GACRxrB,KAIoB,gBAAblC,IAAyBotB,GAAczqB,KAAM3C,GACnDpB,EAAQoB,GACRA,OACD,GACCoC,QAGHwrB,QAAS,SAAU1Z,EAAWjU,GAC7B,GAAI+Q,GACH3M,EAAI,EACJqF,EAAIxH,KAAKE,OACTqB,KACAoqB,EAAMT,GAAczqB,KAAMuR,IAAoC,gBAAdA,GAC/CtV,EAAQsV,EAAWjU,GAAWiC,KAAKjC,SACnC,CAEF,MAAYyJ,EAAJrF,EAAOA,IACd,IAAM2M,EAAM9O,KAAKmC,GAAI2M,GAAOA,IAAQ/Q,EAAS+Q,EAAMA,EAAIhO,WAEtD,GAAoB,GAAfgO,EAAIvO,WAAkBorB,EAC1BA,EAAIpR,MAAMzL,GAAO,GAGA,IAAjBA,EAAIvO,UACH7D,EAAO0D,KAAKmQ,gBAAgBzB,EAAKkD,IAAc,CAEhDlD,EAAMvN,EAAIpE,KAAM2R,EAChB,OAKH,MAAO9O,MAAKqB,UAAWE,EAAIrB,OAAS,EAAIxD,EAAOwc,OAAQ3X,GAAQA,IAKhEgZ,MAAO,SAAUxa,GAGhB,MAAMA,GAKe,gBAATA,GACJrD,EAAO2K,QAASrH,KAAK,GAAItD,EAAQqD,IAIlCrD,EAAO2K,QAEbtH,EAAKH,OAASG,EAAK,GAAKA,EAAMC,MAXrBA,KAAK,IAAMA,KAAK,GAAGc,WAAed,KAAKgC,QAAQ4pB,UAAU1rB,OAAS,IAc7Eoa,IAAK,SAAUxc,EAAUC,GACxB,GAAIolB,GAA0B,gBAAbrlB,GACfpB,EAAQoB,EAAUC,GAClBrB,EAAOsE,UAAWlD,GAAYA,EAASyC,UAAazC,GAAaA,GAClEiB,EAAMrC,EAAO2D,MAAOL,KAAKmB,MAAOgiB,EAEjC,OAAOnjB,MAAKqB,UAAW3E,EAAOwc,OAAOna,KAGtC8sB,QAAS,SAAU/tB,GAClB,MAAOkC,MAAKsa,IAAiB,MAAZxc,EAChBkC,KAAKwB,WAAaxB,KAAKwB,WAAW0O,OAAOpS,MAK5C,SAASguB,IAAShd,EAAKsD,GACtB,EACCtD,GAAMA,EAAKsD,SACFtD,GAAwB,IAAjBA,EAAIvO,SAErB,OAAOuO,GAGRpS,EAAO+E,MACNgO,OAAQ,SAAU1P,GACjB,GAAI0P,GAAS1P,EAAKe,UAClB,OAAO2O,IAA8B,KAApBA,EAAOlP,SAAkBkP,EAAS,MAEpDsc,QAAS,SAAUhsB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,eAE1BisB,aAAc,SAAUjsB,EAAMoC,EAAG8pB,GAChC,MAAOvvB,GAAO0V,IAAKrS,EAAM,aAAcksB,IAExChL,KAAM,SAAUlhB,GACf,MAAO+rB,IAAS/rB,EAAM,gBAEvBurB,KAAM,SAAUvrB,GACf,MAAO+rB,IAAS/rB,EAAM,oBAEvBmsB,QAAS,SAAUnsB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,gBAE1B6rB,QAAS,SAAU7rB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,oBAE1BosB,UAAW,SAAUpsB,EAAMoC,EAAG8pB,GAC7B,MAAOvvB,GAAO0V,IAAKrS,EAAM,cAAeksB,IAEzCG,UAAW,SAAUrsB,EAAMoC,EAAG8pB,GAC7B,MAAOvvB,GAAO0V,IAAKrS,EAAM,kBAAmBksB,IAE7CI,SAAU,SAAUtsB,GACnB,MAAOrD,GAAOovB,SAAW/rB,EAAKe,gBAAmBiP,WAAYhQ,IAE9DqrB,SAAU,SAAUrrB,GACnB,MAAOrD,GAAOovB,QAAS/rB,EAAKgQ,aAE7Bsb,SAAU,SAAUtrB,GACnB,MAAOrD,GAAOmK,SAAU9G,EAAM,UAC7BA,EAAKusB,iBAAmBvsB,EAAKwsB,cAAcjwB,SAC3CI,EAAO2D,SAAWN,EAAK2F,cAEvB,SAAU5C,EAAM9E,GAClBtB,EAAOsB,GAAI8E,GAAS,SAAUmpB,EAAOnuB,GACpC,GAAIyD,GAAM7E,EAAO4F,IAAKtC,KAAMhC,EAAIiuB,EAsBhC,OApB0B,UAArBnpB,EAAKzF,MAAO,MAChBS,EAAWmuB,GAGPnuB,GAAgC,gBAAbA,KACvByD,EAAM7E,EAAOwT,OAAQpS,EAAUyD,IAG3BvB,KAAKE,OAAS,IAEZirB,GAAkBroB,KACvBvB,EAAM7E,EAAOwc,OAAQ3X,IAIjB0pB,GAAaxqB,KAAMqC,KACvBvB,EAAMA,EAAIirB,YAILxsB,KAAKqB,UAAWE,MAIzB7E,EAAOgG,QACNwN,OAAQ,SAAUoB,EAAMhQ,EAAOuS,GAC9B,GAAI9T,GAAOuB,EAAO,EAMlB,OAJKuS,KACJvC,EAAO,QAAUA,EAAO,KAGD,IAAjBhQ,EAAMpB,QAAkC,IAAlBH,EAAKQ,SACjC7D,EAAO0D,KAAKmQ,gBAAiBxQ,EAAMuR,IAAWvR,MAC9CrD,EAAO0D,KAAKwJ,QAAS0H,EAAM5U,EAAO+K,KAAMnG,EAAO,SAAUvB,GACxD,MAAyB,KAAlBA,EAAKQ,aAIf6R,IAAK,SAAUrS,EAAMqS,EAAK6Z,GACzB,GAAIrY,MACH9E,EAAM/O,EAAMqS,EAEb,OAAQtD,GAAwB,IAAjBA,EAAIvO,WAAmB0rB,IAAUhwB,GAA8B,IAAjB6S,EAAIvO,WAAmB7D,EAAQoS,GAAM2c,GAAIQ,IAC/E,IAAjBnd,EAAIvO,UACRqT,EAAQzW,KAAM2R,GAEfA,EAAMA,EAAIsD,EAEX,OAAOwB,IAGRkY,QAAS,SAAUW,EAAG1sB,GACrB,GAAI2sB,KAEJ,MAAQD,EAAGA,EAAIA,EAAExd,YACI,IAAfwd,EAAElsB,UAAkBksB,IAAM1sB,GAC9B2sB,EAAEvvB,KAAMsvB,EAIV,OAAOC,KAKT,SAASlB,IAAQja,EAAUob,EAAW9Y,GACrC,GAAKnX,EAAOiE,WAAYgsB,GACvB,MAAOjwB,GAAO+K,KAAM8J,EAAU,SAAUxR,EAAMoC,GAE7C,QAASwqB,EAAUzrB,KAAMnB,EAAMoC,EAAGpC,KAAW8T,GAK/C,IAAK8Y,EAAUpsB,SACd,MAAO7D,GAAO+K,KAAM8J,EAAU,SAAUxR,GACvC,MAASA,KAAS4sB,IAAgB9Y,GAKpC,IAA0B,gBAAd8Y,GAAyB,CACpC,GAAK3B,GAASvqB,KAAMksB,GACnB,MAAOjwB,GAAOwT,OAAQyc,EAAWpb,EAAUsC,EAG5C8Y,GAAYjwB,EAAOwT,OAAQyc,EAAWpb,GAGvC,MAAO7U,GAAO+K,KAAM8J,EAAU,SAAUxR,GACvC,MAASrD,GAAO2K,QAAStH,EAAM4sB,IAAe,IAAQ9Y,IAGxD,QAAS+Y,IAAoBtwB,GAC5B,GAAIyd,GAAO8S,GAAU7jB,MAAO,KAC3B8jB,EAAWxwB,EAAS6hB,wBAErB,IAAK2O,EAASvnB,cACb,MAAQwU,EAAK7Z,OACZ4sB,EAASvnB,cACRwU,EAAKpP,MAIR,OAAOmiB,GAGR,GAAID,IAAY,6JAEfE,GAAgB,6BAChBC,GAAmB7hB,OAAO,OAAS0hB,GAAY,WAAY,KAC3DI,GAAqB,OACrBC,GAAY,0EACZC,GAAW,YACXC,GAAS,UACTC,GAAQ,YACRC,GAAe,0BACfC,GAA8B,wBAE9BC,GAAW,oCACXC,GAAc,4BACdC,GAAoB,cACpBC,GAAe,2CAGfC,IACCxK,QAAU,EAAG,+BAAgC,aAC7CyK,QAAU,EAAG,aAAc,eAC3BC,MAAQ,EAAG,QAAS,UACpBC,OAAS,EAAG,WAAY,aACxBC,OAAS,EAAG,UAAW,YACvBC,IAAM,EAAG,iBAAkB,oBAC3BC,KAAO,EAAG,mCAAoC,uBAC9CC,IAAM,EAAG,qBAAsB,yBAI/BhH,SAAUzqB,EAAOmI,QAAQkY,eAAkB,EAAG,GAAI,KAAS,EAAG,SAAU,WAEzEqR,GAAexB,GAAoBtwB,GACnC+xB,GAAcD,GAAaxe,YAAatT,EAASiJ,cAAc,OAEhEqoB,IAAQU,SAAWV,GAAQxK,OAC3BwK,GAAQ9Q,MAAQ8Q,GAAQW,MAAQX,GAAQY,SAAWZ,GAAQa,QAAUb,GAAQI,MAC7EJ,GAAQc,GAAKd,GAAQO,GAErBzxB,EAAOsB,GAAG0E,QACTuE,KAAM,SAAUF,GACf,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAU+G,GACrC,MAAOA,KAAU9K,EAChBS,EAAOuK,KAAMjH,MACbA,KAAKgV,QAAQ2Z,QAAU3uB,KAAK,IAAMA,KAAK,GAAGQ,eAAiBlE,GAAWsyB,eAAgB7nB,KACrF,KAAMA,EAAOhF,UAAU7B,SAG3ByuB,OAAQ,WACP,MAAO3uB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAI0C,GAAS6rB,GAAoB9uB,KAAMD,EACvCkD,GAAO2M,YAAa7P,OAKvBgvB,QAAS,WACR,MAAO/uB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAI0C,GAAS6rB,GAAoB9uB,KAAMD,EACvCkD,GAAO+rB,aAAcjvB,EAAMkD,EAAO8M,gBAKrCkf,OAAQ,WACP,MAAOjvB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACrCC,KAAKc,YACTd,KAAKc,WAAWkuB,aAAcjvB,EAAMC,SAKvCkvB,MAAO,WACN,MAAOlvB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACrCC,KAAKc,YACTd,KAAKc,WAAWkuB,aAAcjvB,EAAMC,KAAKiP,gBAM5CxJ,OAAQ,SAAU3H,EAAUqxB,GAC3B,GAAIpvB,GACHuB,EAAQxD,EAAWpB,EAAOwT,OAAQpS,EAAUkC,MAASA,KACrDmC,EAAI,CAEL,MAA6B,OAApBpC,EAAOuB,EAAMa,IAAaA,IAE5BgtB,GAA8B,IAAlBpvB,EAAKQ,UACtB7D,EAAOyjB,UAAWiP,GAAQrvB,IAGtBA,EAAKe,aACJquB,GAAYzyB,EAAOmN,SAAU9J,EAAKS,cAAeT,IACrDsvB,GAAeD,GAAQrvB,EAAM,WAE9BA,EAAKe,WAAW0N,YAAazO,GAI/B,OAAOC,OAGRgV,MAAO,WACN,GAAIjV,GACHoC,EAAI,CAEL,MAA4B,OAAnBpC,EAAOC,KAAKmC,IAAaA,IAAM,CAEhB,IAAlBpC,EAAKQ,UACT7D,EAAOyjB,UAAWiP,GAAQrvB,GAAM,GAIjC,OAAQA,EAAKgQ,WACZhQ,EAAKyO,YAAazO,EAAKgQ,WAKnBhQ,GAAKgD,SAAWrG,EAAOmK,SAAU9G,EAAM,YAC3CA,EAAKgD,QAAQ7C,OAAS,GAIxB,MAAOF,OAGRgD,MAAO,SAAUssB,EAAeC,GAI/B,MAHAD,GAAiC,MAAjBA,GAAwB,EAAQA,EAChDC,EAAyC,MAArBA,EAA4BD,EAAgBC,EAEzDvvB,KAAKsC,IAAK,WAChB,MAAO5F,GAAOsG,MAAOhD,KAAMsvB,EAAeC,MAI5CC,KAAM,SAAUzoB,GACf,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAU+G,GACrC,GAAIhH,GAAOC,KAAK,OACfmC,EAAI,EACJqF,EAAIxH,KAAKE,MAEV,IAAK6G,IAAU9K,EACd,MAAyB,KAAlB8D,EAAKQ,SACXR,EAAK+P,UAAUvM,QAASwpB,GAAe,IACvC9wB,CAIF,MAAsB,gBAAV8K,IAAuBumB,GAAa7sB,KAAMsG,KACnDrK,EAAOmI,QAAQkY,eAAkBiQ,GAAavsB,KAAMsG,KACpDrK,EAAOmI,QAAQgY,mBAAsBoQ,GAAmBxsB,KAAMsG,IAC/D6mB,IAAWT,GAAShtB,KAAM4G,KAAY,GAAI,KAAM,GAAGD,gBAAkB,CAEtEC,EAAQA,EAAMxD,QAAS2pB,GAAW,YAElC,KACC,KAAW1lB,EAAJrF,EAAOA,IAEbpC,EAAOC,KAAKmC,OACW,IAAlBpC,EAAKQ,WACT7D,EAAOyjB,UAAWiP,GAAQrvB,GAAM,IAChCA,EAAK+P,UAAY/I,EAInBhH,GAAO,EAGN,MAAM6E,KAGJ7E,GACJC,KAAKgV,QAAQ2Z,OAAQ5nB,IAEpB,KAAMA,EAAOhF,UAAU7B,SAG3BuvB,YAAa,WACZ,GAEC9tB,GAAOjF,EAAO4F,IAAKtC,KAAM,SAAUD,GAClC,OAASA,EAAKkP,YAAalP,EAAKe,cAEjCqB,EAAI,CAmBL,OAhBAnC,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACnC,GAAIkhB,GAAOtf,EAAMQ,KAChBsN,EAAS9N,EAAMQ,IAEXsN,KAECwR,GAAQA,EAAKngB,aAAe2O,IAChCwR,EAAOjhB,KAAKiP,aAEbvS,EAAQsD,MAAOyF,SACfgK,EAAOuf,aAAcjvB,EAAMkhB,MAG1B,GAGI9e,EAAInC,KAAOA,KAAKyF,UAGxBlG,OAAQ,SAAUzB,GACjB,MAAOkC,MAAKyF,OAAQ3H,GAAU,IAG/B+wB,SAAU,SAAUltB,EAAMD,EAAUguB,GAGnC/tB,EAAO3E,EAAY8E,SAAWH,EAE9B,IAAIK,GAAOuN,EAAMogB,EAChBrqB,EAASkK,EAAK+M,EACdpa,EAAI,EACJqF,EAAIxH,KAAKE,OACTijB,EAAMnjB,KACN4vB,EAAWpoB,EAAI,EACfT,EAAQpF,EAAK,GACbhB,EAAajE,EAAOiE,WAAYoG,EAGjC,IAAKpG,KAAsB,GAAL6G,GAA2B,gBAAVT,IAAsBrK,EAAOmI,QAAQwZ,aAAemP,GAAS/sB,KAAMsG,GACzG,MAAO/G,MAAKyB,KAAK,SAAU8Y,GAC1B,GAAIH,GAAO+I,EAAIlhB,GAAIsY,EACd5Z,KACJgB,EAAK,GAAKoF,EAAM7F,KAAMlB,KAAMua,EAAOH,EAAKoV,SAEzCpV,EAAKyU,SAAUltB,EAAMD,EAAUguB,IAIjC,IAAKloB,IACJ+U,EAAW7f,EAAO8I,cAAe7D,EAAM3B,KAAM,GAAIQ,eAAe,GAAQkvB,GAAqB1vB,MAC7FgC,EAAQua,EAASxM,WAEmB,IAA/BwM,EAAS7W,WAAWxF,SACxBqc,EAAWva,GAGPA,GAAQ,CAMZ,IALAsD,EAAU5I,EAAO4F,IAAK8sB,GAAQ7S,EAAU,UAAYsT,IACpDF,EAAarqB,EAAQpF,OAITsH,EAAJrF,EAAOA,IACdoN,EAAOgN,EAEFpa,IAAMytB,IACVrgB,EAAO7S,EAAOsG,MAAOuM,GAAM,GAAM,GAG5BogB,GACJjzB,EAAO2D,MAAOiF,EAAS8pB,GAAQ7f,EAAM,YAIvC7N,EAASR,KAAMlB,KAAKmC,GAAIoN,EAAMpN,EAG/B,IAAKwtB,EAOJ,IANAngB,EAAMlK,EAASA,EAAQpF,OAAS,GAAIM,cAGpC9D,EAAO4F,IAAKgD,EAASwqB,IAGf3tB,EAAI,EAAOwtB,EAAJxtB,EAAgBA,IAC5BoN,EAAOjK,EAASnD,GACXsrB,GAAYhtB,KAAM8O,EAAKlQ,MAAQ,MAClC3C,EAAO+jB,MAAOlR,EAAM,eAAkB7S,EAAOmN,SAAU2F,EAAKD,KAExDA,EAAK5M,IAETjG,EAAOqzB,SAAUxgB,EAAK5M,KAEtBjG,EAAO+J,YAAc8I,EAAKtI,MAAQsI,EAAKuC,aAAevC,EAAKO,WAAa,IAAKvM,QAASoqB,GAAc,KAOxGpR,GAAWva,EAAQ,KAIrB,MAAOhC,QAMT,SAAS8uB,IAAoB/uB,EAAMiwB,GAClC,MAAOtzB,GAAOmK,SAAU9G,EAAM,UAC7BrD,EAAOmK,SAA+B,IAArBmpB,EAAQzvB,SAAiByvB,EAAUA,EAAQjgB,WAAY,MAExEhQ,EAAKwG,qBAAqB,SAAS,IAClCxG,EAAK6P,YAAa7P,EAAKS,cAAc+E,cAAc,UACpDxF,EAIF,QAAS8vB,IAAe9vB,GAEvB,MADAA,GAAKV,MAA6C,OAArC3C,EAAO0D,KAAKQ,KAAMb,EAAM,SAAqB,IAAMA,EAAKV,KAC9DU,EAER,QAAS+vB,IAAe/vB,GACvB,GAAID,GAAQ4tB,GAAkBvtB,KAAMJ,EAAKV,KAMzC,OALKS,GACJC,EAAKV,KAAOS,EAAM,GAElBC,EAAKgO,gBAAgB,QAEfhO,EAIR,QAASsvB,IAAe/tB,EAAO2uB,GAC9B,GAAIlwB,GACHoC,EAAI,CACL,MAA6B,OAApBpC,EAAOuB,EAAMa,IAAaA,IAClCzF,EAAO+jB,MAAO1gB,EAAM,cAAekwB,GAAevzB,EAAO+jB,MAAOwP,EAAY9tB,GAAI,eAIlF,QAAS+tB,IAAgBvtB,EAAKwtB,GAE7B,GAAuB,IAAlBA,EAAK5vB,UAAmB7D,EAAO6jB,QAAS5d,GAA7C,CAIA,GAAItD,GAAM8C,EAAGqF,EACZ4oB,EAAU1zB,EAAO+jB,MAAO9d,GACxB0tB,EAAU3zB,EAAO+jB,MAAO0P,EAAMC,GAC9BnL,EAASmL,EAAQnL,MAElB,IAAKA,EAAS,OACNoL,GAAQ1K,OACf0K,EAAQpL,SAER,KAAM5lB,IAAQ4lB,GACb,IAAM9iB,EAAI,EAAGqF,EAAIyd,EAAQ5lB,GAAOa,OAAYsH,EAAJrF,EAAOA,IAC9CzF,EAAOyC,MAAMmb,IAAK6V,EAAM9wB,EAAM4lB,EAAQ5lB,GAAQ8C,IAM5CkuB,EAAQlrB,OACZkrB,EAAQlrB,KAAOzI,EAAOgG,UAAY2tB,EAAQlrB,QAI5C,QAASmrB,IAAoB3tB,EAAKwtB,GACjC,GAAItpB,GAAUjC,EAAGO,CAGjB,IAAuB,IAAlBgrB,EAAK5vB,SAAV,CAOA,GAHAsG,EAAWspB,EAAKtpB,SAASC,eAGnBpK,EAAOmI,QAAQgZ,cAAgBsS,EAAMzzB,EAAO0G,SAAY,CAC7D+B,EAAOzI,EAAO+jB,MAAO0P,EAErB,KAAMvrB,IAAKO,GAAK8f,OACfvoB,EAAO4pB,YAAa6J,EAAMvrB,EAAGO,EAAKwgB,OAInCwK,GAAKpiB,gBAAiBrR,EAAO0G,SAIZ,WAAbyD,GAAyBspB,EAAKlpB,OAAStE,EAAIsE,MAC/C4oB,GAAeM,GAAOlpB,KAAOtE,EAAIsE,KACjC6oB,GAAeK,IAIS,WAAbtpB,GACNspB,EAAKrvB,aACTqvB,EAAK3S,UAAY7a,EAAI6a,WAOjB9gB,EAAOmI,QAAQyY,YAAgB3a,EAAImN,YAAcpT,EAAOmB,KAAKsyB,EAAKrgB,aACtEqgB,EAAKrgB,UAAYnN,EAAImN,YAGE,UAAbjJ,GAAwB0mB,GAA4B9sB,KAAMkC,EAAItD,OAKzE8wB,EAAKI,eAAiBJ,EAAKtb,QAAUlS,EAAIkS,QAIpCsb,EAAKppB,QAAUpE,EAAIoE,QACvBopB,EAAKppB,MAAQpE,EAAIoE,QAKM,WAAbF,EACXspB,EAAKK,gBAAkBL,EAAKrb,SAAWnS,EAAI6tB,iBAInB,UAAb3pB,GAAqC,aAAbA,KACnCspB,EAAKlX,aAAetW,EAAIsW,eAI1Bvc,EAAO+E,MACNgvB,SAAU,SACVC,UAAW,UACX1B,aAAc,SACd2B,YAAa,QACbC,WAAY,eACV,SAAU9tB,EAAMulB,GAClB3rB,EAAOsB,GAAI8E,GAAS,SAAUhF,GAC7B,GAAIwD,GACHa,EAAI,EACJZ,KACAsvB,EAASn0B,EAAQoB,GACjBoE,EAAO2uB,EAAO3wB,OAAS,CAExB,MAAagC,GAALC,EAAWA,IAClBb,EAAQa,IAAMD,EAAOlC,KAAOA,KAAKgD,OAAM,GACvCtG,EAAQm0B,EAAO1uB,IAAMkmB,GAAY/mB,GAGjCpE,EAAU4E,MAAOP,EAAKD,EAAMH,MAG7B,OAAOnB,MAAKqB,UAAWE,KAIzB,SAAS6tB,IAAQrxB,EAASsS,GACzB,GAAI/O,GAAOvB,EACVoC,EAAI,EACJ2uB,QAAe/yB,GAAQwI,uBAAyBnK,EAAoB2B,EAAQwI,qBAAsB8J,GAAO,WACjGtS,GAAQ8P,mBAAqBzR,EAAoB2B,EAAQ8P,iBAAkBwC,GAAO,KACzFpU,CAEF,KAAM60B,EACL,IAAMA,KAAYxvB,EAAQvD,EAAQ2H,YAAc3H,EAA8B,OAApBgC,EAAOuB,EAAMa,IAAaA,KAC7EkO,GAAO3T,EAAOmK,SAAU9G,EAAMsQ,GACnCygB,EAAM3zB,KAAM4C,GAEZrD,EAAO2D,MAAOywB,EAAO1B,GAAQrvB,EAAMsQ,GAKtC,OAAOA,KAAQpU,GAAaoU,GAAO3T,EAAOmK,SAAU9I,EAASsS,GAC5D3T,EAAO2D,OAAStC,GAAW+yB,GAC3BA,EAIF,QAASC,IAAmBhxB,GACtBwtB,GAA4B9sB,KAAMV,EAAKV,QAC3CU,EAAKwwB,eAAiBxwB,EAAK8U,SAI7BnY,EAAOgG,QACNM,MAAO,SAAUjD,EAAMuvB,EAAeC,GACrC,GAAIyB,GAAczhB,EAAMvM,EAAOb,EAAG8uB,EACjCC,EAASx0B,EAAOmN,SAAU9J,EAAKS,cAAeT,EAW/C,IATKrD,EAAOmI,QAAQyY,YAAc5gB,EAAOyc,SAASpZ,KAAUitB,GAAavsB,KAAM,IAAMV,EAAK8G,SAAW,KACpG7D,EAAQjD,EAAKwd,WAAW,IAIxB8Q,GAAYve,UAAY/P,EAAKyd,UAC7B6Q,GAAY7f,YAAaxL,EAAQqrB,GAAYte,eAGvCrT,EAAOmI,QAAQgZ,cAAiBnhB,EAAOmI,QAAQmZ,gBACjC,IAAlBje,EAAKQ,UAAoC,KAAlBR,EAAKQ,UAAqB7D,EAAOyc,SAASpZ,IAOnE,IAJAixB,EAAe5B,GAAQpsB,GACvBiuB,EAAc7B,GAAQrvB,GAGhBoC,EAAI,EAA8B,OAA1BoN,EAAO0hB,EAAY9uB,MAAeA,EAE1C6uB,EAAa7uB,IACjBmuB,GAAoB/gB,EAAMyhB,EAAa7uB,GAM1C,IAAKmtB,EACJ,GAAKC,EAIJ,IAHA0B,EAAcA,GAAe7B,GAAQrvB,GACrCixB,EAAeA,GAAgB5B,GAAQpsB,GAEjCb,EAAI,EAA8B,OAA1BoN,EAAO0hB,EAAY9uB,IAAaA,IAC7C+tB,GAAgB3gB,EAAMyhB,EAAa7uB,QAGpC+tB,IAAgBnwB,EAAMiD,EAaxB,OARAguB,GAAe5B,GAAQpsB,EAAO,UACzBguB,EAAa9wB,OAAS,GAC1BmvB,GAAe2B,GAAeE,GAAU9B,GAAQrvB,EAAM,WAGvDixB,EAAeC,EAAc1hB,EAAO,KAG7BvM,GAGRwC,cAAe,SAAUlE,EAAOvD,EAASuH,EAAS6rB,GACjD,GAAI9uB,GAAGtC,EAAM8J,EACZ5D,EAAKoK,EAAKyM,EAAOsU,EACjB5pB,EAAIlG,EAAMpB,OAGVmxB,EAAOzE,GAAoB7uB,GAE3BuzB,KACAnvB,EAAI,CAEL,MAAYqF,EAAJrF,EAAOA,IAGd,GAFApC,EAAOuB,EAAOa,GAETpC,GAAiB,IAATA,EAGZ,GAA6B,WAAxBrD,EAAO2C,KAAMU,GACjBrD,EAAO2D,MAAOixB,EAAOvxB,EAAKQ,UAAaR,GAASA,OAG1C,IAAMstB,GAAM5sB,KAAMV,GAIlB,CACNkG,EAAMA,GAAOorB,EAAKzhB,YAAa7R,EAAQwH,cAAc,QAGrD8K,GAAQ8c,GAAShtB,KAAMJ,KAAW,GAAI,KAAM,GAAG+G,cAC/CsqB,EAAOxD,GAASvd,IAASud,GAAQzG,SAEjClhB,EAAI6J,UAAYshB,EAAK,GAAKrxB,EAAKwD,QAAS2pB,GAAW,aAAgBkE,EAAK,GAGxE/uB,EAAI+uB,EAAK,EACT,OAAQ/uB,IACP4D,EAAMA,EAAIuN,SASX,KALM9W,EAAOmI,QAAQgY,mBAAqBoQ,GAAmBxsB,KAAMV,IAClEuxB,EAAMn0B,KAAMY,EAAQ6wB,eAAgB3B,GAAmB9sB,KAAMJ,GAAO,MAI/DrD,EAAOmI,QAAQiY,MAAQ,CAG5B/c,EAAe,UAARsQ,GAAoB+c,GAAO3sB,KAAMV,GAI3B,YAAZqxB,EAAK,IAAqBhE,GAAO3sB,KAAMV,GAEtC,EADAkG,EAJDA,EAAI8J,WAOL1N,EAAItC,GAAQA,EAAK2F,WAAWxF,MAC5B,OAAQmC,IACF3F,EAAOmK,SAAWiW,EAAQ/c,EAAK2F,WAAWrD,GAAK,WAAcya,EAAMpX,WAAWxF,QAClFH,EAAKyO,YAAasO,GAKrBpgB,EAAO2D,MAAOixB,EAAOrrB,EAAIP,YAGzBO,EAAI6L,YAAc,EAGlB,OAAQ7L,EAAI8J,WACX9J,EAAIuI,YAAavI,EAAI8J,WAItB9J,GAAMorB,EAAK7d,cAtDX8d,GAAMn0B,KAAMY,EAAQ6wB,eAAgB7uB,GA4DlCkG,IACJorB,EAAK7iB,YAAavI,GAKbvJ,EAAOmI,QAAQuZ,eACpB1hB,EAAO+K,KAAM2nB,GAAQkC,EAAO,SAAWP,IAGxC5uB,EAAI,CACJ,OAASpC,EAAOuxB,EAAOnvB,KAItB,KAAKgvB,GAAmD,KAAtCz0B,EAAO2K,QAAStH,EAAMoxB,MAIxCtnB,EAAWnN,EAAOmN,SAAU9J,EAAKS,cAAeT,GAGhDkG,EAAMmpB,GAAQiC,EAAKzhB,YAAa7P,GAAQ,UAGnC8J,GACJwlB,GAAeppB,GAIXX,GAAU,CACdjD,EAAI,CACJ,OAAStC,EAAOkG,EAAK5D,KACforB,GAAYhtB,KAAMV,EAAKV,MAAQ,KACnCiG,EAAQnI,KAAM4C,GAQlB,MAFAkG,GAAM,KAECorB,GAGRlR,UAAW,SAAU7e,EAAsBse,GAC1C,GAAI7f,GAAMV,EAAM0B,EAAIoE,EACnBhD,EAAI,EACJ2d,EAAcpjB,EAAO0G,QACrB8K,EAAQxR,EAAOwR,MACf0P,EAAgBlhB,EAAOmI,QAAQ+Y,cAC/BwH,EAAU1oB,EAAOyC,MAAMimB,OAExB,MAA6B,OAApBrlB,EAAOuB,EAAMa,IAAaA,IAElC,IAAKyd,GAAcljB,EAAOkjB,WAAY7f,MAErCgB,EAAKhB,EAAM+f,GACX3a,EAAOpE,GAAMmN,EAAOnN,IAER,CACX,GAAKoE,EAAK8f,OACT,IAAM5lB,IAAQ8F,GAAK8f,OACbG,EAAS/lB,GACb3C,EAAOyC,MAAMsG,OAAQ1F,EAAMV,GAI3B3C,EAAO4pB,YAAavmB,EAAMV,EAAM8F,EAAKwgB,OAMnCzX;EAAOnN,WAEJmN,GAAOnN,GAKT6c,QACG7d,GAAM+f,SAEK/f,GAAKgO,kBAAoB3R,EAC3C2D,EAAKgO,gBAAiB+R,GAGtB/f,EAAM+f,GAAgB,KAGvBhjB,EAAgBK,KAAM4D,MAO3BgvB,SAAU,SAAUwB,GACnB,MAAO70B,GAAO80B,MACbD,IAAKA,EACLlyB,KAAM,MACNoyB,SAAU,SACVprB,OAAO,EACP0e,QAAQ,EACR2M,UAAU,OAIbh1B,EAAOsB,GAAG0E,QACTivB,QAAS,SAAUnC,GAClB,GAAK9yB,EAAOiE,WAAY6uB,GACvB,MAAOxvB,MAAKyB,KAAK,SAASU,GACzBzF,EAAOsD,MAAM2xB,QAASnC,EAAKtuB,KAAKlB,KAAMmC,KAIxC,IAAKnC,KAAK,GAAK,CAEd,GAAIoxB,GAAO10B,EAAQ8yB,EAAMxvB,KAAK,GAAGQ,eAAgByB,GAAG,GAAGe,OAAM,EAExDhD,MAAK,GAAGc,YACZswB,EAAKpC,aAAchvB,KAAK,IAGzBoxB,EAAK9uB,IAAI,WACR,GAAIvC,GAAOC,IAEX,OAAQD,EAAKgQ,YAA2C,IAA7BhQ,EAAKgQ,WAAWxP,SAC1CR,EAAOA,EAAKgQ,UAGb,OAAOhQ,KACL4uB,OAAQ3uB,MAGZ,MAAOA,OAGR4xB,UAAW,SAAUpC,GACpB,MAAK9yB,GAAOiE,WAAY6uB,GAChBxvB,KAAKyB,KAAK,SAASU,GACzBzF,EAAOsD,MAAM4xB,UAAWpC,EAAKtuB,KAAKlB,KAAMmC,MAInCnC,KAAKyB,KAAK,WAChB,GAAI2Y,GAAO1d,EAAQsD,MAClBqrB,EAAWjR,EAAKiR,UAEZA,GAASnrB,OACbmrB,EAASsG,QAASnC,GAGlBpV,EAAKuU,OAAQa,MAKhB4B,KAAM,SAAU5B,GACf,GAAI7uB,GAAajE,EAAOiE,WAAY6uB,EAEpC,OAAOxvB,MAAKyB,KAAK,SAASU,GACzBzF,EAAQsD,MAAO2xB,QAAShxB,EAAa6uB,EAAKtuB,KAAKlB,KAAMmC,GAAKqtB,MAI5DqC,OAAQ,WACP,MAAO7xB,MAAKyP,SAAShO,KAAK,WACnB/E,EAAOmK,SAAU7G,KAAM,SAC5BtD,EAAQsD,MAAOyvB,YAAazvB,KAAK0F,cAEhCnD,QAGL,IAAIuvB,IAAQC,GAAWC,GACtBC,GAAS,kBACTC,GAAW,wBACXC,GAAY,4BAGZC,GAAe,4BACfC,GAAU,UACVC,GAAgBnnB,OAAQ,KAAOjN,EAAY,SAAU,KACrDq0B,GAAgBpnB,OAAQ,KAAOjN,EAAY,kBAAmB,KAC9Ds0B,GAAcrnB,OAAQ,YAAcjN,EAAY,IAAK,KACrDu0B,IAAgBC,KAAM,SAEtBC,IAAYC,SAAU,WAAYC,WAAY,SAAU7T,QAAS,SACjE8T,IACCC,cAAe,EACfC,WAAY,KAGbC,IAAc,MAAO,QAAS,SAAU,QACxCC,IAAgB,SAAU,IAAK,MAAO,KAGvC,SAASC,IAAgB1qB,EAAO3F,GAG/B,GAAKA,IAAQ2F,GACZ,MAAO3F,EAIR,IAAIswB,GAAUtwB,EAAK7C,OAAO,GAAGhB,cAAgB6D,EAAKzF,MAAM,GACvDg2B,EAAWvwB,EACXX,EAAI+wB,GAAYhzB,MAEjB,OAAQiC,IAEP,GADAW,EAAOowB,GAAa/wB,GAAMixB,EACrBtwB,IAAQ2F,GACZ,MAAO3F,EAIT,OAAOuwB,GAGR,QAASC,IAAUvzB,EAAMwzB,GAIxB,MADAxzB,GAAOwzB,GAAMxzB,EAC4B,SAAlCrD,EAAO82B,IAAKzzB,EAAM,aAA2BrD,EAAOmN,SAAU9J,EAAKS,cAAeT,GAG1F,QAAS0zB,IAAUliB,EAAUmiB,GAC5B,GAAI1U,GAASjf,EAAM4zB,EAClBzX,KACA3B,EAAQ,EACRra,EAASqR,EAASrR,MAEnB,MAAgBA,EAARqa,EAAgBA,IACvBxa,EAAOwR,EAAUgJ,GACXxa,EAAK0I,QAIXyT,EAAQ3B,GAAU7d,EAAO+jB,MAAO1gB,EAAM,cACtCif,EAAUjf,EAAK0I,MAAMuW,QAChB0U,GAGExX,EAAQ3B,IAAuB,SAAZyE,IACxBjf,EAAK0I,MAAMuW,QAAU,IAMM,KAAvBjf,EAAK0I,MAAMuW,SAAkBsU,GAAUvzB,KAC3Cmc,EAAQ3B,GAAU7d,EAAO+jB,MAAO1gB,EAAM,aAAc6zB,GAAmB7zB,EAAK8G,aAIvEqV,EAAQ3B,KACboZ,EAASL,GAAUvzB,IAEdif,GAAuB,SAAZA,IAAuB2U,IACtCj3B,EAAO+jB,MAAO1gB,EAAM,aAAc4zB,EAAS3U,EAAUtiB,EAAO82B,IAAKzzB,EAAM,aAQ3E,KAAMwa,EAAQ,EAAWra,EAARqa,EAAgBA,IAChCxa,EAAOwR,EAAUgJ,GACXxa,EAAK0I,QAGLirB,GAA+B,SAAvB3zB,EAAK0I,MAAMuW,SAA6C,KAAvBjf,EAAK0I,MAAMuW,UACzDjf,EAAK0I,MAAMuW,QAAU0U,EAAOxX,EAAQ3B,IAAW,GAAK,QAItD,OAAOhJ,GAGR7U,EAAOsB,GAAG0E,QACT8wB,IAAK,SAAU1wB,EAAMiE,GACpB,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAM+C,EAAMiE,GACjD,GAAI3E,GAAKyxB,EACRvxB,KACAH,EAAI,CAEL,IAAKzF,EAAOyG,QAASL,GAAS,CAI7B,IAHA+wB,EAAS9B,GAAWhyB,GACpBqC,EAAMU,EAAK5C,OAECkC,EAAJD,EAASA,IAChBG,EAAKQ,EAAMX,IAAQzF,EAAO82B,IAAKzzB,EAAM+C,EAAMX,IAAK,EAAO0xB,EAGxD,OAAOvxB,GAGR,MAAOyE,KAAU9K,EAChBS,EAAO+L,MAAO1I,EAAM+C,EAAMiE,GAC1BrK,EAAO82B,IAAKzzB,EAAM+C,IACjBA,EAAMiE,EAAOhF,UAAU7B,OAAS,IAEpCwzB,KAAM,WACL,MAAOD,IAAUzzB,MAAM,IAExB8zB,KAAM,WACL,MAAOL,IAAUzzB,OAElB+zB,OAAQ,SAAUlZ,GACjB,MAAsB,iBAAVA,GACJA,EAAQ7a,KAAK0zB,OAAS1zB,KAAK8zB,OAG5B9zB,KAAKyB,KAAK,WACX6xB,GAAUtzB,MACdtD,EAAQsD,MAAO0zB,OAEfh3B,EAAQsD,MAAO8zB,YAMnBp3B,EAAOgG,QAGNsxB,UACC/W,SACC9b,IAAK,SAAUpB,EAAMk0B,GACpB,GAAKA,EAAW,CAEf,GAAI1yB,GAAMywB,GAAQjyB,EAAM,UACxB,OAAe,KAARwB,EAAa,IAAMA,MAO9B2yB,WACCC,aAAe,EACfC,aAAe,EACfpB,YAAc,EACdqB,YAAc,EACdpX,SAAW,EACXqX,OAAS,EACTC,SAAW,EACXC,QAAU,EACVC,QAAU,EACVvV,MAAQ,GAKTwV,UAECC,QAASj4B,EAAOmI,QAAQqY,SAAW,WAAa,cAIjDzU,MAAO,SAAU1I,EAAM+C,EAAMiE,EAAO6tB,GAEnC,GAAM70B,GAA0B,IAAlBA,EAAKQ,UAAoC,IAAlBR,EAAKQ,UAAmBR,EAAK0I,MAAlE,CAKA,GAAIlH,GAAKlC,EAAM0hB,EACdsS,EAAW32B,EAAOiK,UAAW7D,GAC7B2F,EAAQ1I,EAAK0I,KASd,IAPA3F,EAAOpG,EAAOg4B,SAAUrB,KAAgB32B,EAAOg4B,SAAUrB,GAAaF,GAAgB1qB,EAAO4qB,IAI7FtS,EAAQrkB,EAAOs3B,SAAUlxB,IAAUpG,EAAOs3B,SAAUX,GAG/CtsB,IAAU9K,EAsCd,MAAK8kB,IAAS,OAASA,KAAUxf,EAAMwf,EAAM5f,IAAKpB,GAAM,EAAO60B,MAAa34B,EACpEsF,EAIDkH,EAAO3F,EAhCd,IAVAzD,QAAc0H,GAGA,WAAT1H,IAAsBkC,EAAMixB,GAAQryB,KAAM4G,MAC9CA,GAAUxF,EAAI,GAAK,GAAMA,EAAI,GAAKiD,WAAY9H,EAAO82B,IAAKzzB,EAAM+C,IAEhEzD,EAAO,YAIM,MAAT0H,GAA0B,WAAT1H,GAAqBkF,MAAOwC,KAKpC,WAAT1H,GAAsB3C,EAAOw3B,UAAWb,KAC5CtsB,GAAS,MAKJrK,EAAOmI,QAAQ6Z,iBAA6B,KAAV3X,GAA+C,IAA/BjE,EAAKvF,QAAQ,gBACpEkL,EAAO3F,GAAS,WAIXie,GAAW,OAASA,KAAWha,EAAQga,EAAMoC,IAAKpjB,EAAMgH,EAAO6tB,MAAa34B,IAIjF,IACCwM,EAAO3F,GAASiE,EACf,MAAMnC,OAcX4uB,IAAK,SAAUzzB,EAAM+C,EAAM8xB,EAAOf,GACjC,GAAIzyB,GAAKoQ,EAAKuP,EACbsS,EAAW32B,EAAOiK,UAAW7D,EAyB9B,OAtBAA,GAAOpG,EAAOg4B,SAAUrB,KAAgB32B,EAAOg4B,SAAUrB,GAAaF,GAAgBpzB,EAAK0I,MAAO4qB,IAIlGtS,EAAQrkB,EAAOs3B,SAAUlxB,IAAUpG,EAAOs3B,SAAUX,GAG/CtS,GAAS,OAASA,KACtBvP,EAAMuP,EAAM5f,IAAKpB,GAAM,EAAM60B,IAIzBpjB,IAAQvV,IACZuV,EAAMwgB,GAAQjyB,EAAM+C,EAAM+wB,IAId,WAARriB,GAAoB1O,IAAQgwB,MAChCthB,EAAMshB,GAAoBhwB,IAIZ,KAAV8xB,GAAgBA,GACpBxzB,EAAMoD,WAAYgN,GACXojB,KAAU,GAAQl4B,EAAO4H,UAAWlD,GAAQA,GAAO,EAAIoQ,GAExDA,KAMJxV,EAAOqjB,kBACX0S,GAAY,SAAUhyB,GACrB,MAAO/D,GAAOqjB,iBAAkBtf,EAAM,OAGvCiyB,GAAS,SAAUjyB,EAAM+C,EAAM+xB,GAC9B,GAAIvV,GAAOwV,EAAUC,EACpBd,EAAWY,GAAa9C,GAAWhyB,GAGnCwB,EAAM0yB,EAAWA,EAASe,iBAAkBlyB,IAAUmxB,EAAUnxB,GAAS7G,EACzEwM,EAAQ1I,EAAK0I,KA8Bd,OA5BKwrB,KAES,KAAR1yB,GAAe7E,EAAOmN,SAAU9J,EAAKS,cAAeT,KACxDwB,EAAM7E,EAAO+L,MAAO1I,EAAM+C,IAOtByvB,GAAU9xB,KAAMc,IAAS8wB,GAAQ5xB,KAAMqC,KAG3Cwc,EAAQ7W,EAAM6W,MACdwV,EAAWrsB,EAAMqsB,SACjBC,EAAWtsB,EAAMssB,SAGjBtsB,EAAMqsB,SAAWrsB,EAAMssB,SAAWtsB,EAAM6W,MAAQ/d,EAChDA,EAAM0yB,EAAS3U,MAGf7W,EAAM6W,MAAQA,EACd7W,EAAMqsB,SAAWA,EACjBrsB,EAAMssB,SAAWA,IAIZxzB,IAEGjF,EAASE,gBAAgBy4B,eACpClD,GAAY,SAAUhyB,GACrB,MAAOA,GAAKk1B,cAGbjD,GAAS,SAAUjyB,EAAM+C,EAAM+xB,GAC9B,GAAIK,GAAMC,EAAIC,EACbnB,EAAWY,GAAa9C,GAAWhyB,GACnCwB,EAAM0yB,EAAWA,EAAUnxB,GAAS7G,EACpCwM,EAAQ1I,EAAK0I,KAoCd,OAhCY,OAAPlH,GAAekH,GAASA,EAAO3F,KACnCvB,EAAMkH,EAAO3F,IAUTyvB,GAAU9xB,KAAMc,KAAU4wB,GAAU1xB,KAAMqC,KAG9CoyB,EAAOzsB,EAAMysB,KACbC,EAAKp1B,EAAKs1B,aACVD,EAASD,GAAMA,EAAGD,KAGbE,IACJD,EAAGD,KAAOn1B,EAAKk1B,aAAaC,MAE7BzsB,EAAMysB,KAAgB,aAATpyB,EAAsB,MAAQvB,EAC3CA,EAAMkH,EAAM6sB,UAAY,KAGxB7sB,EAAMysB,KAAOA,EACRE,IACJD,EAAGD,KAAOE,IAIG,KAAR7zB,EAAa,OAASA,GAI/B,SAASg0B,IAAmBx1B,EAAMgH,EAAOyuB,GACxC,GAAI5rB,GAAU0oB,GAAUnyB,KAAM4G,EAC9B,OAAO6C,GAENvG,KAAKiE,IAAK,EAAGsC,EAAS,IAAQ4rB,GAAY,KAAU5rB,EAAS,IAAO,MACpE7C,EAGF,QAAS0uB,IAAsB11B,EAAM+C,EAAM8xB,EAAOc,EAAa7B,GAC9D,GAAI1xB,GAAIyyB,KAAYc,EAAc,SAAW,WAE5C,EAES,UAAT5yB,EAAmB,EAAI,EAEvB0O,EAAM,CAEP,MAAY,EAAJrP,EAAOA,GAAK,EAEJ,WAAVyyB,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM60B,EAAQ3B,GAAW9wB,IAAK,EAAM0xB,IAGnD6B,GAEW,YAAVd,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,UAAYkzB,GAAW9wB,IAAK,EAAM0xB,IAI7C,WAAVe,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,SAAWkzB,GAAW9wB,GAAM,SAAS,EAAM0xB,MAIrEriB,GAAO9U,EAAO82B,IAAKzzB,EAAM,UAAYkzB,GAAW9wB,IAAK,EAAM0xB,GAG5C,YAAVe,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,SAAWkzB,GAAW9wB,GAAM,SAAS,EAAM0xB,IAKvE,OAAOriB,GAGR,QAASmkB,IAAkB51B,EAAM+C,EAAM8xB,GAGtC,GAAIgB,IAAmB,EACtBpkB,EAAe,UAAT1O,EAAmB/C,EAAKqf,YAAcrf,EAAKgf,aACjD8U,EAAS9B,GAAWhyB,GACpB21B,EAAch5B,EAAOmI,QAAQsa,WAAgE,eAAnDziB,EAAO82B,IAAKzzB,EAAM,aAAa,EAAO8zB,EAKjF,IAAY,GAAPriB,GAAmB,MAAPA,EAAc,CAQ9B,GANAA,EAAMwgB,GAAQjyB,EAAM+C,EAAM+wB,IACf,EAANriB,GAAkB,MAAPA,KACfA,EAAMzR,EAAK0I,MAAO3F,IAIdyvB,GAAU9xB,KAAK+Q,GACnB,MAAOA,EAKRokB,GAAmBF,IAAiBh5B,EAAOmI,QAAQkZ,mBAAqBvM,IAAQzR,EAAK0I,MAAO3F,IAG5F0O,EAAMhN,WAAYgN,IAAS,EAI5B,MAASA,GACRikB,GACC11B,EACA+C,EACA8xB,IAAWc,EAAc,SAAW,WACpCE,EACA/B,GAEE,KAIL,QAASD,IAAoB/sB,GAC5B,GAAI2I,GAAMlT,EACT0iB,EAAUyT,GAAa5rB,EA0BxB,OAxBMmY,KACLA,EAAU6W,GAAehvB,EAAU2I,GAGlB,SAAZwP,GAAuBA,IAE3B8S,IAAWA,IACVp1B,EAAO,kDACN82B,IAAK,UAAW,6BAChB/C,SAAUjhB,EAAIhT,iBAGhBgT,GAAQsiB,GAAO,GAAGvF,eAAiBuF,GAAO,GAAGxF,iBAAkBhwB,SAC/DkT,EAAIsmB,MAAM,+BACVtmB,EAAIumB,QAEJ/W,EAAU6W,GAAehvB,EAAU2I,GACnCsiB,GAAOvyB,UAIRkzB,GAAa5rB,GAAamY,GAGpBA,EAIR,QAAS6W,IAAe/yB,EAAM0M,GAC7B,GAAIzP,GAAOrD,EAAQ8S,EAAIjK,cAAezC,IAAS2tB,SAAUjhB,EAAI1L,MAC5Dkb,EAAUtiB,EAAO82B,IAAKzzB,EAAK,GAAI,UAEhC,OADAA,GAAK0F,SACEuZ,EAGRtiB,EAAO+E,MAAO,SAAU,SAAW,SAAUU,EAAGW,GAC/CpG,EAAOs3B,SAAUlxB,IAChB3B,IAAK,SAAUpB,EAAMk0B,EAAUW,GAC9B,MAAKX,GAGwB,IAArBl0B,EAAKqf,aAAqBgT,GAAa3xB,KAAM/D,EAAO82B,IAAKzzB,EAAM,YACrErD,EAAO6L,KAAMxI,EAAM4yB,GAAS,WAC3B,MAAOgD,IAAkB51B,EAAM+C,EAAM8xB,KAEtCe,GAAkB51B,EAAM+C,EAAM8xB,GAPhC,GAWDzR,IAAK,SAAUpjB,EAAMgH,EAAO6tB,GAC3B,GAAIf,GAASe,GAAS7C,GAAWhyB,EACjC,OAAOw1B,IAAmBx1B,EAAMgH,EAAO6tB,EACtCa,GACC11B,EACA+C,EACA8xB,EACAl4B,EAAOmI,QAAQsa,WAAgE,eAAnDziB,EAAO82B,IAAKzzB,EAAM,aAAa,EAAO8zB,GAClEA,GACG,OAMFn3B,EAAOmI,QAAQoY,UACpBvgB,EAAOs3B,SAAS/W,SACf9b,IAAK,SAAUpB,EAAMk0B,GAEpB,MAAO/B,IAASzxB,MAAOwzB,GAAYl0B,EAAKk1B,aAAel1B,EAAKk1B,aAAa/kB,OAASnQ,EAAK0I,MAAMyH,SAAW,IACrG,IAAO1L,WAAY2G,OAAO6qB,IAAS,GACrC/B,EAAW,IAAM,IAGnB9Q,IAAK,SAAUpjB,EAAMgH,GACpB,GAAI0B,GAAQ1I,EAAK0I,MAChBwsB,EAAel1B,EAAKk1B,aACpBhY,EAAUvgB,EAAO4H,UAAWyC,GAAU,iBAA2B,IAARA,EAAc,IAAM,GAC7EmJ,EAAS+kB,GAAgBA,EAAa/kB,QAAUzH,EAAMyH,QAAU,EAIjEzH,GAAMyW,KAAO,GAINnY,GAAS,GAAe,KAAVA,IAC6B,KAAhDrK,EAAOmB,KAAMqS,EAAO3M,QAAS0uB,GAAQ,MACrCxpB,EAAMsF,kBAKPtF,EAAMsF,gBAAiB,UAGR,KAAVhH,GAAgBkuB,IAAiBA,EAAa/kB,UAMpDzH,EAAMyH,OAAS+hB,GAAOxxB,KAAMyP,GAC3BA,EAAO3M,QAAS0uB,GAAQhV,GACxB/M,EAAS,IAAM+M,MAOnBvgB,EAAO,WACAA,EAAOmI,QAAQiZ,sBACpBphB,EAAOs3B,SAASzU,aACfpe,IAAK,SAAUpB,EAAMk0B,GACpB,MAAKA,GAGGv3B,EAAO6L,KAAMxI,GAAQif,QAAW,gBACtCgT,IAAUjyB,EAAM,gBAJlB,MAaGrD,EAAOmI,QAAQ8Y,eAAiBjhB,EAAOsB,GAAG40B,UAC/Cl2B,EAAO+E,MAAQ,MAAO,QAAU,SAAUU,EAAGmgB,GAC5C5lB,EAAOs3B,SAAU1R,IAChBnhB,IAAK,SAAUpB,EAAMk0B,GACpB,MAAKA,IACJA,EAAWjC,GAAQjyB,EAAMuiB,GAElBiQ,GAAU9xB,KAAMwzB,GACtBv3B,EAAQqD,GAAO6yB,WAAYtQ,GAAS,KACpC2R,GALF,QAcAv3B,EAAO4U,MAAQ5U,EAAO4U,KAAKwE,UAC/BpZ,EAAO4U,KAAKwE,QAAQ6d,OAAS,SAAU5zB,GAGtC,MAA2B,IAApBA,EAAKqf,aAAyC,GAArBrf,EAAKgf,eAClCriB,EAAOmI,QAAQoa,uBAAmG,UAAxElf,EAAK0I,OAAS1I,EAAK0I,MAAMuW,SAAYtiB,EAAO82B,IAAKzzB,EAAM,aAGrGrD,EAAO4U,KAAKwE,QAAQmgB,QAAU,SAAUl2B,GACvC,OAAQrD,EAAO4U,KAAKwE,QAAQ6d,OAAQ5zB,KAKtCrD,EAAO+E,MACNy0B,OAAQ,GACRC,QAAS,GACTC,OAAQ,SACN,SAAUC,EAAQC,GACpB55B,EAAOs3B,SAAUqC,EAASC,IACzBC,OAAQ,SAAUxvB,GACjB,GAAI5E,GAAI,EACPq0B,KAGAC,EAAyB,gBAAV1vB,GAAqBA,EAAMiC,MAAM,MAASjC,EAE1D,MAAY,EAAJ5E,EAAOA,IACdq0B,EAAUH,EAASpD,GAAW9wB,GAAMm0B,GACnCG,EAAOt0B,IAAOs0B,EAAOt0B,EAAI,IAAOs0B,EAAO,EAGzC,OAAOD,KAIHnE,GAAQ5xB,KAAM41B,KACnB35B,EAAOs3B,SAAUqC,EAASC,GAASnT,IAAMoS,KAG3C,IAAImB,IAAM,OACTC,GAAW,QACXC,GAAQ,SACRC,GAAkB,wCAClBC,GAAe,oCAEhBp6B,GAAOsB,GAAG0E,QACTq0B,UAAW,WACV,MAAOr6B,GAAOqxB,MAAO/tB,KAAKg3B,mBAE3BA,eAAgB,WACf,MAAOh3B,MAAKsC,IAAI,WAEf,GAAIiP,GAAW7U,EAAO4lB,KAAMtiB,KAAM,WAClC,OAAOuR,GAAW7U,EAAOsE,UAAWuQ,GAAavR,OAEjDkQ,OAAO,WACP,GAAI7Q,GAAOW,KAAKX,IAEhB,OAAOW,MAAK8C,OAASpG,EAAQsD,MAAOyrB,GAAI,cACvCqL,GAAar2B,KAAMT,KAAK6G,YAAegwB,GAAgBp2B,KAAMpB,KAC3DW,KAAK6U,UAAY0Y,GAA4B9sB,KAAMpB,MAEtDiD,IAAI,SAAUH,EAAGpC,GACjB,GAAIyR,GAAM9U,EAAQsD,MAAOwR,KAEzB,OAAc,OAAPA,EACN,KACA9U,EAAOyG,QAASqO,GACf9U,EAAO4F,IAAKkP,EAAK,SAAUA,GAC1B,OAAS1O,KAAM/C,EAAK+C,KAAMiE,MAAOyK,EAAIjO,QAASqzB,GAAO,YAEpD9zB,KAAM/C,EAAK+C,KAAMiE,MAAOyK,EAAIjO,QAASqzB,GAAO,WAC9Cz1B,SAMLzE,EAAOqxB,MAAQ,SAAUzjB,EAAG2sB,GAC3B,GAAIZ,GACHa,KACA5c,EAAM,SAAU3V,EAAKoC,GAEpBA,EAAQrK,EAAOiE,WAAYoG,GAAUA,IAAqB,MAATA,EAAgB,GAAKA,EACtEmwB,EAAGA,EAAEh3B,QAAWi3B,mBAAoBxyB,GAAQ,IAAMwyB,mBAAoBpwB,GASxE,IALKkwB,IAAgBh7B,IACpBg7B,EAAcv6B,EAAO06B,cAAgB16B,EAAO06B,aAAaH,aAIrDv6B,EAAOyG,QAASmH,IAASA,EAAE1K,SAAWlD,EAAOgE,cAAe4J,GAEhE5N,EAAO+E,KAAM6I,EAAG,WACfgQ,EAAKta,KAAK8C,KAAM9C,KAAK+G,aAMtB,KAAMsvB,IAAU/rB,GACf+sB,GAAahB,EAAQ/rB,EAAG+rB,GAAUY,EAAa3c,EAKjD,OAAO4c,GAAEtpB,KAAM,KAAMrK,QAASmzB,GAAK,KAGpC,SAASW,IAAahB,EAAQlyB,EAAK8yB,EAAa3c,GAC/C,GAAIxX,EAEJ,IAAKpG,EAAOyG,QAASgB,GAEpBzH,EAAO+E,KAAM0C,EAAK,SAAUhC,EAAGm1B,GACzBL,GAAeN,GAASl2B,KAAM41B,GAElC/b,EAAK+b,EAAQiB,GAIbD,GAAahB,EAAS,KAAqB,gBAANiB,GAAiBn1B,EAAI,IAAO,IAAKm1B,EAAGL,EAAa3c,SAIlF,IAAM2c,GAAsC,WAAvBv6B,EAAO2C,KAAM8E,GAQxCmW,EAAK+b,EAAQlyB,OANb,KAAMrB,IAAQqB,GACbkzB,GAAahB,EAAS,IAAMvzB,EAAO,IAAKqB,EAAKrB,GAAQm0B,EAAa3c,GAQrE5d,EAAO+E,KAAM,0MAEqDuH,MAAM,KAAM,SAAU7G,EAAGW,GAG1FpG,EAAOsB,GAAI8E,GAAS,SAAUqC,EAAMnH,GACnC,MAAO+D,WAAU7B,OAAS,EACzBF,KAAK6qB,GAAI/nB,EAAM,KAAMqC,EAAMnH,GAC3BgC,KAAKiE,QAASnB,MAIjBpG,EAAOsB,GAAG0E,QACT60B,MAAO,SAAUC,EAAQC,GACxB,MAAOz3B,MAAKiqB,WAAYuN,GAAStN,WAAYuN,GAASD,IAGvDE,KAAM,SAAU1S,EAAO7f,EAAMnH,GAC5B,MAAOgC,MAAK6qB,GAAI7F,EAAO,KAAM7f,EAAMnH,IAEpC25B,OAAQ,SAAU3S,EAAOhnB,GACxB,MAAOgC,MAAKkE,IAAK8gB,EAAO,KAAMhnB,IAG/B45B,SAAU,SAAU95B,EAAUknB,EAAO7f,EAAMnH,GAC1C,MAAOgC,MAAK6qB,GAAI7F,EAAOlnB,EAAUqH,EAAMnH,IAExC65B,WAAY,SAAU/5B,EAAUknB,EAAOhnB,GAEtC,MAA4B,KAArB+D,UAAU7B,OAAeF,KAAKkE,IAAKpG,EAAU,MAASkC,KAAKkE,IAAK8gB,EAAOlnB,GAAY,KAAME,KAGlG,IAEC85B,IACAC,GACAC,GAAat7B,EAAO0L,MAEpB6vB,GAAc,KACdC,GAAQ,OACRC,GAAM,gBACNC,GAAW,gCAEXC,GAAiB,4DACjBC,GAAa,iBACbC,GAAY,QACZC,GAAO,8CAGPC,GAAQ/7B,EAAOsB,GAAGqrB,KAWlBqP,MAOAC,MAGAC,GAAW,KAAK37B,OAAO,IAIxB,KACC86B,GAAe17B,EAASoY,KACvB,MAAO7P,IAGRmzB,GAAez7B,EAASiJ,cAAe,KACvCwyB,GAAatjB,KAAO,GACpBsjB,GAAeA,GAAatjB,KAI7BqjB,GAAeU,GAAKr4B,KAAM43B,GAAajxB,kBAGvC,SAAS+xB,IAA6BC,GAGrC,MAAO,UAAUC,EAAoBpe,GAED,gBAAvBoe,KACXpe,EAAOoe,EACPA,EAAqB,IAGtB,IAAItH,GACHtvB,EAAI,EACJ62B,EAAYD,EAAmBjyB,cAAchH,MAAO1B,MAErD,IAAK1B,EAAOiE,WAAYga,GAEvB,MAAS8W,EAAWuH,EAAU72B,KAER,MAAhBsvB,EAAS,IACbA,EAAWA,EAASp0B,MAAO,IAAO,KACjCy7B,EAAWrH,GAAaqH,EAAWrH,QAAkBpgB,QAASsJ,KAI9Dme,EAAWrH,GAAaqH,EAAWrH,QAAkBt0B,KAAMwd,IAQjE,QAASse,IAA+BH,EAAW/1B,EAASm2B,EAAiBC,GAE5E,GAAIC,MACHC,EAAqBP,IAAcH,EAEpC,SAASW,GAAS7H,GACjB,GAAI3c,EAYJ,OAXAskB,GAAW3H,IAAa,EACxB/0B,EAAO+E,KAAMq3B,EAAWrH,OAAkB,SAAUhlB,EAAG8sB,GACtD,GAAIC,GAAsBD,EAAoBx2B,EAASm2B,EAAiBC,EACxE,OAAmC,gBAAxBK,IAAqCH,GAAqBD,EAAWI,GAIpEH,IACDvkB,EAAW0kB,GADf,GAHNz2B,EAAQi2B,UAAU3nB,QAASmoB,GAC3BF,EAASE,IACF,KAKF1kB,EAGR,MAAOwkB,GAASv2B,EAAQi2B,UAAW,MAAUI,EAAW,MAASE,EAAS,KAM3E,QAASG,IAAYx2B,EAAQN,GAC5B,GAAIO,GAAMyB,EACT+0B,EAAch9B,EAAO06B,aAAasC,eAEnC,KAAM/0B,IAAOhC,GACPA,EAAKgC,KAAU1I,KACjBy9B,EAAa/0B,GAAQ1B,EAAWC,IAASA,OAAgByB,GAAQhC,EAAKgC,GAO1E,OAJKzB,IACJxG,EAAOgG,QAAQ,EAAMO,EAAQC,GAGvBD,EAGRvG,EAAOsB,GAAGqrB,KAAO,SAAUkI,EAAKoI,EAAQj4B,GACvC,GAAoB,gBAAR6vB,IAAoBkH,GAC/B,MAAOA,IAAM32B,MAAO9B,KAAM+B,UAG3B,IAAIjE,GAAU87B,EAAUv6B,EACvB+a,EAAOpa,KACPkE,EAAMqtB,EAAIh0B,QAAQ,IA+CnB,OA7CK2G,IAAO,IACXpG,EAAWyzB,EAAIl0B,MAAO6G,EAAKqtB,EAAIrxB,QAC/BqxB,EAAMA,EAAIl0B,MAAO,EAAG6G,IAIhBxH,EAAOiE,WAAYg5B,IAGvBj4B,EAAWi4B,EACXA,EAAS19B,GAGE09B,GAA4B,gBAAXA,KAC5Bt6B,EAAO,QAIH+a,EAAKla,OAAS,GAClBxD,EAAO80B,MACND,IAAKA,EAGLlyB,KAAMA,EACNoyB,SAAU,OACVtsB,KAAMw0B,IACJ93B,KAAK,SAAUg4B,GAGjBD,EAAW73B,UAEXqY,EAAKoV,KAAM1xB,EAIVpB,EAAO,SAASiyB,OAAQjyB,EAAO4D,UAAWu5B,IAAiBz5B,KAAMtC,GAGjE+7B,KAECC,SAAUp4B,GAAY,SAAUy3B,EAAOY,GACzC3f,EAAK3Y,KAAMC,EAAUk4B,IAAcT,EAAMU,aAAcE,EAAQZ,MAI1Dn5B,MAIRtD,EAAO+E,MAAQ,YAAa,WAAY,eAAgB,YAAa,cAAe,YAAc,SAAUU,EAAG9C,GAC9G3C,EAAOsB,GAAIqB,GAAS,SAAUrB,GAC7B,MAAOgC,MAAK6qB,GAAIxrB,EAAMrB,MAIxBtB,EAAOgG,QAGNs3B,OAAQ,EAGRC,gBACAC,QAEA9C,cACC7F,IAAKwG,GACL14B,KAAM,MACN86B,QAAS9B,GAAe53B,KAAMq3B,GAAc,IAC5C/S,QAAQ,EACRqV,aAAa,EACb/zB,OAAO,EACPg0B,YAAa,mDAabC,SACCC,IAAK3B,GACL3xB,KAAM,aACNuoB,KAAM,YACNxpB,IAAK,4BACLw0B,KAAM,qCAGPnP,UACCrlB,IAAK,MACLwpB,KAAM,OACNgL,KAAM,QAGPC,gBACCz0B,IAAK,cACLiB,KAAM,eACNuzB,KAAM,gBAKPE,YAGCC,SAAUj2B,OAGVk2B,aAAa,EAGbC,YAAan+B,EAAOiJ,UAGpBm1B,WAAYp+B,EAAOqJ,UAOpB2zB,aACCnI,KAAK,EACLxzB,SAAS,IAOXg9B,UAAW,SAAU93B,EAAQ+3B,GAC5B,MAAOA,GAGNvB,GAAYA,GAAYx2B,EAAQvG,EAAO06B,cAAgB4D,GAGvDvB,GAAY/8B,EAAO06B,aAAcn0B,IAGnCg4B,cAAepC,GAA6BH,IAC5CwC,cAAerC,GAA6BF,IAG5CnH,KAAM,SAAUD,EAAKxuB,GAGA,gBAARwuB,KACXxuB,EAAUwuB,EACVA,EAAMt1B,GAIP8G,EAAUA,KAEV,IACC0zB,GAEAt0B,EAEAg5B,EAEAC,EAEAC,EAGAC,EAEAC,EAEAC,EAEAtE,EAAIx6B,EAAOq+B,aAAeh4B,GAE1B04B,EAAkBvE,EAAEn5B,SAAWm5B,EAE/BwE,EAAqBxE,EAAEn5B,UAAa09B,EAAgBl7B,UAAYk7B,EAAgB77B,QAC/ElD,EAAQ++B,GACR/+B,EAAOyC,MAER4b,EAAWre,EAAOgM,WAClBizB,EAAmBj/B,EAAO8c,UAAU,eAEpCoiB,EAAa1E,EAAE0E,eAEfC,KACAC,KAEAjhB,EAAQ,EAERkhB,EAAW,WAEX5C,GACC75B,WAAY,EAGZ08B,kBAAmB,SAAUr3B,GAC5B,GAAI7E,EACJ,IAAe,IAAV+a,EAAc,CAClB,IAAM2gB,EAAkB,CACvBA,IACA,OAAS17B,EAAQs4B,GAASj4B,KAAMi7B,GAC/BI,EAAiB17B,EAAM,GAAGgH,eAAkBhH,EAAO,GAGrDA,EAAQ07B,EAAiB72B,EAAImC,eAE9B,MAAgB,OAAThH,EAAgB,KAAOA,GAI/Bm8B,sBAAuB,WACtB,MAAiB,KAAVphB,EAAcugB,EAAwB,MAI9Cc,iBAAkB,SAAUp5B,EAAMiE,GACjC,GAAIo1B,GAAQr5B,EAAKgE,aAKjB,OAJM+T,KACL/X,EAAOg5B,EAAqBK,GAAUL,EAAqBK,IAAWr5B,EACtE+4B,EAAgB/4B,GAASiE,GAEnB/G,MAIRo8B,iBAAkB,SAAU/8B,GAI3B,MAHMwb,KACLqc,EAAEmF,SAAWh9B,GAEPW,MAIR47B,WAAY,SAAUt5B,GACrB,GAAIg6B,EACJ,IAAKh6B,EACJ,GAAa,EAARuY,EACJ,IAAMyhB,IAAQh6B,GAEbs5B,EAAYU,IAAWV,EAAYU,GAAQh6B,EAAKg6B,QAIjDnD,GAAMre,OAAQxY,EAAK62B,EAAMY,QAG3B,OAAO/5B,OAIRu8B,MAAO,SAAUC,GAChB,GAAIC,GAAYD,GAAcT,CAK9B,OAJKR,IACJA,EAAUgB,MAAOE,GAElB56B,EAAM,EAAG46B,GACFz8B,MAwCV,IAnCA+a,EAASnZ,QAASu3B,GAAQW,SAAW6B,EAAiBrhB,IACtD6e,EAAMuD,QAAUvD,EAAMt3B,KACtBs3B,EAAMn0B,MAAQm0B,EAAMne,KAMpBkc,EAAE3F,MAAUA,GAAO2F,EAAE3F,KAAOwG,IAAiB,IAAKx0B,QAAS20B,GAAO,IAAK30B,QAASg1B,GAAWT,GAAc,GAAM,MAG/GZ,EAAE73B,KAAO0D,EAAQ45B,QAAU55B,EAAQ1D,MAAQ63B,EAAEyF,QAAUzF,EAAE73B,KAGzD63B,EAAE8B,UAAYt8B,EAAOmB,KAAMq5B,EAAEzF,UAAY,KAAM3qB,cAAchH,MAAO1B,KAAqB,IAGnE,MAAjB84B,EAAE0F,cACNnG,EAAQ+B,GAAKr4B,KAAM+2B,EAAE3F,IAAIzqB,eACzBowB,EAAE0F,eAAkBnG,GACjBA,EAAO,KAAQqB,GAAc,IAAOrB,EAAO,KAAQqB,GAAc,KAChErB,EAAO,KAAwB,UAAfA,EAAO,GAAkB,KAAO,WAC/CqB,GAAc,KAA+B,UAAtBA,GAAc,GAAkB,KAAO,UAK/DZ,EAAE/xB,MAAQ+xB,EAAEkD,aAAiC,gBAAXlD,GAAE/xB,OACxC+xB,EAAE/xB,KAAOzI,EAAOqxB,MAAOmJ,EAAE/xB,KAAM+xB,EAAED,cAIlCgC,GAA+BP,GAAYxB,EAAGn0B,EAASo2B,GAGxC,IAAVte,EACJ,MAAOse,EAIRmC,GAAcpE,EAAEnS,OAGXuW,GAAmC,IAApB5+B,EAAOs9B,UAC1Bt9B,EAAOyC,MAAM8E,QAAQ,aAItBizB,EAAE73B,KAAO63B,EAAE73B,KAAKJ,cAGhBi4B,EAAE2F,YAAcvE,GAAW73B,KAAMy2B,EAAE73B,MAInC87B,EAAWjE,EAAE3F,IAGP2F,EAAE2F,aAGF3F,EAAE/xB,OACNg2B,EAAajE,EAAE3F,MAAS0G,GAAYx3B,KAAM06B,GAAa,IAAM,KAAQjE,EAAE/xB,WAEhE+xB,GAAE/xB,MAIL+xB,EAAEhpB,SAAU,IAChBgpB,EAAE3F,IAAM4G,GAAI13B,KAAM06B,GAGjBA,EAAS53B,QAAS40B,GAAK,OAASH,MAGhCmD,GAAalD,GAAYx3B,KAAM06B,GAAa,IAAM,KAAQ,KAAOnD,OAK/Dd,EAAE4F,aACDpgC,EAAOu9B,aAAckB,IACzBhC,EAAM+C,iBAAkB,oBAAqBx/B,EAAOu9B,aAAckB,IAE9Dz+B,EAAOw9B,KAAMiB,IACjBhC,EAAM+C,iBAAkB,gBAAiBx/B,EAAOw9B,KAAMiB,MAKnDjE,EAAE/xB,MAAQ+xB,EAAE2F,YAAc3F,EAAEmD,eAAgB,GAASt3B,EAAQs3B,cACjElB,EAAM+C,iBAAkB,eAAgBhF,EAAEmD,aAI3ClB,EAAM+C,iBACL,SACAhF,EAAE8B,UAAW,IAAO9B,EAAEoD,QAASpD,EAAE8B,UAAU,IAC1C9B,EAAEoD,QAASpD,EAAE8B,UAAU,KAA8B,MAArB9B,EAAE8B,UAAW,GAAc,KAAOJ,GAAW,WAAa,IAC1F1B,EAAEoD,QAAS,KAIb,KAAMn4B,IAAK+0B,GAAE6F,QACZ5D,EAAM+C,iBAAkB/5B,EAAG+0B,EAAE6F,QAAS56B,GAIvC,IAAK+0B,EAAE8F,aAAgB9F,EAAE8F,WAAW97B,KAAMu6B,EAAiBtC,EAAOjC,MAAQ,GAAmB,IAAVrc,GAElF,MAAOse,GAAMoD,OAIdR,GAAW,OAGX,KAAM55B,KAAOu6B,QAAS,EAAG13B,MAAO,EAAG80B,SAAU,GAC5CX,EAAOh3B,GAAK+0B,EAAG/0B,GAOhB,IAHAo5B,EAAYtC,GAA+BN,GAAYzB,EAAGn0B,EAASo2B,GAK5D,CACNA,EAAM75B,WAAa,EAGdg8B,GACJI,EAAmBz3B,QAAS,YAAck1B,EAAOjC,IAG7CA,EAAE7wB,OAAS6wB,EAAE1V,QAAU,IAC3B6Z,EAAet3B,WAAW,WACzBo1B,EAAMoD,MAAM,YACVrF,EAAE1V,SAGN,KACC3G,EAAQ,EACR0gB,EAAU0B,KAAMpB,EAAgBh6B,GAC/B,MAAQ+C,GAET,KAAa,EAARiW,GAIJ,KAAMjW,EAHN/C,GAAM,GAAI+C,QArBZ/C,GAAM,GAAI,eA8BX,SAASA,GAAMk4B,EAAQmD,EAAkBC,EAAWJ,GACnD,GAAIK,GAAWV,EAAS13B,EAAO40B,EAAUyD,EACxCb,EAAaU,CAGC,KAAVriB,IAKLA,EAAQ,EAGHwgB,GACJ5Z,aAAc4Z,GAKfE,EAAYt/B,EAGZm/B,EAAwB2B,GAAW,GAGnC5D,EAAM75B,WAAay6B,EAAS,EAAI,EAAI,EAGpCqD,EAAYrD,GAAU,KAAgB,IAATA,GAA2B,MAAXA,EAGxCoD,IACJvD,EAAW0D,GAAqBpG,EAAGiC,EAAOgE,IAI3CvD,EAAW2D,GAAarG,EAAG0C,EAAUT,EAAOiE,GAGvCA,GAGClG,EAAE4F,aACNO,EAAWlE,EAAM6C,kBAAkB,iBAC9BqB,IACJ3gC,EAAOu9B,aAAckB,GAAakC,GAEnCA,EAAWlE,EAAM6C,kBAAkB,QAC9BqB,IACJ3gC,EAAOw9B,KAAMiB,GAAakC,IAKZ,MAAXtD,GAA6B,SAAX7C,EAAE73B,KACxBm9B,EAAa,YAGS,MAAXzC,EACXyC,EAAa,eAIbA,EAAa5C,EAAS/e,MACtB6hB,EAAU9C,EAASz0B,KACnBH,EAAQ40B,EAAS50B,MACjBo4B,GAAap4B,KAKdA,EAAQw3B,GACHzC,IAAWyC,KACfA,EAAa,QACC,EAATzC,IACJA,EAAS,KAMZZ,EAAMY,OAASA,EACfZ,EAAMqD,YAAeU,GAAoBV,GAAe,GAGnDY,EACJriB,EAAS/W,YAAay3B,GAAmBiB,EAASF,EAAYrD,IAE9Dpe,EAASyiB,WAAY/B,GAAmBtC,EAAOqD,EAAYx3B,IAI5Dm0B,EAAMyC,WAAYA,GAClBA,EAAa3/B,EAERq/B,GACJI,EAAmBz3B,QAASm5B,EAAY,cAAgB,aACrDjE,EAAOjC,EAAGkG,EAAYV,EAAU13B,IAIpC22B,EAAiBjhB,SAAU+gB,GAAmBtC,EAAOqD,IAEhDlB,IACJI,EAAmBz3B,QAAS,gBAAkBk1B,EAAOjC,MAE3Cx6B,EAAOs9B,QAChBt9B,EAAOyC,MAAM8E,QAAQ,cAKxB,MAAOk1B,IAGRsE,QAAS,SAAUlM,EAAKpsB,EAAMzD,GAC7B,MAAOhF,GAAOyE,IAAKowB,EAAKpsB,EAAMzD,EAAU,SAGzCg8B,UAAW,SAAUnM,EAAK7vB,GACzB,MAAOhF,GAAOyE,IAAKowB,EAAKt1B,EAAWyF,EAAU,aAI/ChF,EAAO+E,MAAQ,MAAO,QAAU,SAAUU,EAAGw6B,GAC5CjgC,EAAQigC,GAAW,SAAUpL,EAAKpsB,EAAMzD,EAAUrC,GAQjD,MANK3C,GAAOiE,WAAYwE,KACvB9F,EAAOA,GAAQqC,EACfA,EAAWyD,EACXA,EAAOlJ,GAGDS,EAAO80B,MACbD,IAAKA,EACLlyB,KAAMs9B,EACNlL,SAAUpyB,EACV8F,KAAMA,EACNu3B,QAASh7B,MASZ,SAAS47B,IAAqBpG,EAAGiC,EAAOgE,GACvC,GAAIQ,GAAeC,EAAIC,EAAex+B,EACrCgsB,EAAW6L,EAAE7L,SACb2N,EAAY9B,EAAE8B,SAGf,OAA0B,MAAnBA,EAAW,GACjBA,EAAU5qB,QACLwvB,IAAO3hC,IACX2hC,EAAK1G,EAAEmF,UAAYlD,EAAM6C,kBAAkB,gBAK7C,IAAK4B,EACJ,IAAMv+B,IAAQgsB,GACb,GAAKA,EAAUhsB,IAAUgsB,EAAUhsB,GAAOoB,KAAMm9B,GAAO,CACtD5E,EAAU3nB,QAAShS,EACnB,OAMH,GAAK25B,EAAW,IAAOmE,GACtBU,EAAgB7E,EAAW,OACrB,CAEN,IAAM35B,IAAQ89B,GAAY,CACzB,IAAMnE,EAAW,IAAO9B,EAAEwD,WAAYr7B,EAAO,IAAM25B,EAAU,IAAO,CACnE6E,EAAgBx+B,CAChB,OAEKs+B,IACLA,EAAgBt+B,GAIlBw+B,EAAgBA,GAAiBF,EAMlC,MAAKE,IACCA,IAAkB7E,EAAW,IACjCA,EAAU3nB,QAASwsB,GAEbV,EAAWU,IAJnB,EAWD,QAASN,IAAarG,EAAG0C,EAAUT,EAAOiE,GACzC,GAAIU,GAAOC,EAASC,EAAM/3B,EAAKqlB,EAC9BoP,KAEA1B,EAAY9B,EAAE8B,UAAU37B,OAGzB,IAAK27B,EAAW,GACf,IAAMgF,IAAQ9G,GAAEwD,WACfA,EAAYsD,EAAKl3B,eAAkBowB,EAAEwD,WAAYsD,EAInDD,GAAU/E,EAAU5qB,OAGpB,OAAQ2vB,EAcP,GAZK7G,EAAEuD,eAAgBsD,KACtB5E,EAAOjC,EAAEuD,eAAgBsD,IAAcnE,IAIlCtO,GAAQ8R,GAAalG,EAAE+G,aAC5BrE,EAAW1C,EAAE+G,WAAYrE,EAAU1C,EAAEzF,WAGtCnG,EAAOyS,EACPA,EAAU/E,EAAU5qB,QAKnB,GAAiB,MAAZ2vB,EAEJA,EAAUzS,MAGJ,IAAc,MAATA,GAAgBA,IAASyS,EAAU,CAM9C,GAHAC,EAAOtD,EAAYpP,EAAO,IAAMyS,IAAarD,EAAY,KAAOqD,IAG1DC,EACL,IAAMF,IAASpD,GAId,GADAz0B,EAAM63B,EAAM90B,MAAO,KACd/C,EAAK,KAAQ83B,IAGjBC,EAAOtD,EAAYpP,EAAO,IAAMrlB,EAAK,KACpCy0B,EAAY,KAAOz0B,EAAK,KACb,CAEN+3B,KAAS,EACbA,EAAOtD,EAAYoD,GAGRpD,EAAYoD,MAAY,IACnCC,EAAU93B,EAAK,GACf+yB,EAAU3nB,QAASpL,EAAK,IAEzB,OAOJ,GAAK+3B,KAAS,EAGb,GAAKA,GAAQ9G,EAAG,UACf0C,EAAWoE,EAAMpE,OAEjB,KACCA,EAAWoE,EAAMpE,GAChB,MAAQh1B,GACT,OAASiW,MAAO,cAAe7V,MAAOg5B,EAAOp5B,EAAI,sBAAwB0mB,EAAO,OAASyS,IAQ/F,OAASljB,MAAO,UAAW1V,KAAMy0B,GAGlCl9B,EAAOq+B,WACNT,SACC4D,OAAQ,6FAET7S,UACC6S,OAAQ,uBAETxD,YACCyD,cAAe,SAAUl3B,GAExB,MADAvK,GAAO+J,WAAYQ,GACZA,MAMVvK,EAAOu+B,cAAe,SAAU,SAAU/D,GACpCA,EAAEhpB,QAAUjS,IAChBi7B,EAAEhpB,OAAQ,GAENgpB,EAAE0F,cACN1F,EAAE73B,KAAO,MACT63B,EAAEnS,QAAS,KAKbroB,EAAOw+B,cAAe,SAAU,SAAShE,GAGxC,GAAKA,EAAE0F,YAAc,CAEpB,GAAIsB,GACHE,EAAO9hC,EAAS8hC,MAAQ1hC,EAAO,QAAQ,IAAMJ,EAASE,eAEvD,QAECygC,KAAM,SAAUxwB,EAAG/K,GAElBw8B,EAAS5hC,EAASiJ,cAAc,UAEhC24B,EAAO73B,OAAQ,EAEV6wB,EAAEmH,gBACNH,EAAOI,QAAUpH,EAAEmH,eAGpBH,EAAOv7B,IAAMu0B,EAAE3F,IAGf2M,EAAOK,OAASL,EAAOM,mBAAqB,SAAU/xB,EAAGgyB,IAEnDA,IAAYP,EAAO5+B,YAAc,kBAAkBmB,KAAMy9B,EAAO5+B,eAGpE4+B,EAAOK,OAASL,EAAOM,mBAAqB,KAGvCN,EAAOp9B,YACXo9B,EAAOp9B,WAAW0N,YAAa0vB,GAIhCA,EAAS,KAGHO,GACL/8B,EAAU,IAAK,aAOlB08B,EAAKpP,aAAckP,EAAQE,EAAKruB,aAGjCwsB,MAAO,WACD2B,GACJA,EAAOK,OAAQtiC,GAAW,OAM/B,IAAIyiC,OACHC,GAAS,mBAGVjiC,GAAOq+B,WACN6D,MAAO,WACPC,cAAe,WACd,GAAIn9B,GAAWg9B,GAAa/zB,OAAWjO,EAAO0G,QAAU,IAAQ40B,IAEhE,OADAh4B,MAAM0B,IAAa,EACZA,KAKThF,EAAOu+B,cAAe,aAAc,SAAU/D,EAAG4H,EAAkB3F,GAElE,GAAI4F,GAAcC,EAAaC,EAC9BC,EAAWhI,EAAE0H,SAAU,IAAWD,GAAOl+B,KAAMy2B,EAAE3F,KAChD,MACkB,gBAAX2F,GAAE/xB,QAAwB+xB,EAAEmD,aAAe,IAAK98B,QAAQ,sCAAwCohC,GAAOl+B,KAAMy2B,EAAE/xB,OAAU,OAIlI,OAAK+5B,IAAiC,UAArBhI,EAAE8B,UAAW,IAG7B+F,EAAe7H,EAAE2H,cAAgBniC,EAAOiE,WAAYu2B,EAAE2H,eACrD3H,EAAE2H,gBACF3H,EAAE2H,cAGEK,EACJhI,EAAGgI,GAAahI,EAAGgI,GAAW37B,QAASo7B,GAAQ,KAAOI,GAC3C7H,EAAE0H,SAAU,IACvB1H,EAAE3F,MAAS0G,GAAYx3B,KAAMy2B,EAAE3F,KAAQ,IAAM,KAAQ2F,EAAE0H,MAAQ,IAAMG,GAItE7H,EAAEwD,WAAW,eAAiB,WAI7B,MAHMuE,IACLviC,EAAOsI,MAAO+5B,EAAe,mBAEvBE,EAAmB,IAI3B/H,EAAE8B,UAAW,GAAM,OAGnBgG,EAAchjC,EAAQ+iC,GACtB/iC,EAAQ+iC,GAAiB,WACxBE,EAAoBl9B,WAIrBo3B,EAAMre,OAAO,WAEZ9e,EAAQ+iC,GAAiBC,EAGpB9H,EAAG6H,KAEP7H,EAAE2H,cAAgBC,EAAiBD,cAGnCH,GAAavhC,KAAM4hC,IAIfE,GAAqBviC,EAAOiE,WAAYq+B,IAC5CA,EAAaC,EAAmB,IAGjCA,EAAoBD,EAAc/iC,IAI5B,UAtDR,GAyDD,IAAIkjC,IAAcC,GACjBC,GAAQ,EAERC,GAAmBtjC,EAAOoK,eAAiB,WAE1C,GAAIzB,EACJ,KAAMA,IAAOw6B,IACZA,GAAcx6B,GAAO1I,GAAW,GAKnC,SAASsjC,MACR,IACC,MAAO,IAAIvjC,GAAOwjC,eACjB,MAAO56B,KAGV,QAAS66B,MACR,IACC,MAAO,IAAIzjC,GAAOoK,cAAc,qBAC/B,MAAOxB,KAKVlI,EAAO06B,aAAasI,IAAM1jC,EAAOoK,cAOhC,WACC,OAAQpG,KAAKm6B,SAAWoF,MAAuBE,MAGhDF,GAGDH,GAAe1iC,EAAO06B,aAAasI,MACnChjC,EAAOmI,QAAQ86B,OAASP,IAAkB,mBAAqBA,IAC/DA,GAAe1iC,EAAOmI,QAAQ2sB,OAAS4N,GAGlCA,IAEJ1iC,EAAOw+B,cAAc,SAAUhE,GAE9B,IAAMA,EAAE0F,aAAelgC,EAAOmI,QAAQ86B,KAAO,CAE5C,GAAIj+B,EAEJ,QACCu7B,KAAM,SAAUF,EAASjD,GAGxB,GAAInU,GAAQxjB,EACXu9B,EAAMxI,EAAEwI,KAWT,IAPKxI,EAAE0I,SACNF,EAAIG,KAAM3I,EAAE73B,KAAM63B,EAAE3F,IAAK2F,EAAE7wB,MAAO6wB,EAAE0I,SAAU1I,EAAExhB,UAEhDgqB,EAAIG,KAAM3I,EAAE73B,KAAM63B,EAAE3F,IAAK2F,EAAE7wB,OAIvB6wB,EAAE4I,UACN,IAAM39B,IAAK+0B,GAAE4I,UACZJ,EAAKv9B,GAAM+0B,EAAE4I,UAAW39B,EAKrB+0B,GAAEmF,UAAYqD,EAAItD,kBACtBsD,EAAItD,iBAAkBlF,EAAEmF,UAQnBnF,EAAE0F,aAAgBG,EAAQ,sBAC/BA,EAAQ,oBAAsB,iBAI/B,KACC,IAAM56B,IAAK46B,GACV2C,EAAIxD,iBAAkB/5B,EAAG46B,EAAS56B,IAElC,MAAO2iB,IAKT4a,EAAIzC,KAAQ/F,EAAE2F,YAAc3F,EAAE/xB,MAAU,MAGxCzD,EAAW,SAAU+K,EAAGgyB,GACvB,GAAI1E,GAAQyB,EAAiBgB,EAAYW,CAKzC,KAGC,GAAKz7B,IAAc+8B,GAA8B,IAAnBiB,EAAIpgC,YAcjC,GAXAoC,EAAWzF,EAGN0pB,IACJ+Z,EAAIlB,mBAAqB9hC,EAAO8J,KAC3B84B,UACGH,IAAcxZ,IAKlB8Y,EAEoB,IAAnBiB,EAAIpgC,YACRogC,EAAInD,YAEC,CACNY,KACApD,EAAS2F,EAAI3F,OACbyB,EAAkBkE,EAAIzD,wBAIW,gBAArByD,GAAI7F,eACfsD,EAAUl2B,KAAOy4B,EAAI7F,aAKtB,KACC2C,EAAakD,EAAIlD,WAChB,MAAO53B,GAER43B,EAAa,GAQRzC,IAAU7C,EAAEiD,SAAYjD,EAAE0F,YAGT,OAAX7C,IACXA,EAAS,KAHTA,EAASoD,EAAUl2B,KAAO,IAAM,KAOlC,MAAO84B,GACFtB,GACL3E,EAAU,GAAIiG,GAKX5C,GACJrD,EAAUC,EAAQyC,EAAYW,EAAW3B,IAIrCtE,EAAE7wB,MAGuB,IAAnBq5B,EAAIpgC,WAGfyE,WAAYrC,IAEZikB,IAAW0Z,GACNC,KAGEH,KACLA,MACAziC,EAAQV,GAASgkC,OAAQV,KAG1BH,GAAcxZ,GAAWjkB,GAE1Bg+B,EAAIlB,mBAAqB98B,GAjBzBA,KAqBF66B,MAAO,WACD76B,GACJA,EAAUzF,GAAW,OAO3B,IAAIgkC,IAAOC,GACVC,GAAW,yBACXC,GAAaj1B,OAAQ,iBAAmBjN,EAAY,cAAe,KACnEmiC,GAAO,cACPC,IAAwBC,IACxBC,IACCjG,KAAM,SAAUjY,EAAMvb,GACrB,GAAI05B,GAAQzgC,KAAK0gC,YAAape,EAAMvb,GACnC9D,EAASw9B,EAAM3xB,MACf2nB,EAAQ2J,GAAOjgC,KAAM4G,GACrB45B,EAAOlK,GAASA,EAAO,KAAS/5B,EAAOw3B,UAAW5R,GAAS,GAAK,MAGhEhP,GAAU5W,EAAOw3B,UAAW5R,IAAmB,OAATqe,IAAkB19B,IACvDm9B,GAAOjgC,KAAMzD,EAAO82B,IAAKiN,EAAM1gC,KAAMuiB,IACtCse,EAAQ,EACRC,EAAgB,EAEjB,IAAKvtB,GAASA,EAAO,KAAQqtB,EAAO,CAEnCA,EAAOA,GAAQrtB,EAAO,GAGtBmjB,EAAQA,MAGRnjB,GAASrQ,GAAU,CAEnB,GAGC29B,GAAQA,GAAS,KAGjBttB,GAAgBstB,EAChBlkC,EAAO+L,MAAOg4B,EAAM1gC,KAAMuiB,EAAMhP,EAAQqtB,SAI/BC,KAAWA,EAAQH,EAAM3xB,MAAQ7L,IAAqB,IAAV29B,KAAiBC,GAaxE,MATKpK,KACJnjB,EAAQmtB,EAAMntB,OAASA,IAAUrQ,GAAU,EAC3Cw9B,EAAME,KAAOA,EAEbF,EAAMl+B,IAAMk0B,EAAO,GAClBnjB,GAAUmjB,EAAO,GAAM,GAAMA,EAAO,IACnCA,EAAO,IAGHgK,IAKV,SAASK,MAIR,MAHA/8B,YAAW,WACVk8B,GAAQhkC,IAEAgkC,GAAQvjC,EAAO0L,MAGzB,QAASs4B,IAAa35B,EAAOub,EAAMye,GAClC,GAAIN,GACHO,GAAeR,GAAUle,QAAerlB,OAAQujC,GAAU,MAC1DjmB,EAAQ,EACRra,EAAS8gC,EAAW9gC,MACrB,MAAgBA,EAARqa,EAAgBA,IACvB,GAAMkmB,EAAQO,EAAYzmB,GAAQrZ,KAAM6/B,EAAWze,EAAMvb,GAGxD,MAAO05B,GAKV,QAASQ,IAAWlhC,EAAMmhC,EAAYn+B,GACrC,GAAIgQ,GACHouB,EACA5mB,EAAQ,EACRra,EAASogC,GAAoBpgC,OAC7B6a,EAAWre,EAAOgM,WAAWoS,OAAQ,iBAE7BsmB,GAAKrhC,OAEbqhC,EAAO,WACN,GAAKD,EACJ,OAAO,CAER,IAAIE,GAAcpB,IAASa,KAC1B9kB,EAAY3Y,KAAKiE,IAAK,EAAGy5B,EAAUO,UAAYP,EAAUQ,SAAWF,GAEpElqB,EAAO6E,EAAY+kB,EAAUQ,UAAY,EACzCC,EAAU,EAAIrqB,EACdoD,EAAQ,EACRra,EAAS6gC,EAAUU,OAAOvhC,MAE3B,MAAgBA,EAARqa,EAAiBA,IACxBwmB,EAAUU,OAAQlnB,GAAQmnB,IAAKF,EAKhC,OAFAzmB,GAASqB,WAAYrc,GAAQghC,EAAWS,EAASxlB,IAElC,EAAVwlB,GAAethC,EACZ8b,GAEPjB,EAAS/W,YAAajE,GAAQghC,KACvB,IAGTA,EAAYhmB,EAASnZ,SACpB7B,KAAMA,EACNmoB,MAAOxrB,EAAOgG,UAAYw+B,GAC1BS,KAAMjlC,EAAOgG,QAAQ,GAAQk/B,kBAAqB7+B,GAClD8+B,mBAAoBX,EACpBhI,gBAAiBn2B,EACjBu+B,UAAWrB,IAASa,KACpBS,SAAUx+B,EAAQw+B,SAClBE,UACAf,YAAa,SAAUpe,EAAM/f,GAC5B,GAAIk+B,GAAQ/jC,EAAOolC,MAAO/hC,EAAMghC,EAAUY,KAAMrf,EAAM/f,EACpDw+B,EAAUY,KAAKC,cAAetf,IAAUye,EAAUY,KAAKI,OAEzD,OADAhB,GAAUU,OAAOtkC,KAAMsjC,GAChBA,GAERvf,KAAM,SAAU8gB,GACf,GAAIznB,GAAQ,EAGXra,EAAS8hC,EAAUjB,EAAUU,OAAOvhC,OAAS,CAC9C,IAAKihC,EACJ,MAAOnhC,KAGR,KADAmhC,GAAU,EACMjhC,EAARqa,EAAiBA,IACxBwmB,EAAUU,OAAQlnB,GAAQmnB,IAAK,EAUhC,OALKM,GACJjnB,EAAS/W,YAAajE,GAAQghC,EAAWiB,IAEzCjnB,EAASyiB,WAAYz9B,GAAQghC,EAAWiB,IAElChiC,QAGTkoB,EAAQ6Y,EAAU7Y,KAInB,KAFA+Z,GAAY/Z,EAAO6Y,EAAUY,KAAKC,eAElB1hC,EAARqa,EAAiBA,IAExB,GADAxH,EAASutB,GAAqB/lB,GAAQrZ,KAAM6/B,EAAWhhC,EAAMmoB,EAAO6Y,EAAUY,MAE7E,MAAO5uB,EAmBT,OAfArW,GAAO4F,IAAK4lB,EAAOwY,GAAaK,GAE3BrkC,EAAOiE,WAAYogC,EAAUY,KAAKruB,QACtCytB,EAAUY,KAAKruB,MAAMpS,KAAMnB,EAAMghC,GAGlCrkC,EAAO4kB,GAAG4gB,MACTxlC,EAAOgG,OAAQ0+B,GACdrhC,KAAMA,EACNoiC,KAAMpB,EACNngB,MAAOmgB,EAAUY,KAAK/gB,SAKjBmgB,EAAUtlB,SAAUslB,EAAUY,KAAKlmB,UACxC5Z,KAAMk/B,EAAUY,KAAK9/B,KAAMk/B,EAAUY,KAAK7H,UAC1C9e,KAAM+lB,EAAUY,KAAK3mB,MACrBF,OAAQimB,EAAUY,KAAK7mB,QAG1B,QAASmnB,IAAY/Z,EAAO0Z,GAC3B,GAAIrnB,GAAOzX,EAAMi/B,EAAQh7B,EAAOga,CAGhC,KAAMxG,IAAS2N,GAed,GAdAplB,EAAOpG,EAAOiK,UAAW4T,GACzBwnB,EAASH,EAAe9+B,GACxBiE,EAAQmhB,EAAO3N,GACV7d,EAAOyG,QAAS4D,KACpBg7B,EAASh7B,EAAO,GAChBA,EAAQmhB,EAAO3N,GAAUxT,EAAO,IAG5BwT,IAAUzX,IACdolB,EAAOplB,GAASiE,QACTmhB,GAAO3N,IAGfwG,EAAQrkB,EAAOs3B,SAAUlxB,GACpBie,GAAS,UAAYA,GAAQ,CACjCha,EAAQga,EAAMwV,OAAQxvB,SACfmhB,GAAOplB,EAId,KAAMyX,IAASxT,GACNwT,IAAS2N,KAChBA,EAAO3N,GAAUxT,EAAOwT,GACxBqnB,EAAernB,GAAUwnB,OAI3BH,GAAe9+B,GAASi/B,EAK3BrlC,EAAOukC,UAAYvkC,EAAOgG,OAAQu+B,IAEjCmB,QAAS,SAAUla,EAAOxmB,GACpBhF,EAAOiE,WAAYunB,IACvBxmB,EAAWwmB,EACXA,GAAU,MAEVA,EAAQA,EAAMlf,MAAM,IAGrB,IAAIsZ,GACH/H,EAAQ,EACRra,EAASgoB,EAAMhoB,MAEhB,MAAgBA,EAARqa,EAAiBA,IACxB+H,EAAO4F,EAAO3N,GACdimB,GAAUle,GAASke,GAAUle,OAC7Bke,GAAUle,GAAOjR,QAAS3P,IAI5B2gC,UAAW,SAAU3gC,EAAUqtB,GACzBA,EACJuR,GAAoBjvB,QAAS3P,GAE7B4+B,GAAoBnjC,KAAMuE,KAK7B,SAAS6+B,IAAkBxgC,EAAMmoB,EAAOyZ,GAEvC,GAAIrf,GAAMvb,EAAOgtB,EAAQ0M,EAAO1f,EAAOuhB,EACtCH,EAAOniC,KACPmqB,KACA1hB,EAAQ1I,EAAK0I,MACbkrB,EAAS5zB,EAAKQ,UAAY+yB,GAAUvzB,GACpCwiC,EAAW7lC,EAAO+jB,MAAO1gB,EAAM,SAG1B4hC,GAAK/gB,QACVG,EAAQrkB,EAAOskB,YAAajhB,EAAM,MACX,MAAlBghB,EAAMyhB,WACVzhB,EAAMyhB,SAAW,EACjBF,EAAUvhB,EAAM/L,MAAMkF,KACtB6G,EAAM/L,MAAMkF,KAAO,WACZ6G,EAAMyhB,UACXF,MAIHvhB,EAAMyhB,WAENL,EAAKrnB,OAAO,WAGXqnB,EAAKrnB,OAAO,WACXiG,EAAMyhB,WACA9lC,EAAOkkB,MAAO7gB,EAAM,MAAOG,QAChC6gB,EAAM/L,MAAMkF,YAOO,IAAlBna,EAAKQ,WAAoB,UAAY2nB,IAAS,SAAWA,MAK7DyZ,EAAKc,UAAah6B,EAAMg6B,SAAUh6B,EAAMi6B,UAAWj6B,EAAMk6B,WAIlB,WAAlCjmC,EAAO82B,IAAKzzB,EAAM,YACW,SAAhCrD,EAAO82B,IAAKzzB,EAAM,WAIbrD,EAAOmI,QAAQ4Y,wBAAkE,WAAxCmW,GAAoB7zB,EAAK8G,UAIvE4B,EAAMyW,KAAO,EAHbzW,EAAMuW,QAAU,iBAQd2iB,EAAKc,WACTh6B,EAAMg6B,SAAW,SACX/lC,EAAOmI,QAAQ6Y,kBACpBykB,EAAKrnB,OAAO,WACXrS,EAAMg6B,SAAWd,EAAKc,SAAU,GAChCh6B,EAAMi6B,UAAYf,EAAKc,SAAU,GACjCh6B,EAAMk6B,UAAYhB,EAAKc,SAAU,KAOpC,KAAMngB,IAAQ4F,GAEb,GADAnhB,EAAQmhB,EAAO5F,GACV6d,GAAShgC,KAAM4G,GAAU,CAG7B,SAFOmhB,GAAO5F,GACdyR,EAASA,GAAoB,WAAVhtB,EACdA,KAAY4sB,EAAS,OAAS,QAClC,QAEDxJ,GAAM7H,GAASigB,GAAYA,EAAUjgB,IAAU5lB,EAAO+L,MAAO1I,EAAMuiB,GAIrE,IAAM5lB,EAAOqI,cAAeolB,GAAS,CAC/BoY,EACC,UAAYA,KAChB5O,EAAS4O,EAAS5O,QAGnB4O,EAAW7lC,EAAO+jB,MAAO1gB,EAAM,aAI3Bg0B,IACJwO,EAAS5O,QAAUA,GAEfA,EACJj3B,EAAQqD,GAAO2zB,OAEfyO,EAAKtgC,KAAK,WACTnF,EAAQqD,GAAO+zB,SAGjBqO,EAAKtgC,KAAK,WACT,GAAIygB,EACJ5lB,GAAOgkB,YAAa3gB,EAAM,SAC1B,KAAMuiB,IAAQ6H,GACbztB,EAAO+L,MAAO1I,EAAMuiB,EAAM6H,EAAM7H,KAGlC,KAAMA,IAAQ6H,GACbsW,EAAQC,GAAa/M,EAAS4O,EAAUjgB,GAAS,EAAGA,EAAM6f,GAElD7f,IAAQigB,KACfA,EAAUjgB,GAASme,EAAMntB,MACpBqgB,IACJ8M,EAAMl+B,IAAMk+B,EAAMntB,MAClBmtB,EAAMntB,MAAiB,UAATgP,GAA6B,WAATA,EAAoB,EAAI,KAO/D,QAASwf,IAAO/hC,EAAMgD,EAASuf,EAAM/f,EAAKw/B,GACzC,MAAO,IAAID,IAAMniC,UAAU1B,KAAM8B,EAAMgD,EAASuf,EAAM/f,EAAKw/B,GAE5DrlC,EAAOolC,MAAQA,GAEfA,GAAMniC,WACLE,YAAaiiC,GACb7jC,KAAM,SAAU8B,EAAMgD,EAASuf,EAAM/f,EAAKw/B,EAAQpB,GACjD3gC,KAAKD,KAAOA,EACZC,KAAKsiB,KAAOA,EACZtiB,KAAK+hC,OAASA,GAAU,QACxB/hC,KAAK+C,QAAUA,EACf/C,KAAKsT,MAAQtT,KAAKoI,IAAMpI,KAAK8O,MAC7B9O,KAAKuC,IAAMA,EACXvC,KAAK2gC,KAAOA,IAAUjkC,EAAOw3B,UAAW5R,GAAS,GAAK,OAEvDxT,IAAK,WACJ,GAAIiS,GAAQ+gB,GAAMhe,UAAW9jB,KAAKsiB,KAElC,OAAOvB,IAASA,EAAM5f,IACrB4f,EAAM5f,IAAKnB,MACX8hC,GAAMhe,UAAUqD,SAAShmB,IAAKnB,OAEhC0hC,IAAK,SAAUF,GACd,GAAIoB,GACH7hB,EAAQ+gB,GAAMhe,UAAW9jB,KAAKsiB,KAoB/B,OAjBCtiB,MAAK2rB,IAAMiX,EADP5iC,KAAK+C,QAAQw+B,SACE7kC,EAAOqlC,OAAQ/hC,KAAK+hC,QACtCP,EAASxhC,KAAK+C,QAAQw+B,SAAWC,EAAS,EAAG,EAAGxhC,KAAK+C,QAAQw+B,UAG3CC,EAEpBxhC,KAAKoI,KAAQpI,KAAKuC,IAAMvC,KAAKsT,OAAUsvB,EAAQ5iC,KAAKsT,MAE/CtT,KAAK+C,QAAQ8/B,MACjB7iC,KAAK+C,QAAQ8/B,KAAK3hC,KAAMlB,KAAKD,KAAMC,KAAKoI,IAAKpI,MAGzC+gB,GAASA,EAAMoC,IACnBpC,EAAMoC,IAAKnjB,MAEX8hC,GAAMhe,UAAUqD,SAAShE,IAAKnjB,MAExBA,OAIT8hC,GAAMniC,UAAU1B,KAAK0B,UAAYmiC,GAAMniC,UAEvCmiC,GAAMhe,WACLqD,UACChmB,IAAK,SAAUs/B,GACd,GAAI1tB,EAEJ,OAAiC,OAA5B0tB,EAAM1gC,KAAM0gC,EAAMne,OACpBme,EAAM1gC,KAAK0I,OAA2C,MAAlCg4B,EAAM1gC,KAAK0I,MAAOg4B,EAAMne,OAQ/CvP,EAASrW,EAAO82B,IAAKiN,EAAM1gC,KAAM0gC,EAAMne,KAAM,IAErCvP,GAAqB,SAAXA,EAAwBA,EAAJ,GAT9B0tB,EAAM1gC,KAAM0gC,EAAMne,OAW3Ba,IAAK,SAAUsd,GAGT/jC,EAAO4kB,GAAGuhB,KAAMpC,EAAMne,MAC1B5lB,EAAO4kB,GAAGuhB,KAAMpC,EAAMne,MAAQme,GACnBA,EAAM1gC,KAAK0I,QAAgE,MAArDg4B,EAAM1gC,KAAK0I,MAAO/L,EAAOg4B,SAAU+L,EAAMne,QAAoB5lB,EAAOs3B,SAAUyM,EAAMne,OACrH5lB,EAAO+L,MAAOg4B,EAAM1gC,KAAM0gC,EAAMne,KAAMme,EAAMr4B,IAAMq4B,EAAME,MAExDF,EAAM1gC,KAAM0gC,EAAMne,MAASme,EAAMr4B,OASrC05B,GAAMhe,UAAUmF,UAAY6Y,GAAMhe,UAAU+E,YAC3C1F,IAAK,SAAUsd,GACTA,EAAM1gC,KAAKQ,UAAYkgC,EAAM1gC,KAAKe,aACtC2/B,EAAM1gC,KAAM0gC,EAAMne,MAASme,EAAMr4B,OAKpC1L,EAAO+E,MAAO,SAAU,OAAQ,QAAU,SAAUU,EAAGW,GACtD,GAAIggC,GAAQpmC,EAAOsB,GAAI8E,EACvBpG,GAAOsB,GAAI8E,GAAS,SAAUigC,EAAOhB,EAAQrgC,GAC5C,MAAgB,OAATqhC,GAAkC,iBAAVA,GAC9BD,EAAMhhC,MAAO9B,KAAM+B,WACnB/B,KAAKgjC,QAASC,GAAOngC,GAAM,GAAQigC,EAAOhB,EAAQrgC,MAIrDhF,EAAOsB,GAAG0E,QACTwgC,OAAQ,SAAUH,EAAOI,EAAIpB,EAAQrgC,GAGpC,MAAO1B,MAAKkQ,OAAQojB,IAAWE,IAAK,UAAW,GAAIE,OAGjDnxB,MAAMygC,SAAU/lB,QAASkmB,GAAMJ,EAAOhB,EAAQrgC,IAEjDshC,QAAS,SAAU1gB,EAAMygB,EAAOhB,EAAQrgC,GACvC,GAAIsT,GAAQtY,EAAOqI,cAAeud,GACjC8gB,EAAS1mC,EAAOqmC,MAAOA,EAAOhB,EAAQrgC,GACtC2hC,EAAc,WAEb,GAAIlB,GAAOlB,GAAWjhC,KAAMtD,EAAOgG,UAAY4f,GAAQ8gB,IAGlDpuB,GAAStY,EAAO+jB,MAAOzgB,KAAM,YACjCmiC,EAAKjhB,MAAM,GAKd,OAFCmiB,GAAYC,OAASD,EAEfruB,GAASouB,EAAOxiB,SAAU,EAChC5gB,KAAKyB,KAAM4hC,GACXrjC,KAAK4gB,MAAOwiB,EAAOxiB,MAAOyiB,IAE5BniB,KAAM,SAAU7hB,EAAMqiB,EAAYsgB,GACjC,GAAIuB,GAAY,SAAUxiB,GACzB,GAAIG,GAAOH,EAAMG,WACVH,GAAMG,KACbA,EAAM8gB,GAYP,OATqB,gBAAT3iC,KACX2iC,EAAUtgB,EACVA,EAAariB,EACbA,EAAOpD,GAEHylB,GAAcriB,KAAS,GAC3BW,KAAK4gB,MAAOvhB,GAAQ,SAGdW,KAAKyB,KAAK,WAChB,GAAIof,IAAU,EACbtG,EAAgB,MAARlb,GAAgBA,EAAO,aAC/BmkC,EAAS9mC,EAAO8mC,OAChBr+B,EAAOzI,EAAO+jB,MAAOzgB,KAEtB,IAAKua,EACCpV,EAAMoV,IAAWpV,EAAMoV,GAAQ2G,MACnCqiB,EAAWp+B,EAAMoV,QAGlB,KAAMA,IAASpV,GACTA,EAAMoV,IAAWpV,EAAMoV,GAAQ2G,MAAQmf,GAAK5/B,KAAM8Z,IACtDgpB,EAAWp+B,EAAMoV,GAKpB,KAAMA,EAAQipB,EAAOtjC,OAAQqa,KACvBipB,EAAQjpB,GAAQxa,OAASC,MAAiB,MAARX,GAAgBmkC,EAAQjpB,GAAQqG,QAAUvhB,IAChFmkC,EAAQjpB,GAAQ4nB,KAAKjhB,KAAM8gB,GAC3BnhB,GAAU,EACV2iB,EAAO/gC,OAAQ8X,EAAO,KAOnBsG,IAAYmhB,IAChBtlC,EAAOmkB,QAAS7gB,KAAMX,MAIzBikC,OAAQ,SAAUjkC,GAIjB,MAHKA,MAAS,IACbA,EAAOA,GAAQ,MAETW,KAAKyB,KAAK,WAChB,GAAI8Y,GACHpV,EAAOzI,EAAO+jB,MAAOzgB,MACrB4gB,EAAQzb,EAAM9F,EAAO,SACrB0hB,EAAQ5b,EAAM9F,EAAO,cACrBmkC,EAAS9mC,EAAO8mC,OAChBtjC,EAAS0gB,EAAQA,EAAM1gB,OAAS,CAajC,KAVAiF,EAAKm+B,QAAS,EAGd5mC,EAAOkkB,MAAO5gB,KAAMX,MAEf0hB,GAASA,EAAMG,MACnBH,EAAMG,KAAKhgB,KAAMlB,MAAM,GAIlBua,EAAQipB,EAAOtjC,OAAQqa,KACvBipB,EAAQjpB,GAAQxa,OAASC,MAAQwjC,EAAQjpB,GAAQqG,QAAUvhB,IAC/DmkC,EAAQjpB,GAAQ4nB,KAAKjhB,MAAM,GAC3BsiB,EAAO/gC,OAAQ8X,EAAO,GAKxB,KAAMA,EAAQ,EAAWra,EAARqa,EAAgBA,IAC3BqG,EAAOrG,IAAWqG,EAAOrG,GAAQ+oB,QACrC1iB,EAAOrG,GAAQ+oB,OAAOpiC,KAAMlB,YAKvBmF,GAAKm+B,WAMf,SAASL,IAAO5jC,EAAMokC,GACrB,GAAInb,GACH5Z,GAAUg1B,OAAQrkC,GAClB8C,EAAI,CAKL,KADAshC,EAAeA,EAAc,EAAI,EACtB,EAAJthC,EAAQA,GAAK,EAAIshC,EACvBnb,EAAQ2K,GAAW9wB,GACnBuM,EAAO,SAAW4Z,GAAU5Z,EAAO,UAAY4Z,GAAUjpB,CAO1D,OAJKokC,KACJ/0B,EAAMuO,QAAUvO,EAAM4Q,MAAQjgB,GAGxBqP,EAIRhS,EAAO+E,MACNkiC,UAAWV,GAAM,QACjBW,QAASX,GAAM,QACfY,YAAaZ,GAAM,UACnBa,QAAU7mB,QAAS,QACnB8mB,SAAW9mB,QAAS,QACpB+mB,YAAc/mB,QAAS,WACrB,SAAUna,EAAMolB,GAClBxrB,EAAOsB,GAAI8E,GAAS,SAAUigC,EAAOhB,EAAQrgC,GAC5C,MAAO1B,MAAKgjC,QAAS9a,EAAO6a,EAAOhB,EAAQrgC,MAI7ChF,EAAOqmC,MAAQ,SAAUA,EAAOhB,EAAQ/jC,GACvC,GAAIwe,GAAMumB,GAA0B,gBAAVA,GAAqBrmC,EAAOgG,UAAYqgC,IACjEjJ,SAAU97B,IAAOA,GAAM+jC,GACtBrlC,EAAOiE,WAAYoiC,IAAWA,EAC/BxB,SAAUwB,EACVhB,OAAQ/jC,GAAM+jC,GAAUA,IAAWrlC,EAAOiE,WAAYohC,IAAYA,EAwBnE,OArBAvlB,GAAI+kB,SAAW7kC,EAAO4kB,GAAGpd,IAAM,EAA4B,gBAAjBsY,GAAI+kB,SAAwB/kB,EAAI+kB,SACzE/kB,EAAI+kB,WAAY7kC,GAAO4kB,GAAGC,OAAS7kB,EAAO4kB,GAAGC,OAAQ/E,EAAI+kB,UAAa7kC,EAAO4kB,GAAGC,OAAO4F,UAGtE,MAAb3K,EAAIoE,OAAiBpE,EAAIoE,SAAU,KACvCpE,EAAIoE,MAAQ,MAIbpE,EAAIhU,IAAMgU,EAAIsd,SAEdtd,EAAIsd,SAAW,WACTp9B,EAAOiE,WAAY6b,EAAIhU,MAC3BgU,EAAIhU,IAAItH,KAAMlB,MAGVwc,EAAIoE,OACRlkB,EAAOmkB,QAAS7gB,KAAMwc,EAAIoE,QAIrBpE,GAGR9f,EAAOqlC,QACNkC,OAAQ,SAAUC,GACjB,MAAOA,IAERC,MAAO,SAAUD,GAChB,MAAO,GAAM7gC,KAAK+gC,IAAKF,EAAE7gC,KAAKghC,IAAO,IAIvC3nC,EAAO8mC,UACP9mC,EAAO4kB,GAAKwgB,GAAMniC,UAAU1B,KAC5BvB,EAAO4kB,GAAG8f,KAAO,WAChB,GAAIc,GACHsB,EAAS9mC,EAAO8mC,OAChBrhC,EAAI,CAIL,KAFA89B,GAAQvjC,EAAO0L,MAEHo7B,EAAOtjC,OAAXiC,EAAmBA,IAC1B+/B,EAAQsB,EAAQrhC,GAEV+/B,KAAWsB,EAAQrhC,KAAQ+/B,GAChCsB,EAAO/gC,OAAQN,IAAK,EAIhBqhC,GAAOtjC,QACZxD,EAAO4kB,GAAGJ,OAEX+e,GAAQhkC,GAGTS,EAAO4kB,GAAG4gB,MAAQ,SAAUA,GACtBA,KAAWxlC,EAAO8mC,OAAOrmC,KAAM+kC,IACnCxlC,EAAO4kB,GAAGhO,SAIZ5W,EAAO4kB,GAAGgjB,SAAW,GAErB5nC,EAAO4kB,GAAGhO,MAAQ,WACX4sB,KACLA,GAAUqE,YAAa7nC,EAAO4kB,GAAG8f,KAAM1kC,EAAO4kB,GAAGgjB,YAInD5nC,EAAO4kB,GAAGJ,KAAO,WAChBsjB,cAAetE,IACfA,GAAU,MAGXxjC,EAAO4kB,GAAGC,QACTkjB,KAAM,IACNC,KAAM,IAENvd,SAAU,KAIXzqB,EAAO4kB,GAAGuhB,QAELnmC,EAAO4U,MAAQ5U,EAAO4U,KAAKwE,UAC/BpZ,EAAO4U,KAAKwE,QAAQ6uB,SAAW,SAAU5kC,GACxC,MAAOrD,GAAO+K,KAAK/K,EAAO8mC,OAAQ,SAAUxlC,GAC3C,MAAO+B,KAAS/B,EAAG+B,OACjBG,SAGLxD,EAAOsB,GAAG4mC,OAAS,SAAU7hC,GAC5B,GAAKhB,UAAU7B,OACd,MAAO6C,KAAY9G,EAClB+D,KACAA,KAAKyB,KAAK,SAAUU,GACnBzF,EAAOkoC,OAAOC,UAAW7kC,KAAM+C,EAASZ,IAI3C,IAAI5F,GAASuoC,EACZC,GAAQn8B,IAAK,EAAGssB,KAAM,GACtBn1B,EAAOC,KAAM,GACbwP,EAAMzP,GAAQA,EAAKS,aAEpB,IAAMgP,EAON,MAHAjT,GAAUiT,EAAIhT,gBAGRE,EAAOmN,SAAUtN,EAASwD,UAMpBA,GAAKilC,wBAA0B5oC,IAC1C2oC,EAAMhlC,EAAKilC,yBAEZF,EAAMG,GAAWz1B,IAEhB5G,IAAKm8B,EAAIn8B,KAASk8B,EAAII,aAAe3oC,EAAQ0sB,YAAiB1sB,EAAQ2sB,WAAc,GACpFgM,KAAM6P,EAAI7P,MAAS4P,EAAIK,aAAe5oC,EAAQssB,aAAiBtsB,EAAQusB,YAAc,KAX9Eic,GAeTroC,EAAOkoC,QAENC,UAAW,SAAU9kC,EAAMgD,EAASZ,GACnC,GAAIywB,GAAWl2B,EAAO82B,IAAKzzB,EAAM,WAGf,YAAb6yB,IACJ7yB,EAAK0I,MAAMmqB,SAAW,WAGvB,IAAIwS,GAAU1oC,EAAQqD,GACrBslC,EAAYD,EAAQR,SACpBU,EAAY5oC,EAAO82B,IAAKzzB,EAAM,OAC9BwlC,EAAa7oC,EAAO82B,IAAKzzB,EAAM,QAC/BylC,GAAmC,aAAb5S,GAAwC,UAAbA,IAA0Bl2B,EAAO2K,QAAQ,QAASi+B,EAAWC,IAAe,GAC7Hrd,KAAYud,KAAkBC,EAAQC,CAGlCH,IACJC,EAAcL,EAAQxS,WACtB8S,EAASD,EAAY78B,IACrB+8B,EAAUF,EAAYvQ,OAEtBwQ,EAASlhC,WAAY8gC,IAAe,EACpCK,EAAUnhC,WAAY+gC,IAAgB,GAGlC7oC,EAAOiE,WAAYoC,KACvBA,EAAUA,EAAQ7B,KAAMnB,EAAMoC,EAAGkjC,IAGd,MAAftiC,EAAQ6F,MACZsf,EAAMtf,IAAQ7F,EAAQ6F,IAAMy8B,EAAUz8B,IAAQ88B,GAE1B,MAAhB3iC,EAAQmyB,OACZhN,EAAMgN,KAASnyB,EAAQmyB,KAAOmQ,EAAUnQ,KAASyQ,GAG7C,SAAW5iC,GACfA,EAAQ6iC,MAAM1kC,KAAMnB,EAAMmoB,GAE1Bkd,EAAQ5R,IAAKtL,KAMhBxrB,EAAOsB,GAAG0E,QAETkwB,SAAU,WACT,GAAM5yB,KAAM,GAAZ,CAIA,GAAI6lC,GAAcjB,EACjBkB,GAAiBl9B,IAAK,EAAGssB,KAAM,GAC/Bn1B,EAAOC,KAAM,EAwBd,OArBwC,UAAnCtD,EAAO82B,IAAKzzB,EAAM,YAEtB6kC,EAAS7kC,EAAKilC,yBAGda,EAAe7lC,KAAK6lC,eAGpBjB,EAAS5kC,KAAK4kC,SACRloC,EAAOmK,SAAUg/B,EAAc,GAAK,UACzCC,EAAeD,EAAajB,UAI7BkB,EAAal9B,KAAQlM,EAAO82B,IAAKqS,EAAc,GAAK,kBAAkB,GACtEC,EAAa5Q,MAAQx4B,EAAO82B,IAAKqS,EAAc,GAAK,mBAAmB,KAOvEj9B,IAAMg8B,EAAOh8B,IAAOk9B,EAAal9B,IAAMlM,EAAO82B,IAAKzzB,EAAM,aAAa,GACtEm1B,KAAM0P,EAAO1P,KAAO4Q,EAAa5Q,KAAOx4B,EAAO82B,IAAKzzB,EAAM,cAAc,MAI1E8lC,aAAc,WACb,MAAO7lC,MAAKsC,IAAI,WACf,GAAIujC,GAAe7lC,KAAK6lC,cAAgBtpC,CACxC,OAAQspC,IAAmBnpC,EAAOmK,SAAUg/B,EAAc,SAAsD,WAA1CnpC,EAAO82B,IAAKqS,EAAc,YAC/FA,EAAeA,EAAaA,YAE7B,OAAOA,IAAgBtpC,OAO1BG,EAAO+E,MAAOonB,WAAY,cAAeI,UAAW,eAAgB,SAAU0T,EAAQra,GACrF,GAAI1Z,GAAM,IAAInI,KAAM6hB,EAEpB5lB,GAAOsB,GAAI2+B,GAAW,SAAUnrB,GAC/B,MAAO9U,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAM48B,EAAQnrB,GACnD,GAAIszB,GAAMG,GAAWllC,EAErB,OAAKyR,KAAQvV,EACL6oC,EAAOxiB,IAAQwiB,GAAOA,EAAKxiB,GACjCwiB,EAAIxoC,SAASE,gBAAiBmgC,GAC9B58B,EAAM48B,IAGHmI,EACJA,EAAIiB,SACFn9B,EAAYlM,EAAQooC,GAAMjc,aAApBrX,EACP5I,EAAM4I,EAAM9U,EAAQooC,GAAM7b,aAI3BlpB,EAAM48B,GAAWnrB,EAPlB,IASEmrB,EAAQnrB,EAAKzP,UAAU7B,OAAQ,QAIpC,SAAS+kC,IAAWllC,GACnB,MAAOrD,GAAO2H,SAAUtE,GACvBA,EACkB,IAAlBA,EAAKQ,SACJR,EAAK2P,aAAe3P,EAAKgnB,cACzB,EAGHrqB,EAAO+E,MAAQukC,OAAQ,SAAUC,MAAO,SAAW,SAAUnjC,EAAMzD,GAClE3C,EAAO+E,MAAQ00B,QAAS,QAAUrzB,EAAMktB,QAAS3wB,EAAM,GAAI,QAAUyD,GAAQ,SAAUojC,EAAcC,GAEpGzpC,EAAOsB,GAAImoC,GAAa,SAAUjQ,EAAQnvB,GACzC,GAAIiB,GAAYjG,UAAU7B,SAAYgmC,GAAkC,iBAAXhQ,IAC5DtB,EAAQsR,IAAkBhQ,KAAW,GAAQnvB,KAAU,EAAO,SAAW,SAE1E,OAAOrK,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAMV,EAAM0H,GACjD,GAAIyI,EAEJ,OAAK9S,GAAO2H,SAAUtE,GAIdA,EAAKzD,SAASE,gBAAiB,SAAWsG,GAI3B,IAAlB/C,EAAKQ,UACTiP,EAAMzP,EAAKvD,gBAIJ6G,KAAKiE,IACXvH,EAAK+D,KAAM,SAAWhB,GAAQ0M,EAAK,SAAW1M,GAC9C/C,EAAK+D,KAAM,SAAWhB,GAAQ0M,EAAK,SAAW1M,GAC9C0M,EAAK,SAAW1M,KAIXiE,IAAU9K,EAEhBS,EAAO82B,IAAKzzB,EAAMV,EAAMu1B,GAGxBl4B,EAAO+L,MAAO1I,EAAMV,EAAM0H,EAAO6tB,IAChCv1B,EAAM2I,EAAYkuB,EAASj6B,EAAW+L,EAAW,WAQvDtL,EAAOsB,GAAGooC,KAAO,WAChB,MAAOpmC,MAAKE,QAGbxD,EAAOsB,GAAGqoC,QAAU3pC,EAAOsB,GAAG6tB,QAGP,gBAAXya,SAAuBA,QAAoC,gBAAnBA,QAAOC,QAK1DD,OAAOC,QAAU7pC,GAGjBV,EAAOU,OAASV,EAAOY,EAAIF,EASJ,kBAAX8pC,SAAyBA,OAAOC,KAC3CD,OAAQ,YAAc,WAAc,MAAO9pC,QAIzCV"}
\ No newline at end of file
diff --git a/trunk/research/players/js/json2.js b/trunk/research/players/js/json2.js
deleted file mode 100755
index d89ecc7a2..000000000
--- a/trunk/research/players/js/json2.js
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- json2.js
- 2013-05-26
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or ' '),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, regexp: true */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (typeof JSON !== 'object') {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function () {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function () {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({'': j}, '')
- : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/trunk/research/players/js/jwplayer.flash.swf b/trunk/research/players/js/jwplayer.flash.swf
deleted file mode 100644
index b5889888a..000000000
Binary files a/trunk/research/players/js/jwplayer.flash.swf and /dev/null differ
diff --git a/trunk/research/players/js/jwplayer.html5.js b/trunk/research/players/js/jwplayer.html5.js
deleted file mode 100644
index 8d041732f..000000000
--- a/trunk/research/players/js/jwplayer.html5.js
+++ /dev/null
@@ -1,194 +0,0 @@
-(function(f){f.html5={};f.html5.version="6.4.3359"})(jwplayer);
-(function(f){function h(a){return function(){a("Error loading file")}}function e(a,b,c,e){return function(){try{var g=a.responseXML;if(g&&g.firstChild)return c(a)}catch(d){}(g=f.parseXML(a.responseText))&&g.firstChild?(a=f.extend({},a,{responseXML:g}),c(a)):e&&e(a.responseText?"Invalid XML":b)}}var d=window;f.serialize=function(a){return null==a?null:"true"==a.toString().toLowerCase()?!0:"false"==a.toString().toLowerCase()?!1:isNaN(Number(a))||5c?"0":"")+c+":"+(10>a?"0":"")+a}return"00:00"};f.seconds=function(a){a=a.replace(",",".");var b=a.split(":"),c=0;"s"==a.substr(-1)?c=Number(a.substr(0,
-a.length-1)):"m"==a.substr(-1)?c=60*Number(a.substr(0,a.length-1)):"h"==a.substr(-1)?c=3600*Number(a.substr(0,a.length-1)):1e.indexOf("url")?"url("+e+")":e+k;else switch(a){case "z-index":case "opacity":b=e+k;break a;default:b=a.match(/color/i)?"#"+f.pad(e.toString(16).replace(/^0x/i,""),6)+k:0===e?0+k:Math.ceil(e)+"px"+k}}}g(c[d][a])&&!g(b)?delete c[d][a]:g(b)&&(c[d][a]=b)});
-0p?(c*=g,k*=g):(c*=p,k*=p);case h.NONE:g=p=1;case h.EXACTFIT:l=!0;break;default:g>p?0.95=B.length||(B[x].data?w.populate(B[x].data):(H=a=B[x].file,h.ajax(a,q,n)),s(!1))}function A(){var a=[];a.push({label:"Off"});for(var b=0;b=q)){b=c;break}-1==b?a(""):b!=l&&(l=b,a(g[c].text))}function f(a,b){h(b,
-function(b,c){a.style[b]=c})}var g,p,j,l,q,n="visible",r;this.hide=function(){f(p,{display:"none"});r&&(clearInterval(r),r=null)};this.populate=function(a){l=-1;g=a;c()};this.resize=function(){b()};p=document.createElement("div");j=document.createElement("span");p.appendChild(j);d.appendChild(p);f(p,{display:"block",height:"auto",position:"absolute",bottom:"20px",textAlign:"center",width:"100%"});f(j,{color:"#"+e.color.substr(-6),display:"inline-block",fontFamily:e.fontFamily,fontStyle:e.fontStyle,
-fontWeight:e.fontWeight,height:"auto",margin:"auto",position:"relative",textAlign:"center",textDecoration:e.textDecoration,wordWrap:"break-word",width:"auto"});e.back?f(j,{background:"#000"}):f(j,{textShadow:"-2px 0px 1px #000,2px 0px 1px #000,0px -2px 1px #000,0px 2px 1px #000,-1px 1px 1px #000,1px 1px 1px #000,1px -1px 1px #000,1px 1px 1px #000"});this.show=function(){f(p,{display:"block"});r||(r=setInterval(b,250));b()};this.update=function(a){q=a;g&&c()}}})(jwplayer.html5);
-(function(f){var h=f.html5,e=f.utils,d=f.events,a=d.state,b=e.css;f=e.transitionStyle;var c="button",k="text",g="divider",p="slider",j="100%",l={display:"none"},q={display:v},n=!1,r=!0,s=null,v=void 0,u=window,A=document;h.controlbar=function(f,y){function t(a,b,c){return{name:a,type:b,className:c}}function w(a){var b=n,c;K.elapsed&&(c=e.timeFormat(a.position),K.elapsed.innerHTML=c,b=c.length!=e.timeFormat(va).length);K.duration&&(c=e.timeFormat(a.duration),K.duration.innerHTML=c,b=b||c.length!=e.timeFormat(ia).length);
-0ka.right?a.offsetX(ka.right-b.right):b.lefta&&(a=0);0.9da.maxwidth;c=wa?0:da.margin;b(D(),{left:a?"50%":c,right:a?v:c,"margin-left":a?N.clientWidth/-2:v,width:a?j:v});ka=e.bounds(N);e.foreach(Ea,function(a,b){pa(b)})};ha.audioMode=function(a){a!=wa&&(wa=a,b(D(".jwfullscreen"),{display:a?"none":v}),b(D(".jwhd"),{display:a?"none":v}),b(D(".jwcc"),{display:a?"none":v}),ya())};ha.element=function(){return N};ha.margin=function(){return parseInt(da.margin)};
-ha.height=function(){return U};ha.show=function(){ha.visible||(clearTimeout(Ha),Ha=v,ha.visible=!0,N.style.display="inline-block",ya(),z(),Ha=setTimeout(function(){N.style.opacity=1},10))};ha.hide=function(){ha.visible&&(ha.visible=!1,N.style.opacity=0,clearTimeout(Ha),Ha=v,Ha=setTimeout(function(){N.style.display="none"},150))};K={};G=f;$=G.id+"_controlbar";ia=va=0;N=L();N.id=$;N.className="jwcontrolbar";R=G.skin;ga=R.getComponentLayout("controlbar");ga||(ga=W.layout);e.clearCss("#"+$);H();var Ia=
-I("capLeft"),T=I("capRight"),ab=I("background",{position:"absolute",left:O("capLeft").width,right:O("capRight").width,"background-repeat":"repeat-x"},r);ab&&N.appendChild(ab);Ia&&N.appendChild(Ia);Ga("left");Ga("center");Ga("right");N.appendChild(xa.left);N.appendChild(xa.center);N.appendChild(xa.right);K.hd&&(la=new h.menu("hd",$+"_hd",R,Ta),ba(la,K.hd,oa,ua),Ea.hd=la);K.cc&&(ma=new h.menu("cc",$+"_cc",R,Ua),ba(ma,K.cc,aa,P),Ea.cc=ma);K.mute&&(K.volume&&K.volume.vertical)&&(ra=new h.overlay($+"_volumeoverlay",
-R),ra.setContents(K.volume),ba(ra,K.mute,X),Ea.volume=ra);K.fullscreen&&(Ma=new h.overlay($+"_fullscreenoverlay",R),Ia=A.createElement("div"),Ia.className="jwoverlaytext",Ia.innerHTML="Fullscreen",Ma.setContents(Ia),ba(Ma,K.fullscreen,ea),Ea.fullscreen=Ma);b(D(".jwright"),{right:O("capRight").width});T&&N.appendChild(T);G.jwAddEventListener(d.JWPLAYER_MEDIA_TIME,w);G.jwAddEventListener(d.JWPLAYER_PLAYER_STATE,function(c){switch(c.newstate){case a.BUFFERING:case a.PLAYING:b(D(".jwtimeSliderThumb"),
-{opacity:1});Z("play",r);break;case a.PAUSED:ta||Z("play",n);break;case a.IDLE:Z("play",n),b(D(".jwtimeSliderThumb"),{opacity:0}),K.timeRail&&(K.timeRail.className="jwrail",setTimeout(function(){K.timeRail.className+=" jwsmooth"},100)),Da(0),w({position:0,duration:0})}});G.jwAddEventListener(d.JWPLAYER_PLAYLIST_ITEM,function(a){a=G.jwGetPlaylist()[a.index].tracks;if("array"==e.typeOf(a))for(var b=0;bb.left&&a.offsetX(c.left-b.left+8);n.show();h.foreach(y,function(a,b){a!=g&&b.hide()})},!1);j.addEventListener("mouseout",function(){s=setTimeout(n.hide,100)},!1);t.appendChild(n.element());y[g]=n}A++;r()}};z.removeButton=function(a){m[a]&&(w.removeChild(m[a].element),w.removeChild(m[a].divider),delete m[a],A--,r())};z.numButtons=function(){return A};z.visible=!1;t=q("div","jwdock");w=q("div","jwdockbuttons");t.appendChild(w);t.id=v;var x=n("button"),B=n("buttonOver"),
-C=n("buttonActive");x&&(e(l(),{height:x.height,padding:s.margin}),e(a,{height:x.height}),e(l("button"),{width:x.width,cursor:"pointer",border:c,background:x.src}),B.src&&e(l("button:hover"),{background:B.src}),C.src&&e(l("button:active"),{background:C.src}),e(l("button\x3ediv"),{opacity:s.iconalpha}),e(l("button:hover\x3ediv"),{opacity:s.iconalphaover}),e(l("button:active\x3ediv"),{opacity:s.iconalphaactive}),e(l(".jwoverlay"),{top:s.margin+x.height}),j("capLeft",w),j("capRight",w),j("divider"));
-setTimeout(function(){d(t)})};e(".jwdock",{opacity:0,display:c});e(".jwdock \x3e *",{height:"100%","float":"left"});e(".jwdock \x3e .jwoverlay",{height:"auto","float":c,"z-index":99});e(a+" button",{position:"relative"});e(a+" \x3e *",{height:"100%","float":"left"});e(a+" .divider",{display:c});e(a+" button ~ .divider",{display:k});e(a+" .capLeft, "+a+" .capRight",{display:c});e(a+" .capRight",{"float":"right"});e(a+" button \x3e div",{left:0,right:0,top:0,bottom:0,margin:5,position:"absolute","background-position":"center",
-"background-repeat":"no-repeat"});h.transitionStyle(".jwdock","background .15s, opacity .15s");h.transitionStyle(".jwdock .jwoverlay","opacity .15s");h.transitionStyle(a+" button div","opacity .15s")})(jwplayer.html5);
-(function(f){var h=jwplayer,e=h.utils,d=h.events,a=d.state,b=h.playlist;f.instream=function(c,h,g,p){function j(a){E&&H.sendEvent(a.type,a);I=!0;F.jwInstreamDestroy(!1)}function l(a){E&&E&&H.sendEvent(a.type,a)}function q(){E&&x.play()}function n(){E&&setTimeout(function(){F.jwInstreamDestroy(!0)},10)}function r(a){a.width&&a.height&&m.resizeMedia()}function s(){B&&B.redraw();C&&C.redraw()}var v={controlbarseekable:"never",controlbarpausable:!0,controlbarstoppable:!0,playlistclickable:!0},u,A,m=g,
-y,t,w,z,x,B,C,E=!1,H,D,L,F=this,I=!1,Q=!0;this.load=function(g,M){e.isAndroid(2.3)?j({type:d.JWPLAYER_ERROR,message:"Error loading instream: Cannot play instream on Android 2.3"}):(E=!0,A=e.extend(v,M),u=new b.item(g),D=document.createElement("div"),D.id=F.id+"_instream_container",y=p.detachMedia(),x=new f.video(y),x.addGlobalListener(l),x.addEventListener(d.JWPLAYER_MEDIA_META,r),x.addEventListener(d.JWPLAYER_MEDIA_COMPLETE,n),x.addEventListener(d.JWPLAYER_MEDIA_BUFFER_FULL,q),x.attachMedia(),x.mute(h.mute),
-x.volume(h.volume),L=new f.model({},x),L.setVolume(h.volume),L.setMute(h.mute),L.addEventListener(d.JWPLAYER_ERROR,j),z=h.playlist[h.item],w=h.getVideo().checkComplete()?a.IDLE:c.jwGetState(),p.checkBeforePlay()&&(w=a.PLAYING,Q=!1),t=y.currentTime,L.setPlaylist([g]),I||((w==a.BUFFERING||w==a.PLAYING)&&y.pause(),C=new f.display(F),C.setAlternateClickHandler(function(b){L.state==a.PAUSED?F.jwInstreamPlay():(F.jwInstreamPause(),E&&H.sendEvent(d.JWPLAYER_INSTREAM_CLICK,b))}),D.appendChild(C.element()),
-e.isMobile()||(B=new f.controlbar(F),D.appendChild(B.element()),B.show()),m.setupInstream(D,y),s(),x.load(L.playlist[0])))};this.jwInstreamDestroy=function(b){if(E){E=!1;w!=a.IDLE?x.load(z,!1):x.stop();H.resetEventListeners();I||C.revertAlternateClickHandler();x.detachMedia();m.destroyInstream();if(B)try{B.element().parentNode.removeChild(B.getDisplayElement())}catch(c){}H.sendEvent(d.JWPLAYER_INSTREAM_DESTROYED,{reason:b?"complete":"destroyed"});p.attachMedia();if(w==a.BUFFERING||w==a.PLAYING)y.play(),
-h.playlist[h.item]==z&&Q&&h.getVideo().seek(t)}};this.jwInstreamAddEventListener=function(a,b){H.addEventListener(a,b)};this.jwInstreamRemoveEventListener=function(a,b){H.removeEventListener(a,b)};this.jwInstreamPlay=function(){E&&(x.play(!0),h.state=jwplayer.events.state.PLAYING,C.show())};this.jwInstreamPause=function(){E&&(x.pause(!0),h.state=jwplayer.events.state.PAUSED,C.show())};this.jwInstreamSeek=function(a){E&&x.seek(a)};this.jwPlay=function(){"true"==A.controlbarpausable.toString().toLowerCase()&&
-this.jwInstreamPlay()};this.jwPause=function(){"true"==A.controlbarpausable.toString().toLowerCase()&&this.jwInstreamPause()};this.jwStop=function(){"true"==A.controlbarstoppable.toString().toLowerCase()&&(this.jwInstreamDestroy(),c.jwStop())};this.jwSeek=function(a){switch(A.controlbarseekable.toLowerCase()){case "always":this.jwInstreamSeek(a);break;case "backwards":L.position>a&&this.jwInstreamSeek(a)}};this.jwSeekDrag=function(a){L.seekDrag(a)};this.jwGetPosition=function(){};this.jwGetDuration=
-function(){};this.jwGetWidth=c.jwGetWidth;this.jwGetHeight=c.jwGetHeight;this.jwGetFullscreen=c.jwGetFullscreen;this.jwSetFullscreen=c.jwSetFullscreen;this.jwGetVolume=function(){return h.volume};this.jwSetVolume=function(a){L.setVolume(a);c.jwSetVolume(a)};this.jwGetMute=function(){return h.mute};this.jwSetMute=function(a){L.setMute(a);c.jwSetMute(a)};this.jwGetState=function(){return h.state};this.jwGetPlaylist=function(){return[u]};this.jwGetPlaylistIndex=function(){return 0};this.jwGetStretching=
-function(){return h.config.stretching};this.jwAddEventListener=function(a,b){H.addEventListener(a,b)};this.jwRemoveEventListener=function(a,b){H.removeEventListener(a,b)};this.jwSetCurrentQuality=function(){};this.jwGetQualityLevels=function(){return[]};this.skin=c.skin;this.id=c.id+"_instream";H=new d.eventdispatcher;c.jwAddEventListener(d.JWPLAYER_RESIZE,s);c.jwAddEventListener(d.JWPLAYER_FULLSCREEN,function(a){l(a);s()});return this}})(jwplayer.html5);
-(function(f){var h=f.utils,e=h.css,d=f.events.state,a=f.html5.logo=function(b,c){function k(a){h.exists(a)&&a.stopPropagation();if(!n||!j.link)g.jwGetState()==d.IDLE||g.jwGetState()==d.PAUSED?g.jwPlay():g.jwPause();n&&j.link&&(g.jwPause(),g.jwSetFullscreen(!1),window.open(j.link,j.linktarget))}var g=b,p=g.id+"_logo",j,l,q=a.defaults,n=!1;this.resize=function(){};this.element=function(){return l};this.offset=function(a){e("#"+p+" ",{"margin-bottom":a})};this.position=function(){return j.position};
-this.margin=function(){return parseInt(j.margin)};this.hide=function(a){if(j.hide||a)n=!1,l.style.visibility="hidden",l.style.opacity=0};this.show=function(){n=!0;l.style.visibility="visible";l.style.opacity=1};var r="o";g.edition&&(r=g.edition(),r="pro"==r?"p":"premium"==r?"r":"ads"==r?"a":"free"==r?"f":"o");if("o"==r||"f"==r)q.link="http://www.longtailvideo.com/jwpabout/?a\x3dl\x26v\x3d"+f.version+"\x26m\x3dh\x26e\x3d"+r;j=h.extend({},q,c);j.hide="true"==j.hide.toString();l=document.createElement("img");
-l.className="jwlogo";l.id=p;if(j.file){var q=/(\w+)-(\w+)/.exec(j.position),r={},s=j.margin;3==q.length?(r[q[1]]=s,r[q[2]]=s):r.top=r.right=s;e("#"+p+" ",r);l.src=(j.prefix?j.prefix:"")+j.file;l.onclick=k}else l.style.display="none";return this};a.defaults={prefix:h.repo(),file:"logo.png",linktarget:"_top",margin:8,hide:!1,position:"top-right"};e(".jwlogo",{cursor:"pointer",position:"absolute","z-index":100,opacity:0});h.transitionStyle(".jwlogo","visibility .15s, opacity .15s")})(jwplayer);
-(function(f){var h=f.html5,e=f.utils,d=e.css,a=void 0;h.menu=function(b,c,f,g){function p(a,b){return function(){v(a);q&&q(b)}}function j(a,b){var c=document.createElement("div");a&&(c.className=a);b&&b.appendChild(c);return c}function l(b){return(b=f.getSkinElement("tooltip",b))?b:{width:0,height:0,src:a}}var q=g,n=new h.overlay(c+"_overlay",f);g=e.extend({fontcase:a,fontcolor:"#cccccc",fontsize:11,fontweight:a,activecolor:"#ffffff",overcolor:"#ffffff"},f.getComponentSettings("tooltip"));var r,s=
-[];this.element=function(){return n.element()};this.addOption=function(a,b){var e=j("jwoption",r);e.id=c+"_option_"+b;e.innerHTML=a;e.addEventListener("click",p(s.length,b));s.push(e)};this.clearOptions=function(){for(;0a?(a=
-0,b=!0):a=-1==a||a>c.playlist.length?c.playlist.length-1:a;if(b||a!=c.item)c.item=a,c.sendEvent(e.JWPLAYER_PLAYLIST_ITEM,{index:c.item})};c.setVolume=function(a){c.mute&&0a&&(a=0);1parseFloat(jwplayer.version))&&s("Incompatible player version");if(0===a.length)r(n);else for(b=0;bp[b].end;)b++;b==p.length&&b--;if(p[b].text)if(a=p[b].text,0>a.indexOf("://")&&(a=j?j+"/"+a:a),0x)&&Z(x);f()}},emptied:c,ended:function(){F&&C!=d.IDLE&&(Q=-1,X=!0,b(e.JWPLAYER_MEDIA_BEFORECOMPLETE),
-F&&(n(d.IDLE),b(e.JWPLAYER_MEDIA_COMPLETE),X=!1))},error:function(){F&&(h.log("Error playing media: %o",m.error),L.sendEvent(e.JWPLAYER_MEDIA_ERROR,{message:"Error loading media: File could not be played"}),n(d.IDLE))},loadeddata:c,loadedmetadata:g,loadstart:c,pause:p,play:p,playing:p,progress:function(){w&&(0Q&&(Q=0);for(a=0;aa)&&(Q=a,h.saveCookie("qualityLabel",I[a].label),b(e.JWPLAYER_MEDIA_LEVEL_CHANGED,
-{currentQuality:a,levels:l(I)}),a=m.currentTime,q(),M.seek(a)))};M.getCurrentQuality=function(){return Q};M.getQualityLevels=function(){return l(I)};m=a;h.foreach(v,function(a,b){m.addEventListener(a,b,!1)});m.controls=!0;m.controls=!1;m.setAttribute("x-webkit-airplay","allow");F=!0}})(jwplayer);
-(function(f){var h=jwplayer.utils,e=jwplayer.events,d=e.state,a=h.css,b=h.isMobile(),c=h.isIPad(),k=h.isIPod(),g=h.isAndroid(),p=h.isIOS(),j=document,l="aspectMode",q="jwmain",n="jwvideo",r="jwplaylistcontainer",s=!0,v=!1,u="hidden",A="none",m="block";f.view=function(y,t){function w(a){a&&(a.element().addEventListener("mousemove",B,v),a.element().addEventListener("mouseout",C,v))}function z(a,b){var c=j.createElement(a);b&&(c.className=b);return c}function x(){clearTimeout(pa);if(S.jwGetState()==
-d.PLAYING||S.jwGetState()==d.PAUSED)oa(),Aa||(pa=setTimeout(E,Da))}function B(){clearTimeout(pa);Aa=s}function C(){Aa=v}function E(){S.jwGetState()!=d.BUFFERING&&(G&&(!U&&!N)&&G.hide(),T&&(!ia&&!N)&&T.hide(),X());clearTimeout(pa);pa=0}function H(a){ca.sendEvent(a.type,a)}function D(b,c){h.exists(b)&&h.exists(c)&&(J.width=b,J.height=c);P.style.width=isNaN(b)?b:b+"px";-1==P.className.indexOf(l)&&(P.style.height=isNaN(c)?c:c+"px");R&&R.redraw();G&&G.redraw();W&&(W.offset(G&&0<=W.position().indexOf("bottom")?
-G.height()+G.margin():0),setTimeout(function(){T&&T.offset("top-left"==W.position()?W.element().clientWidth+W.margin():0)},500));var d=J.playlistsize,f=J.playlistposition;if(K&&d&&("right"==f||"bottom"==f)){K.redraw();var g={display:m},j={};g[f]=0;j[f]=d;"right"==f?g.width=d:g.height=d;a(fa(r),g);a(fa(q),j)}L(c);F();ca.sendEvent(e.JWPLAYER_RESIZE)}function L(a){U=(!b||N)&&40>=a&&0>a.toString().indexOf("%");G&&(U?(G.audioMode(s),oa(),R.hidePreview(s),Z(),aa(v)):(G.audioMode(v),Pa(S.jwGetState())));
-W&&U&&X();P.style.backgroundColor=U?"transparent":"#000"}function F(){Y&&h.stretch(J.stretching,Y,ja.clientWidth,ja.clientHeight,Y.videoWidth,Y.videoHeight)}function I(a){if(J.fullscreen)switch(a.keyCode){case 27:Ba(v)}}function Q(a){p||(a?(P.className+=" jwfullscreen",j.getElementsByTagName("body")[0].style["overflow-y"]=u):(P.className=P.className.replace(/\s+jwfullscreen/,""),j.getElementsByTagName("body")[0].style["overflow-y"]=""))}function V(){var a;a:{a=[j.mozFullScreenElement,j.webkitCurrentFullScreenElement,
-Y.webkitDisplayingFullscreen];for(var b=0;bj||j>c)}else c=void 0;if(c)return g;c=a.substring(0,a.indexOf("://")+3);var j=a.substring(c.length,a.indexOf("/",c.length+1)),d;0===g.indexOf("/")?d=g.split("/"):(d=a.split("?")[0],d=d.substring(c.length+j.length+1,d.lastIndexOf("/")),d=d.split("/").concat(g.split("/")));
-for(var h=[],e=0;ec&&0>j&&(!a||!isNaN(a))?d.CDN:d.RELATIVE}};b.getPluginName=function(a){return a.replace(/^(.*\/)?([^-]*)-?.*\.(swf|js)$/,"$2")};b.getPluginVersion=function(a){return a.replace(/[^-]*-?([^\.]*).*$/,"$1")};
-b.isYouTube=function(a){return-1=c.length&&(c[1]=0);for(var d=a.strToLongs(e.encode(b).slice(0,16)),g=c.length,f=c[g-1],m=c[0],n,k=Math.floor(6+52/g),h=0;0>>2&3;for(var r=0;r>>5^m<<2)+(m>>>3^f<<4)^(h^m)+(d[r&3^n]^f),f=c[r]+=f}c=a.longsToStr(c);return l.encode(c)};a.decrypt=function(j,b){if(0==j.length)return"";for(var c=a.strToLongs(l.decode(j)),
-d=a.strToLongs(e.encode(b).slice(0,16)),g=c.length,f=c[g-1],m=c[0],n,k=2654435769*Math.floor(6+52/g);0!=k;){n=k>>>2&3;for(var h=g-1;0<=h;h--)f=c[0>>5^m<<2)+(m>>>3^f<<4)^(k^m)+(d[h&3^n]^f),m=c[h]-=f;k-=2654435769}c=a.longsToStr(c);c=c.replace(/\0+$/,"");return e.decode(c)};a.strToLongs=function(a){for(var b=Array(Math.ceil(a.length/4)),c=0;c>>8&255,a[c]>>>16&255,a[c]>>>24&255);return b.join("")};var l={code:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\x3d",encode:function(a,b){var c,d,g,f,m=[],n="",k,h,r=l.code;h=("undefined"==typeof b?0:b)?e.encode(a):a;k=h.length%3;if(0k++;)n+="\x3d",h+="\x00";for(k=0;k>18&63,d=f>>12&63,g=f>>6&63,f&=63,m[k/
-3]=r.charAt(c)+r.charAt(d)+r.charAt(g)+r.charAt(f);m=m.join("");return m=m.slice(0,m.length-n.length)+n},decode:function(a,b){b="undefined"==typeof b?!1:b;var c,d,g,f,m,n=[],k,h=l.code;k=b?e.decode(a):a;for(var r=0;r>>16&255,d=g>>>8&255,g&=255,n[r/4]=String.fromCharCode(c,d,g),64==m&&(n[r/4]=String.fromCharCode(c,d)),64==f&&(n[r/4]=String.fromCharCode(c));
-f=n.join("");return b?e.decode(f):f}},e={encode:function(a){a=a.replace(/[\u0080-\u07ff]/g,function(a){a=a.charCodeAt(0);return String.fromCharCode(192|a>>6,128|a&63)});return a=a.replace(/[\u0800-\uffff]/g,function(a){a=a.charCodeAt(0);return String.fromCharCode(224|a>>12,128|a>>6&63,128|a&63)})},decode:function(a){a=a.replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(a){a=(a.charCodeAt(0)&15)<<12|(a.charCodeAt(1)&63)<<6|a.charCodeAt(2)&63;return String.fromCharCode(a)});return a=
-a.replace(/[\u00c0-\u00df][\u0080-\u00bf]/g,function(a){a=(a.charCodeAt(0)&31)<<6|a.charCodeAt(1)&63;return String.fromCharCode(a)})}}}(jwplayer.utils),function(f){f.events={COMPLETE:"COMPLETE",ERROR:"ERROR",API_READY:"jwplayerAPIReady",JWPLAYER_READY:"jwplayerReady",JWPLAYER_FULLSCREEN:"jwplayerFullscreen",JWPLAYER_RESIZE:"jwplayerResize",JWPLAYER_ERROR:"jwplayerError",JWPLAYER_MEDIA_BEFOREPLAY:"jwplayerMediaBeforePlay",JWPLAYER_MEDIA_BEFORECOMPLETE:"jwplayerMediaBeforeComplete",JWPLAYER_COMPONENT_SHOW:"jwplayerComponentShow",
-JWPLAYER_COMPONENT_HIDE:"jwplayerComponentHide",JWPLAYER_MEDIA_BUFFER:"jwplayerMediaBuffer",JWPLAYER_MEDIA_BUFFER_FULL:"jwplayerMediaBufferFull",JWPLAYER_MEDIA_ERROR:"jwplayerMediaError",JWPLAYER_MEDIA_LOADED:"jwplayerMediaLoaded",JWPLAYER_MEDIA_COMPLETE:"jwplayerMediaComplete",JWPLAYER_MEDIA_SEEK:"jwplayerMediaSeek",JWPLAYER_MEDIA_TIME:"jwplayerMediaTime",JWPLAYER_MEDIA_VOLUME:"jwplayerMediaVolume",JWPLAYER_MEDIA_META:"jwplayerMediaMeta",JWPLAYER_MEDIA_MUTE:"jwplayerMediaMute",JWPLAYER_MEDIA_LEVELS:"jwplayerMediaLevels",
-JWPLAYER_MEDIA_LEVEL_CHANGED:"jwplayerMediaLevelChanged",JWPLAYER_CAPTIONS_CHANGED:"jwplayerCaptionsChanged",JWPLAYER_CAPTIONS_LIST:"jwplayerCaptionsList",JWPLAYER_PLAYER_STATE:"jwplayerPlayerState",state:{BUFFERING:"BUFFERING",IDLE:"IDLE",PAUSED:"PAUSED",PLAYING:"PLAYING"},JWPLAYER_PLAYLIST_LOADED:"jwplayerPlaylistLoaded",JWPLAYER_PLAYLIST_ITEM:"jwplayerPlaylistItem",JWPLAYER_PLAYLIST_COMPLETE:"jwplayerPlaylistComplete",JWPLAYER_DISPLAY_CLICK:"jwplayerViewClick",JWPLAYER_CONTROLS:"jwplayerViewControls",
-JWPLAYER_INSTREAM_CLICK:"jwplayerInstreamClicked",JWPLAYER_INSTREAM_DESTROYED:"jwplayerInstreamDestroyed"}}(jwplayer),function(f){var a=jwplayer.utils;f.eventdispatcher=function(f,e){var j,b;this.resetEventListeners=function(){j={};b=[]};this.resetEventListeners();this.addEventListener=function(b,d,g){try{a.exists(j[b])||(j[b]=[]),"string"==a.typeOf(d)&&(d=(new Function("return "+d))()),j[b].push({listener:d,count:g})}catch(e){a.log("error",e)}return!1};this.removeEventListener=function(b,d){if(j[b]){try{for(var g=
-0;gparseFloat(f.version)))m=!0,n="Incompatible player version",c()});0==b&&c()}}var g=a.loaderstatus.NEW,q=!1,m=!1,n,k=b,h=new l.eventdispatcher;a.extend(this,h);this.setupPlugins=function(b,d,c){var g={length:0,plugins:{}},h=0,f={},r=j.getPlugins();e(d.plugins,
-function(e,j){var k=a.getPluginName(e),l=r[k],m=l.getFlashPath(),n=l.getJS(),q=l.getURL();m&&(g.plugins[m]=a.extend({},j),g.plugins[m].pluginmode=l.getPluginmode(),g.length++);try{if(n&&d.plugins&&d.plugins[q]){var v=document.createElement("div");v.id=b.id+"_"+k;v.style.position="absolute";v.style.top=0;v.style.zIndex=h+10;f[k]=l.getNewInstance(b,a.extend({},d.plugins[q]),v);h++;b.onReady(c(f[k],v,!0));b.onResize(c(f[k],v))}}catch(B){a.log("ERROR: Failed to load "+k+".")}});b.plugins=f;return g};
-this.load=function(){if(!(a.exists(b)&&"object"!=a.typeOf(b))){g=a.loaderstatus.LOADING;e(b,function(b){a.exists(b)&&(b=j.addPlugin(b),b.addEventListener(l.COMPLETE,d),b.addEventListener(l.ERROR,r))});var c=j.getPlugins();e(c,function(a,b){b.load()})}d()};var r=this.pluginFailed=function(){m||(m=!0,n="File not found",c())};this.getStatus=function(){return g}}}(jwplayer),function(f){f.playlist=function(a){var l=[];if("array"==f.utils.typeOf(a))for(var e=0;em.playlist.length&&(0==m.playlist.length||
-!m.playlist[0].sources||0==m.playlist[0].sources.length))g();else if(s.getStatus()==a.loaderstatus.COMPLETE){for(var e=0;e=c||0>=d?0:100*(d/c)+"%")}-1==b.width.toString().indexOf("%")?delete b.aspectratio:c?b.aspectratio=c:delete b.aspectratio;return b}).addConfig=function(b,c){a(c);return e.extend(b,c)}}(jwplayer),function(f){var a=f.utils,l=document;f.embed.download=function(e,f,b){function c(b,d){for(var c=l.querySelectorAll(b),g=0;gh)return k.sendEvent(l.ERROR,{message:"Flash version must be 10.0 or greater"}),
-!1;var f,p,t=g.config.listbar,s=a.extend({},c);if(j.id+"_wrapper"==j.parentNode.id)f=document.getElementById(j.id+"_wrapper");else{f=document.createElement("div");p=document.createElement("div");p.style.display="none";p.id=j.id+"_aspect";f.id=j.id+"_wrapper";f.style.position="relative";f.style.display="block";f.style.width=a.styleDimension(s.width);f.style.height=a.styleDimension(s.height);if(g.config.aspectratio){var u=parseFloat(g.config.aspectratio);p.style.display="block";p.style.marginTop=g.config.aspectratio;
-f.style.height="auto";f.style.display="inline-block";t&&("bottom"==t.position?p.style.paddingBottom=t.size+"px":"right"==t.position&&(p.style.marginBottom=-1*t.size*(u/100)+"px"))}j.parentNode.replaceChild(f,j);f.appendChild(j);f.appendChild(p)}f=d.setupPlugins(g,s,m);0=
-s.height?"transparent":"opaque";p="height width modes events primary base fallback volume".split(" ");for(t=0;t
-
-
- 标题:
- 日志内容
-
-*/
-var srs_log_disabled = false;
-function info(desc) {
- if (srs_log_disabled) {
- return;
- }
-
- $("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn");
- $("#txt_log_title").text("Info:");
- $("#txt_log_msg").html(desc);
-}
-function warn(code, desc) {
- if (srs_log_disabled) {
- return;
- }
-
- $("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn");
- $("#txt_log_title").text("Warn:");
- $("#txt_log_msg").html("code: " + code + ", " + desc);
-}
-function error(code, desc) {
- if (srs_log_disabled) {
- return;
- }
-
- $("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn");
- $("#txt_log_title").text("Error:");
- $("#txt_log_msg").html("code: " + code + ", " + desc);
-}
diff --git a/trunk/research/players/js/srs.page.js b/trunk/research/players/js/srs.page.js
deleted file mode 100755
index 0fd37b2ad..000000000
--- a/trunk/research/players/js/srs.page.js
+++ /dev/null
@@ -1,449 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////
-
-// to query the swf anti cache.
-function srs_get_version_code() { return "1.33"; }
-
-/**
-* player specified size.
-*/
-function srs_get_player_modal() { return 740; }
-function srs_get_player_width() { return srs_get_player_modal() - 30; }
-function srs_get_player_height() { return srs_get_player_width() * 9 / 19; }
-
-// get the default vhost for players.
-function srs_get_player_vhost() { return "players"; }
-// the api server port, for chat room.
-function srs_get_api_server_port() { return 8085; }
-// the srs http server port
-function srs_get_srs_http_server_port() { return 8080; }
-
-//////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////
-
-/**
-* update the navigator, add same query string.
-*/
-function update_nav() {
- $("#srs_index").attr("href", "index.html" + window.location.search);
- $("#nav_srs_player").attr("href", "srs_player.html" + window.location.search);
- $("#nav_srs_publisher").attr("href", "srs_publisher.html" + window.location.search);
- $("#nav_srs_chat").attr("href", "srs_chat.html" + window.location.search);
- $("#nav_srs_bwt").attr("href", "srs_bwt.html" + window.location.search);
- $("#nav_jwplayer6").attr("href", "jwplayer6.html" + window.location.search);
- $("#nav_osmf").attr("href", "osmf.html" + window.location.search);
- $("#nav_vlc").attr("href", "vlc.html" + window.location.search);
-}
-
-// Special extra params, such as auth_key.
-function user_extra_params(query, params) {
- var queries = params || [];
- var server = (query.server == undefined)? window.location.hostname:query.server;
- var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost;
-
- for (var key in query.user_query) {
- if (key == 'app' || key == 'autostart' || key == 'dir'
- || key == 'filename' || key == 'host' || key == 'hostname'
- || key == 'http_port' || key == 'pathname' || key == 'port'
- || key == 'server' || key == 'stream' || key == 'buffer'
- || key == 'schema' || key == 'vhost'
- ) {
- continue;
- }
-
- if (query[key]) {
- queries.push(key + '=' + query[key]);
- }
- }
-
- return queries;
-}
-
-/**
-@param server the ip of server. default to window.location.hostname
-@param vhost the vhost of rtmp. default to window.location.hostname
-@param port the port of rtmp. default to 1935
-@param app the app of rtmp. default to live.
-@param stream the stream of rtmp. default to livestream.
-*/
-function build_default_rtmp_url() {
- var query = parse_query_string();
-
- var schema = (!query.schema)? "rtmp":query.schema;
- var server = (!query.server)? window.location.hostname:query.server;
- var port = (!query.port)? schema=="http"?80:1935:query.port;
- var vhost = (!query.vhost)? window.location.hostname:query.vhost;
- var app = (!query.app)? "live":query.app;
- var stream = (!query.stream)? "livestream":query.stream;
-
- var queries = [];
- if (server != vhost && vhost != "__defaultVhost__") {
- queries.push("vhost=" + vhost);
- }
- queries = user_extra_params(query, queries);
-
- var uri = schema + "://" + server + ":" + port + "/" + app + "/" + stream + "?" + queries.join('&');
- while (uri.indexOf("?") == uri.length - 1) {
- uri = uri.substr(0, uri.length - 1);
- }
-
- return uri;
-}
-// for the chat to init the publish url.
-function build_default_publish_rtmp_url() {
- var query = parse_query_string();
-
- var schema = (!query.schema)? "rtmp":query.schema;
- var server = (!query.server)? window.location.hostname:query.server;
- var port = (!query.port)? schema=="http"?80:1935:query.port;
- var vhost = (!query.vhost)? window.location.hostname:query.vhost;
- var app = (!query.app)? "live":query.app;
- var stream = (!query.stream)? "demo":query.stream;
-
- var queries = [];
- if (server != vhost && vhost != "__defaultVhost__") {
- queries.push("vhost=" + vhost);
- }
- if (query.shp_identify) {
- queries.push("shp_identify=" + query.shp_identify);
- }
-
- var uri = schema + "://" + server + ":" + port + "/" + app + "/" + stream + "?" + queries.join('&');
- while (uri.indexOf("?") == uri.length - 1) {
- uri = uri.substr(0, uri.length - 1);
- }
-
- return uri;
-}
-// for the bandwidth tool to init page
-function build_default_bandwidth_rtmp_url() {
- var query = parse_query_string();
-
- var server = (!query.server)? window.location.hostname:query.server;
- var port = (!query.port)? 1935:query.port;
- var vhost = "bandcheck.srs.com";
- var app = (!query.app)? "app":query.app;
- var key = (!query.key)? "35c9b402c12a7246868752e2878f7e0e":query.key;
-
- return "rtmp://" + server + ":" + port + "/" + app + "?key=" + key + "&vhost=" + vhost;
-}
-
-/**
-@param server the ip of server. default to window.location.hostname
-@param vhost the vhost of hls. default to window.location.hostname
-@param hls_vhost the vhost of hls. override the server if specified.
-@param hls_port the port of hls. default to window.location.port
-@param app the app of hls. default to live.
-@param stream the stream of hls. default to livestream.
-*/
-function build_default_hls_url() {
- var query = parse_query_string();
-
- // for http, use hls_vhost to override server if specified.
- var server = window.location.hostname;
- if (query.server != undefined) {
- server = query.server;
- } else if (query.hls_vhost != undefined) {
- server = query.hls_vhost;
- }
-
- var port = (!query.hls_port)? window.location.port:query.hls_port;
- var app = (!query.app)? "live":query.app;
- var stream = (!query.stream)? "demo":query.stream;
-
- if (!port) {
- port = 8080;
- }
-
- if (stream.indexOf(".flv") >= 0) {
- return "http://" + server + ":" + port + "/" + app + "/" + stream;
- }
- return "http://" + server + ":" + port + "/" + app + "/" + stream + ".m3u8";
-}
-
-/**
-* initialize the page.
-* @param rtmp_url the div id contains the rtmp stream url to play
-* @param hls_url the div id contains the hls stream url to play
-* @param modal_player the div id contains the modal player
-*/
-function srs_init_rtmp(rtmp_url, modal_player) {
- srs_init(rtmp_url, null, modal_player);
-}
-function srs_init_hls(hls_url, modal_player) {
- srs_init(null, hls_url, modal_player);
-}
-function srs_init(rtmp_url, hls_url, modal_player) {
- update_nav();
-
- if (rtmp_url) {
- $(rtmp_url).val(build_default_rtmp_url());
- }
- if (hls_url) {
- $(hls_url).val(build_default_hls_url());
- }
- if (modal_player) {
- $(modal_player).width(srs_get_player_modal() + "px");
- $(modal_player).css("margin-left", "-" + srs_get_player_modal() / 2 +"px");
- }
-}
-// for the chat to init the publish url.
-function srs_init_publish(rtmp_url) {
- update_nav();
-
- if (rtmp_url) {
- $(rtmp_url).val(build_default_publish_rtmp_url());
- }
-}
-// for bw to init url
-// url: scheme://host:port/path?query#fragment
-function srs_init_bwt(rtmp_url, hls_url) {
- update_nav();
-
- if (rtmp_url) {
- $(rtmp_url).val(build_default_bandwidth_rtmp_url());
- }
-}
-
-// check whether can republish
-function srs_can_republish() {
- var browser = get_browser_agents();
-
- if (browser.Chrome || browser.Firefox) {
- return true;
- }
-
- if (browser.MSIE || browser.QQBrowser) {
- return false;
- }
-
- return false;
-}
-
-// without default values set.
-function srs_initialize_codec_page(
- cameras, microphones,
- sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate,
- sl_acodec
-) {
- $(sl_cameras).empty();
- for (var i = 0; i < cameras.length; i++) {
- $(sl_cameras).append("= 0) {
- $(sl_cameras + " option[value='" + i + "']").attr("selected", true);
- break;
- }
- }
- if (j < matchs.length) {
- break;
- }
- }
-
- $(sl_microphones).empty();
- for (var i = 0; i < microphones.length; i++) {
- $(sl_microphones).append("= 0) {
- $(sl_microphones + " option[value='" + i + "']").attr("selected", true);
- break;
- }
- }
- if (j < matchs.length) {
- break;
- }
- }
-
- $(sl_vcodec).empty();
- var vcodecs = ["h264", "vp6"];
- vcodecs = ["h264"]; // h264 only.
- for (var i = 0; i < vcodecs.length; i++) {
- $(sl_vcodec).append("" + profiles[i] + "" + levels[i] + "" + gops[i] + "秒" + sizes[i] + "" + Number(fpses[i]).toFixed(2) + " 帧/秒" + bitrates[i] + " kbps" + bitrates[i] + "
-
-
- var p = new SrsPlayer("player", 640, 480);
- p.set_srs_player_url("srs_player.swf?v=1.0.0");
- p.on_player_ready = function() {
- p.set_bt(0.8);
- p.set_mbt(1.2);
- p.play("rtmp://ossrs.net/live/livestream");
- };
- p.on_player_metadata = function(metadata) {
- console.log(metadata);
- console.log(p.dump_log());
- };
- p.start();
-*/
-function SrsPlayer(container, width, height, private_object) {
- if (!SrsPlayer.__id) {
- SrsPlayer.__id = 100;
- }
- if (!SrsPlayer.__players) {
- SrsPlayer.__players = [];
- }
-
- SrsPlayer.__players.push(this);
-
- this.private_object = private_object;
- this.container = container;
- this.width = width;
- this.height = height;
- this.id = SrsPlayer.__id++;
- this.stream_url = null;
- this.buffer_time = 0.3; // default to 0.3
- this.max_buffer_time = this.buffer_time * 3; // default to 3 x bufferTime.
- this.volume = 1.0; // default to 100%
- this.callbackObj = null;
- this.srs_player_url = "srs_player/release/srs_player.swf?_version="+srs_get_version_code();
-
- // callback set the following values.
- this.meatadata = {}; // for on_player_metadata
- this.time = 0; // current stream time.
- this.buffer_length = 0; // current stream buffer length.
- this.kbps = 0; // current stream bitrate(video+audio) in kbps.
- this.fps = 0; // current stream video fps.
- this.rtime = 0; // flash relative time in ms.
-
- this.__fluency = {
- total_empty_count: 0,
- total_empty_time: 0,
- current_empty_time: 0
- };
- this.__fluency.on_stream_empty = function(time) {
- this.total_empty_count++;
- this.current_empty_time = time;
- };
- this.__fluency.on_stream_full = function(time) {
- if (this.current_empty_time > 0) {
- this.total_empty_time += time - this.current_empty_time;
- this.current_empty_time = 0;
- }
- };
- this.__fluency.calc = function(time) {
- var den = this.total_empty_count * 4 + this.total_empty_time * 2 + time;
- if (den > 0) {
- return time * 100 / den;
- }
- return 0;
- };
-}
-/**
-* user can set some callback, then start the player.
-* @param url the default url.
-* callbacks:
-* on_player_ready():int, when srs player ready, user can play().
-* on_player_metadata(metadata:Object):int, when srs player get metadata.
-* methods:
-* set_bt(t:Number):void, set the buffer time in seconds.
-* set_mbt(t:Number):void, set the max buffer time in seconds.
-* dump_log():String, get all logs of player.
-*/
-SrsPlayer.prototype.start = function(url) {
- if (url) {
- this.stream_url = url;
- }
-
- // embed the flash.
- var flashvars = {};
- flashvars.id = this.id;
- flashvars.on_player_ready = "__srs_on_player_ready";
- flashvars.on_player_metadata = "__srs_on_player_metadata";
- flashvars.on_player_timer = "__srs_on_player_timer";
- flashvars.on_player_empty = "__srs_on_player_empty";
- flashvars.on_player_full = "__srs_on_player_full";
- flashvars.on_player_status = "__srs_on_player_status";
-
- var params = {};
- params.wmode = "opaque";
- params.allowFullScreen = "true";
- params.allowScriptAccess = "always";
-
- var attributes = {};
-
- var self = this;
-
- swfobject.embedSWF(
- this.srs_player_url,
- this.container,
- this.width, this.height,
- "11.1.0", "js/AdobeFlashPlayerInstall.swf",
- flashvars, params, attributes,
- function(callbackObj){
- self.callbackObj = callbackObj;
- if (!callbackObj.success) {
- console.error('Initialize player failed:'); console.error(callbackObj);
- }
- }
- );
-
- return this;
-}
-/**
-* play the stream.
-* @param stream_url the url of stream, rtmp or http.
-* @param volume the volume, 0 is mute, 1 is 100%, 2 is 200%.
-*/
-SrsPlayer.prototype.play = function(url, volume) {
- this.stop();
- SrsPlayer.__players.push(this);
-
- if (url) {
- this.stream_url = url;
- }
-
- // volume maybe 0, so never use if(volume) to check its value.
- if (volume != null && volume != undefined) {
- this.volume = volume;
- }
-
- this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.max_buffer_time, this.volume);
-}
-/**
- * stop play stream.
- */
-SrsPlayer.prototype.stop = function() {
- this.callbackObj.ref.__stop();
-}
-/**
- * pause the play.
- */
-SrsPlayer.prototype.pause = function() {
- this.callbackObj.ref.__pause();
-}
-/**
- * resume the play.
- */
-SrsPlayer.prototype.resume = function() {
- this.callbackObj.ref.__resume();
-}
-/**
- * get the stream fluency, where 100 is 100%.
- */
-SrsPlayer.prototype.fluency = function() {
- return this.__fluency.calc(this.rtime);
-}
-/**
- * get the stream empty count.
- */
-SrsPlayer.prototype.empty_count = function() {
- return this.__fluency.total_empty_count;
-}
-/**
- * get all log data.
- */
-SrsPlayer.prototype.dump_log = function() {
- return this.callbackObj.ref.__dump_log();
-}
-/**
-* to set the DAR, for example, DAR=16:9 where num=16,den=9.
-* @param num, for example, 16.
-* use metadata width if 0.
-* use user specified width if -1.
-* @param den, for example, 9.
-* use metadata height if 0.
-* use user specified height if -1.
-*/
-SrsPlayer.prototype.set_dar = function(num, den) {
- this.callbackObj.ref.__set_dar(num, den);
-}
-/**
-* set the fullscreen size data.
-* @refer the refer fullscreen mode. it can be:
-* video: use video orignal size.
-* screen: use screen size to rescale video.
-* @param percent, the rescale percent, where
-* 100 means 100%.
-*/
-SrsPlayer.prototype.set_fs = function(refer, percent) {
- this.callbackObj.ref.__set_fs(refer, percent);
-}
-/**
-* set the stream buffer time in seconds.
-* @buffer_time the buffer time in seconds.
-*/
-SrsPlayer.prototype.set_bt = function(buffer_time) {
- if (this.buffer_time == buffer_time) {
- return;
- }
-
- this.buffer_time = buffer_time;
- this.callbackObj.ref.__set_bt(buffer_time);
-
- // reset the max buffer time to 3 x buffer_time.
- this.set_mbt(buffer_time * 3);
-}
-/**
- * set the stream max buffer time in seconds.
- * @param max_buffer_time the max buffer time in seconds.
- * @remark this is the key feature for realtime communication by flash.
- */
-SrsPlayer.prototype.set_mbt = function(max_buffer_time) {
- // we must atleast set the max buffer time to 0.6s.
- max_buffer_time = Math.max(0.6, max_buffer_time);
- // max buffer time always greater than buffer time.
- max_buffer_time = Math.max(this.buffer_time, max_buffer_time);
-
- if (parseInt(this.max_buffer_time * 10) == parseInt(max_buffer_time * 10)) {
- return;
- }
-
- this.max_buffer_time = max_buffer_time;
- this.callbackObj.ref.__set_mbt(max_buffer_time);
-}
-/**
- * set the srs_player.swf url
- * @param url, srs_player.swf's url.
- * @param params, object.
- */
- SrsPlayer.prototype.set_srs_player_url = function(url, params) {
- var query_array = [],
- query_string = "",
- p;
- params = params || {};
- params._version = srs_get_version_code();
- for (p in params) {
- if (params.hasOwnProperty(p)) {
- query_array.push(p + "=" + encodeURIComponent(params[p]));
- }
- }
- query_string = query_array.join("&");
- this.srs_player_url = url + "?" + query_string;
-}
- /**
- * the callback when player is ready.
- */
-SrsPlayer.prototype.on_player_ready = function() {
-}
-/**
- * the callback when player got metadata.
- * @param metadata the metadata which player got.
- */
-SrsPlayer.prototype.on_player_metadata = function(metadata) {
- // ignore.
-}
-/**
- * the callback when player timer event.
- * @param time current stream time.
- * @param buffer_length current buffer length.
- * @param kbps current video plus audio bitrate in kbps.
- * @param fps current video fps.
- * @param rtime current relative time by flash.util.getTimer().
- */
-SrsPlayer.prototype.on_player_timer = function(time, buffer_length, kbps, fps, rtime) {
- // ignore.
-}
-/**
- * the callback when player got NetStream.Buffer.Empty
- * @param time current relative time by flash.util.getTimer().
- */
-SrsPlayer.prototype.on_player_empty = function(time) {
- // ignore.
-}
-/**
- * the callback when player got NetStream.Buffer.Full
- * @param time current relative time by flash.util.getTimer().
- */
-SrsPlayer.prototype.on_player_full = function(time) {
- // ignore.
-}
-/**
- * the callback when player status change.
- * @param code the status code, "init", "connected", "play", "closed", "rejected", "failed".
- * init => connected/rejected/failed
- * connected => play/rejected => closed
- * @param desc the description for the status.
- */
-SrsPlayer.prototype.on_player_status = function(code, desc) {
- // ignore.
-}
-
-/**
- * helpers.
- */
-function __srs_find_player(id) {
- for (var i = 0; i < SrsPlayer.__players.length; i++) {
- var player = SrsPlayer.__players[i];
-
- if (player.id != id) {
- continue;
- }
-
- return player;
- }
-
- throw new Error("player not found. id=" + id);
-}
-function __srs_on_player_ready(id) {
- var player = __srs_find_player(id);
- player.on_player_ready();
-}
-function __srs_on_player_metadata(id, metadata) {
- var player = __srs_find_player(id);
-
- // user may override the on_player_metadata,
- // so set the data before invoke it.
- player.metadata = metadata;
-
- player.on_player_metadata(metadata);
-}
-function __srs_on_player_timer(id, time, buffer_length, kbps, fps, rtime) {
- var player = __srs_find_player(id);
-
- buffer_length = Math.max(0, buffer_length);
- buffer_length = Math.min(player.buffer_time, buffer_length);
-
- time = Math.max(0, time);
-
- // user may override the on_player_timer,
- // so set the data before invoke it.
- player.time = time;
- player.buffer_length = buffer_length;
- player.kbps = kbps;
- player.fps = fps;
- player.rtime = rtime;
-
- player.on_player_timer(time, buffer_length, kbps, fps, rtime);
-}
-function __srs_on_player_empty(id, time) {
- var player = __srs_find_player(id);
- player.__fluency.on_stream_empty(time);
- player.on_player_empty(time);
-}
-function __srs_on_player_full(id, time) {
- var player = __srs_find_player(id);
- player.__fluency.on_stream_full(time);
- player.on_player_full(time);
-}
-function __srs_on_player_status(id, code, desc) {
- var player = __srs_find_player(id);
- player.on_player_status(code, desc);
-
- if (code != "closed") {
- return;
- }
- for (var i = 0; i < SrsPlayer.__players.length; i++) {
- var player = SrsPlayer.__players[i];
-
- if (player.id != this.id) {
- continue;
- }
-
- SrsPlayer.__players.splice(i, 1);
- break;
- }
-}
diff --git a/trunk/research/players/js/srs.publisher.js b/trunk/research/players/js/srs.publisher.js
deleted file mode 100755
index 25f29bfed..000000000
--- a/trunk/research/players/js/srs.publisher.js
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
-* the SrsPublisher object.
-* @param container the html container id.
-* @param width a float value specifies the width of publisher.
-* @param height a float value specifies the height of publisher.
-* @param private_object [optional] an object that used as private object,
-* for example, the logic chat object which owner this publisher.
-*/
-function SrsPublisher(container, width, height, private_object) {
- if (!SrsPublisher.__id) {
- SrsPublisher.__id = 100;
- }
- if (!SrsPublisher.__publishers) {
- SrsPublisher.__publishers = [];
- }
-
- SrsPublisher.__publishers.push(this);
-
- this.private_object = private_object;
- this.container = container;
- this.width = width;
- this.height = height;
- this.id = SrsPublisher.__id++;
- this.callbackObj = null;
-
- // set the values when publish.
- this.url = null;
- this.vcodec = {};
- this.acodec = {};
-
- // callback set the following values.
- this.cameras = [];
- this.microphones = [];
- this.code = 0;
-
- // error code defines.
- this.errors = {
- "100": "无法获取指定的摄像头。", //error_camera_get
- "101": "无法获取指定的麦克风。", //error_microphone_get
- "102": "摄像头为禁用状态,推流时请允许flash访问摄像头。", //error_camera_muted
- "103": "服务器关闭了连接。", //error_connection_closed
- "104": "服务器连接失败。", //error_connection_failed
- "199": "未知错误。"
- };
-}
-/**
-* user can set some callback, then start the publisher.
-* callbacks:
-* on_publisher_ready(cameras, microphones):int, when srs publisher ready, user can publish.
-* on_publisher_error(code, desc):int, when srs publisher error, callback this method.
-* on_publisher_warn(code, desc):int, when srs publisher warn, callback this method.
-*/
-SrsPublisher.prototype.start = function() {
- // embed the flash.
- var flashvars = {};
- flashvars.id = this.id;
- flashvars.width = this.width;
- flashvars.height = this.height;
- flashvars.on_publisher_ready = "__srs_on_publisher_ready";
- flashvars.on_publisher_error = "__srs_on_publisher_error";
- flashvars.on_publisher_warn = "__srs_on_publisher_warn";
-
- var params = {};
- params.wmode = "opaque";
- params.allowFullScreen = "true";
- params.allowScriptAccess = "always";
-
- var attributes = {};
-
- var self = this;
-
- swfobject.embedSWF(
- "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(),
- this.container,
- this.width, this.height,
- "11.1.0", "js/AdobeFlashPlayerInstall.swf",
- flashvars, params, attributes,
- function(callbackObj){
- self.callbackObj = callbackObj;
- }
- );
-
- return this;
-}
-/**
-* publish stream to server.
-* @param url a string indicates the rtmp url to publish.
-* @param vcodec an object contains the video codec info.
-* @param acodec an object contains the audio codec info.
-*/
-SrsPublisher.prototype.publish = function(url, vcodec, acodec) {
- this.stop();
- SrsPublisher.__publishers.push(this);
-
- if (url) {
- this.url = url;
- }
- if (vcodec) {
- this.vcodec = vcodec;
- }
- if (acodec) {
- this.acodec = acodec;
- }
-
- this.callbackObj.ref.__publish(this.url, this.width, this.height, this.vcodec, this.acodec);
-}
-SrsPublisher.prototype.stop = function() {
- for (var i = 0; i < SrsPublisher.__publishers.length; i++) {
- var player = SrsPublisher.__publishers[i];
-
- if (player.id != this.id) {
- continue;
- }
-
- SrsPublisher.__publishers.splice(i, 1);
- break;
- }
-
- this.callbackObj.ref.__stop();
-}
-/**
-* when publisher ready.
-* @param cameras a string array contains the names of cameras.
-* @param microphones a string array contains the names of microphones.
-*/
-SrsPublisher.prototype.on_publisher_ready = function(cameras, microphones) {
-}
-/**
-* when publisher error.
-* @code the error code.
-* @desc the error desc message.
-*/
-SrsPublisher.prototype.on_publisher_error = function(code, desc) {
- throw new Error("publisher error. code=" + code + ", desc=" + desc);
-}
-SrsPublisher.prototype.on_publisher_warn = function(code, desc) {
- throw new Error("publisher warn. code=" + code + ", desc=" + desc);
-}
-function __srs_find_publisher(id) {
- for (var i = 0; i < SrsPublisher.__publishers.length; i++) {
- var publisher = SrsPublisher.__publishers[i];
-
- if (publisher.id != id) {
- continue;
- }
-
- return publisher;
- }
-
- throw new Error("publisher not found. id=" + id);
-}
-function __srs_on_publisher_ready(id, cameras, microphones) {
- var publisher = __srs_find_publisher(id);
-
- publisher.cameras = cameras;
- publisher.microphones = microphones;
-
- publisher.on_publisher_ready(cameras, microphones);
-}
-function __srs_on_publisher_error(id, code) {
- var publisher = __srs_find_publisher(id);
-
- publisher.code = code;
-
- publisher.on_publisher_error(code, publisher.errors[""+code]);
-}
-function __srs_on_publisher_warn(id, code) {
- var publisher = __srs_find_publisher(id);
-
- publisher.code = code;
-
- publisher.on_publisher_warn(code, publisher.errors[""+code]);
-}
diff --git a/trunk/research/players/js/srs.utility.js b/trunk/research/players/js/srs.utility.js
deleted file mode 100755
index 062924ac5..000000000
--- a/trunk/research/players/js/srs.utility.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
-* parse the rtmp url,
-* for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream
-* @return object {server, port, vhost, app, stream}
-*/
-function srs_parse_rtmp_url(rtmp_url) {
- return parse_rtmp_url(rtmp_url);
-}
diff --git a/trunk/research/players/js/swfobject.js b/trunk/research/players/js/swfobject.js
deleted file mode 100644
index 8eafe9dd8..000000000
--- a/trunk/research/players/js/swfobject.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* SWFObject v2.2
- is released under the MIT License
-*/
-var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab= length){
- return String(number);
- }
- return padding(prefix+number, length, prefix);
-}
-
-/**
- * extends system array, to remove all specified elem.
- * @param arr the array to remove elem from.
- * @param elem the elem to remove.
- * @remark all elem will be removed.
- * for example,
- * arr = [10, 15, 20, 30, 20, 40]
- * system_array_remove(arr, 10) // arr=[15, 20, 30, 20, 40]
- * system_array_remove(arr, 20) // arr=[15, 30, 40]
- */
-function system_array_remove(arr, elem) {
- if (!arr) {
- return;
- }
-
- var removed = true;
- var i = 0;
- while (removed) {
- removed = false;
- for (; i < arr.length; i++) {
- if (elem == arr[i]) {
- arr.splice(i, 1);
- removed = true;
- break;
- }
- }
- }
-}
-
-/**
- * whether the array contains specified element.
- * @param arr the array to find.
- * @param elem_or_function the element value or compare function.
- * @returns true contains elem; otherwise false.
- * for example,
- * arr = [10, 15, 20, 30, 20, 40]
- * system_array_contains(arr, 10) // true
- * system_array_contains(arr, 11) // false
- * system_array_contains(arr, function(elem){return elem == 30;}); // true
- * system_array_contains(arr, function(elem){return elem == 60;}); // false
- */
-function system_array_contains(arr, elem_or_function) {
- return system_array_get(arr, elem_or_function) != null;
-}
-
-/**
- * get the specified element from array
- * @param arr the array to find.
- * @param elem_or_function the element value or compare function.
- * @returns the matched elem; otherwise null.
- * for example,
- * arr = [10, 15, 20, 30, 20, 40]
- * system_array_get(arr, 10) // 10
- * system_array_get(arr, 11) // null
- * system_array_get(arr, function(elem){return elem == 30;}); // 30
- * system_array_get(arr, function(elem){return elem == 60;}); // null
- */
-function system_array_get(arr, elem_or_function) {
- for (var i = 0; i < arr.length; i++) {
- if (typeof elem_or_function == "function") {
- if (elem_or_function(arr[i])) {
- return arr[i];
- }
- } else {
- if (elem_or_function == arr[i]) {
- return arr[i];
- }
- }
- }
- return null;
-}
-
-/**
- * to iterate on array.
- * @param arr the array to iterate on.
- * @param pfn the function to apply on it. return false to break loop.
- * for example,
- * arr = [10, 15, 20, 30, 20, 40]
- * system_array_foreach(arr, function(elem, index){
- * console.log('index=' + index + ',elem=' + elem);
- * });
- * @return true when iterate all elems.
- */
-function system_array_foreach(arr, pfn) {
- if (!pfn) {
- return false;
- }
-
- for (var i = 0; i < arr.length; i++) {
- if (!pfn(arr[i], i)) {
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * whether the str starts with flag.
- */
-function system_string_startswith(str, flag) {
- if (typeof flag == "object" && flag.constructor == Array) {
- for (var i = 0; i < flag.length; i++) {
- if (system_string_startswith(str, flag[i])) {
- return true;
- }
- }
- }
-
- return str && flag && str.length >= flag.length && str.indexOf(flag) == 0;
-}
-
-/**
- * whether the str ends with flag.
- */
-function system_string_endswith(str, flag) {
- if (typeof flag == "object" && flag.constructor == Array) {
- for (var i = 0; i < flag.length; i++) {
- if (system_string_endswith(str, flag[i])) {
- return true;
- }
- }
- }
-
- return str && flag && str.length >= flag.length && str.indexOf(flag) == str.length - flag.length;
-}
-
-/**
- * trim the start and end of flag in str.
- * @param flag a string to trim.
- */
-function system_string_trim(str, flag) {
- if (!flag || !flag.length || typeof flag != "string") {
- return str;
- }
-
- while (system_string_startswith(str, flag)) {
- str = str.substr(flag.length);
- }
-
- while (system_string_endswith(str, flag)) {
- str = str.substr(0, str.length - flag.length);
- }
-
- return str;
-}
-
-/**
- * array sort asc, for example:
- * [a, b] in [10, 11, 9]
- * then sort to: [9, 10, 11]
- * Usage, for example:
- obj.data.data.sort(function(a, b){
- return array_sort_asc(a.metadata.meta_id, b.metadata.meta_id);
- });
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * @remark, if need desc, use -1*array_sort_asc(a,b)
- */
-function array_sort_asc(elem_a, elem_b) {
- if (elem_a > elem_b) {
- return 1;
- }
- return (elem_a < elem_b)? -1 : 0;
-}
-function array_sort_desc(elem_a, elem_b) {
- return -1 * array_sort_asc(elem_a, elem_b);
-}
-function system_array_sort_asc(elem_a, elem_b) {
- return array_sort_asc(elem_a, elem_b);
-}
-function system_array_sort_desc(elem_a, elem_b) {
- return -1 * array_sort_asc(elem_a, elem_b);
-}
-
-/**
- * parse the query string to object.
- * parse the url location object as: host(hostname:http_port), pathname(dir/filename)
- * for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream
- * parsed to object:
- {
- host : "192.168.1.168:1980",
- hostname : "192.168.1.168",
- http_port : 1980,
- pathname : "/ui/players.html",
- dir : "/ui",
- filename : "/players.html",
-
- vhost : "player.vhost.com",
- app : "test",
- stream : "livestream"
- }
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- */
-function parse_query_string(){
- var obj = {};
-
- // add the uri object.
- // parse the host(hostname:http_port), pathname(dir/filename)
- obj.host = window.location.host;
- obj.hostname = window.location.hostname;
- obj.http_port = (window.location.port == "")? 80:window.location.port;
- obj.pathname = window.location.pathname;
- if (obj.pathname.lastIndexOf("/") <= 0) {
- obj.dir = "/";
- obj.filename = "";
- } else {
- obj.dir = obj.pathname.substr(0, obj.pathname.lastIndexOf("/"));
- obj.filename = obj.pathname.substr(obj.pathname.lastIndexOf("/"));
- }
-
- // pure user query object.
- obj.user_query = {};
-
- // parse the query string.
- var query_string = String(window.location.search).replace(" ", "").split("?")[1];
- if(query_string == undefined){
- query_string = String(window.location.hash).replace(" ", "").split("#")[1];
- if(query_string == undefined){
- return obj;
- }
- }
-
- __fill_query(query_string, obj);
-
- return obj;
-}
-
-function __fill_query(query_string, obj) {
- // pure user query object.
- obj.user_query = {};
-
- if (query_string.length == 0) {
- return;
- }
-
- // split again for angularjs.
- if (query_string.indexOf("?") >= 0) {
- query_string = query_string.split("?")[1];
- }
-
- var queries = query_string.split("&");
- for (var i = 0; i < queries.length; i++) {
- var elem = queries[i];
-
- var query = elem.split("=");
- obj[query[0]] = query[1];
- obj.user_query[query[0]] = query[1];
- }
-
- // alias domain for vhost.
- if (obj.domain) {
- obj.vhost = obj.domain;
- }
-}
-
-/**
- * parse the rtmp url,
- * for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream
- * @return object {server, port, vhost, app, stream}
- * for exmaple, rtmp_url is rtmp://demo.srs.com:1935/live...vhost...players/livestream
- * parsed to object:
- {
- server: "demo.srs.com",
- port: 1935,
- vhost: "players",
- app: "live",
- stream: "livestream"
- }
- */
-function parse_rtmp_url(rtmp_url) {
- // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri
- var a = document.createElement("a");
- a.href = rtmp_url.replace("rtmp://", "http://");
-
- var vhost = a.hostname;
- var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1);
- var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1);
-
- // parse the vhost in the params of app, that srs supports.
- app = app.replace("...vhost...", "?vhost=");
- if (app.indexOf("?") >= 0) {
- var params = app.substr(app.indexOf("?"));
- app = app.substr(0, app.indexOf("?"));
-
- if (params.indexOf("vhost=") > 0) {
- vhost = params.substr(params.indexOf("vhost=") + "vhost=".length);
- if (vhost.indexOf("&") > 0) {
- vhost = vhost.substr(0, vhost.indexOf("&"));
- }
- }
- }
-
- // when vhost equals to server, and server is ip,
- // the vhost is __defaultVhost__
- if (a.hostname == vhost) {
- var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
- if (re.test(a.hostname)) {
- vhost = "__defaultVhost__";
- }
- }
-
- // parse the schema
- var schema = "rtmp";
- if (rtmp_url.indexOf("://") > 0) {
- schema = rtmp_url.substr(0, rtmp_url.indexOf("://"));
- }
- var port = (a.port == "")? (schema=="http"?"80":"1935"):a.port;
-
- var ret = {
- url: rtmp_url,
- schema: schema,
- server: a.hostname, port: port,
- vhost: vhost, app: app, stream: stream
- };
- __fill_query(a.search, ret);
-
- return ret;
-}
-
-/**
- * get the agent.
- * @return an object specifies some browser.
- * for example, get_browser_agents().MSIE
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- */
-function get_browser_agents() {
- var agent = navigator.userAgent;
-
- /**
- WindowsPC platform, Win7:
- chrome 31.0.1650.63:
- Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
- (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
- firefox 23.0.1:
- Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101
- Firefox/23.0
- safari 5.1.7(7534.57.2):
- Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2
- (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
- opera 15.0.1147.153:
- Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
- (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
- OPR/15.0.1147.153
- 360 6.2.1.272:
- Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
- Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
- .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
- .NET4.0E)
- IE 10.0.9200.16750(update: 10.0.12):
- Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
- Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
- .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
- .NET4.0E)
- */
-
- return {
- // platform
- Android: agent.indexOf("Android") != -1,
- Windows: agent.indexOf("Windows") != -1,
- iPhone: agent.indexOf("iPhone") != -1,
- // Windows Browsers
- Chrome: agent.indexOf("Chrome") != -1,
- Firefox: agent.indexOf("Firefox") != -1,
- QQBrowser: agent.indexOf("QQBrowser") != -1,
- MSIE: agent.indexOf("MSIE") != -1,
- // Android Browsers
- Opera: agent.indexOf("Presto") != -1,
- MQQBrowser: agent.indexOf("MQQBrowser") != -1
- };
-}
-
-/**
- * format relative seconds to HH:MM:SS,
- * for example, 210s formated to 00:03:30
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * @usage relative_seconds_to_HHMMSS(210)
- */
-function relative_seconds_to_HHMMSS(seconds){
- var date = new Date();
- date.setTime(Number(seconds) * 1000);
-
- var ret = padding(date.getUTCHours(), 2, '0')
- + ":" + padding(date.getUTCMinutes(), 2, '0')
- + ":" + padding(date.getUTCSeconds(), 2, '0');
-
- return ret;
-}
-
-/**
- * format absolute seconds to HH:MM:SS,
- * for example, 1389146480s (2014-01-08 10:01:20 GMT+0800) formated to 10:01:20
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * @usage absolute_seconds_to_HHMMSS(new Date().getTime() / 1000)
- */
-function absolute_seconds_to_HHMMSS(seconds){
- var date = new Date();
- date.setTime(Number(seconds) * 1000);
-
- var ret = padding(date.getHours(), 2, '0')
- + ":" + padding(date.getMinutes(), 2, '0')
- + ":" + padding(date.getSeconds(), 2, '0');
-
- return ret;
-}
-
-/**
- * format absolute seconds to YYYY-mm-dd,
- * for example, 1389146480s (2014-01-08 10:01:20 GMT+0800) formated to 2014-01-08
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * @usage absolute_seconds_to_YYYYmmdd(new Date().getTime() / 1000)
- */
-function absolute_seconds_to_YYYYmmdd(seconds) {
- var date = new Date();
- date.setTime(Number(seconds) * 1000);
-
- var ret = date.getFullYear()
- + "-" + padding(date.getMonth() + 1, 2, '0')
- + "-" + padding(date.getDate(), 2, '0');
-
- return ret;
-}
-
-/**
- * parse the date in str to Date object.
- * @param str the date in str, format as "YYYY-mm-dd", for example, 2014-12-11
- * @returns a date object.
- * @usage YYYYmmdd_parse("2014-12-11")
- */
-function YYYYmmdd_parse(str) {
- var date = new Date();
- date.setTime(Date.parse(str));
- return date;
-}
-
-/**
- * async refresh function call. to avoid multiple call.
- * @remark AsyncRefresh is for jquery to refresh the speicified pfn in a page;
- * if angularjs, use AsyncRefresh2 to change pfn, cancel previous request for angularjs use singleton object.
- * @param refresh_interval the default refresh interval ms.
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * the pfn can be implements as following:
- var async_refresh = new AsyncRefresh(pfn, 3000);
- function pfn() {
- if (!async_refresh.refresh_is_enabled()) {
- async_refresh.request(100);
- return;
- }
- $.ajax({
- type: 'GET', async: true, url: 'xxxxx',
- complete: function(){
- if (!async_refresh.refresh_is_enabled()) {
- async_refresh.request(0);
- } else {
- async_refresh.request(async_refresh.refresh_interval);
- }
- },
- success: function(res){
- // if donot allow refresh, directly return.
- if (!async_refresh.refresh_is_enabled()) {
- return;
- }
-
- // render the res.
- }
- });
- }
- */
-function AsyncRefresh(pfn, refresh_interval) {
- this.refresh_interval = refresh_interval;
-
- this.__handler = null;
- this.__pfn = pfn;
-
- this.__enabled = true;
-}
-/**
- * disable the refresher, the pfn must check the refresh state.
- */
-AsyncRefresh.prototype.refresh_disable = function() {
- this.__enabled = false;
-}
-AsyncRefresh.prototype.refresh_enable = function() {
- this.__enabled = true;
-}
-AsyncRefresh.prototype.refresh_is_enabled = function() {
- return this.__enabled;
-}
-/**
- * start new async request
- * @param timeout the timeout in ms.
- * user can use the refresh_interval of the AsyncRefresh object,
- * which initialized in constructor.
- */
-AsyncRefresh.prototype.request = function(timeout) {
- if (this.__handler) {
- clearTimeout(this.__handler);
- }
-
- this.__handler = setTimeout(this.__pfn, timeout);
-}
-
-/**
- * async refresh v2, support cancellable refresh, and change the refresh pfn.
- * @remakr for angularjs. if user only need jquery, maybe AsyncRefresh is better.
- * @see: http://blog.csdn.net/win_lin/article/details/17994347
- * Usage:
- bsmControllers.controller('CServers', ['$scope', 'MServer', function($scope, MServer){
- async_refresh2.refresh_change(function(){
- // 获取服务器列表
- MServer.servers_load({}, function(data){
- $scope.servers = data.data.servers;
- async_refresh2.request();
- });
- }, 3000);
-
- async_refresh2.request(0);
- }]);
- bsmControllers.controller('CStreams', ['$scope', 'MStream', function($scope, MStream){
- async_refresh2.refresh_change(function(){
- // 获取流列表
- MStream.streams_load({}, function(data){
- $scope.streams = data.data.streams;
- async_refresh2.request();
- });
- }, 3000);
-
- async_refresh2.request(0);
- }]);
- */
-function AsyncRefresh2() {
- /**
- * the function callback before call the pfn.
- * the protype is function():bool, which return true to invoke, false to abort the call.
- * null to ignore this callback.
- *
- * for example, user can abort the refresh by find the class popover:
- * async_refresh2.on_before_call_pfn = function() {
- * if ($(".popover").length > 0) {
- * async_refresh2.request();
- * return false;
- * }
- * return true;
- * };
- */
- this.on_before_call_pfn = null;
-
- // use a anonymous function to call, and check the enabled when actually invoke.
- this.__call = {
- pfn: null,
- timeout: 0,
- __enabled: false,
- __handler: null
- };
-}
-// singleton
-var async_refresh2 = new AsyncRefresh2();
-/**
- * initialize or refresh change. cancel previous request, setup new request.
- * @param pfn a function():void to request after timeout. null to disable refresher.
- * @param timeout the timeout in ms, to call pfn. null to disable refresher.
- */
-AsyncRefresh2.prototype.initialize = function(pfn, timeout) {
- this.refresh_change(pfn, timeout);
-}
-/**
- * stop refresh, the refresh pfn is set to null.
- */
-AsyncRefresh2.prototype.stop = function() {
- this.__call.__enabled = false;
-}
-/**
- * restart refresh, use previous config.
- */
-AsyncRefresh2.prototype.restart = function() {
- this.__call.__enabled = true;
- this.request(0);
-}
-/**
- * change refresh pfn, the old pfn will set to disabled.
- */
-AsyncRefresh2.prototype.refresh_change = function(pfn, timeout) {
- // cancel the previous call.
- if (this.__call.__handler) {
- clearTimeout(this.__handler);
- }
- this.__call.__enabled = false;
-
- // setup new call.
- this.__call = {
- pfn: pfn,
- timeout: timeout,
- __enabled: true,
- __handler: null
- };
-}
-/**
- * start new request, we never auto start the request,
- * user must start new request when previous completed.
- * @param timeout [optional] if not specified, use the timeout in initialize or refresh_change.
- */
-AsyncRefresh2.prototype.request = function(timeout) {
- var self = this;
- var this_call = this.__call;
-
- // clear previous timeout.
- if (this_call.__handler) {
- clearTimeout(this_call.__handler);
- }
-
- // override the timeout
- if (timeout == undefined) {
- timeout = this_call.timeout;
- }
-
- // if user disabled refresher.
- if (this_call.pfn == null || timeout == null) {
- return;
- }
-
- this_call.__handler = setTimeout(function(){
- // cancelled by refresh_change, ignore.
- if (!this_call.__enabled) {
- return;
- }
-
- // callback if the handler installled.
- if (self.on_before_call_pfn) {
- if (!self.on_before_call_pfn()) {
- return;
- }
- }
-
- // do the actual call.
- this_call.pfn();
- }, timeout);
-}
-
-// other components.
-/**
- * jquery/bootstrap pager.
- * depends: jquery1.10, boostrap2
- * https://code.csdn.net/snippets/146160
- * @see: http://blog.csdn.net/win_lin/article/details/17628631
- */
\ No newline at end of file
diff --git a/trunk/research/players/jwplayer6.html b/trunk/research/players/jwplayer6.html
deleted file mode 100644
index f6a2da33a..000000000
--- a/trunk/research/players/jwplayer6.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
- SRS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/trunk/research/players/srs_player/.actionScriptProperties b/trunk/research/players/srs_player/.actionScriptProperties
deleted file mode 100755
index 1908de474..000000000
--- a/trunk/research/players/srs_player/.actionScriptProperties
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/trunk/research/players/srs_player/.project b/trunk/research/players/srs_player/.project
deleted file mode 100755
index 87ed06163..000000000
--- a/trunk/research/players/srs_player/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- srs_player
-
-
-
-
-
- com.adobe.flexbuilder.project.flexbuilder
-
-
-
-
-
- com.adobe.flexbuilder.project.actionscriptnature
-
-
diff --git a/trunk/research/players/srs_player/.settings/org.eclipse.core.resources.prefs b/trunk/research/players/srs_player/.settings/org.eclipse.core.resources.prefs
deleted file mode 100755
index fc698988d..000000000
--- a/trunk/research/players/srs_player/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Wed Dec 18 10:07:19 CST 2013
-eclipse.preferences.version=1
-encoding/=utf-8
diff --git a/trunk/research/players/srs_player/release/srs_player.swf b/trunk/research/players/srs_player/release/srs_player.swf
deleted file mode 100644
index 3294a43a4..000000000
Binary files a/trunk/research/players/srs_player/release/srs_player.swf and /dev/null differ
diff --git a/trunk/research/players/srs_player/src/HlsNetStream.as b/trunk/research/players/srs_player/src/HlsNetStream.as
deleted file mode 100755
index 553741bb1..000000000
--- a/trunk/research/players/srs_player/src/HlsNetStream.as
+++ /dev/null
@@ -1,5374 +0,0 @@
-package
-{
- import flash.events.Event;
- import flash.events.IOErrorEvent;
- import flash.events.NetStatusEvent;
- import flash.events.ProgressEvent;
- import flash.events.SecurityErrorEvent;
- import flash.external.ExternalInterface;
- import flash.net.NetConnection;
- import flash.net.NetStream;
- import flash.net.NetStreamAppendBytesAction;
- import flash.net.URLLoader;
- import flash.net.URLLoaderDataFormat;
- import flash.net.URLRequest;
- import flash.net.URLRequestHeader;
- import flash.net.URLRequestMethod;
- import flash.net.URLStream;
- import flash.net.URLVariables;
- import flash.utils.ByteArray;
- import flash.utils.setTimeout;
-
- // the NetStream to play hls or hls+.
- public class HlsNetStream extends NetStream
- {
- private var hls:HlsCodec = null; // parse m3u8 and ts
-
- // for hls codec.
- public var m3u8_refresh_ratio:Number;
- public var ts_parse_async_interval:Number;
-
- // play param url.
- private var user_url:String = null;
-
- private var conn:NetConnection = null;
-
- /**
- * create stream to play hls.
- * @param m3u8_refresh_ratio, for example, 0.5, fetch m3u8 every 0.5*ts_duration.
- * @param ts_parse_async_interval, for example, 80ms to parse ts async.
- */
- public function HlsNetStream(m3u8_refresh_ratio:Number, ts_parse_async_interval:Number, conn:NetConnection)
- {
- super(conn);
-
- this.m3u8_refresh_ratio = m3u8_refresh_ratio;
- this.ts_parse_async_interval = ts_parse_async_interval;
- hls = new HlsCodec(this);
- this.conn = conn;
- }
-
- /**
- * to play the hls stream.
- * for example, HlsNetStream.play("http://ossrs.net:8080/live/livestream.m3u8").
- * user can set the metadata callback by:
- * var ns:NetStream = new HlsNetStream(...);
- * ns.client = {};
- * ns.client.onMetaData = system_on_metadata;
- */
- public override function play(... params):void
- {
- super.play(null);
- user_url = params[0] as String;
- refresh_m3u8();
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////Private Section//////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-
- private var parsed_ts_seq_no:Number = -1;
- private function refresh_m3u8():void {
- download(user_url, function(stream:ByteArray):void {
- var m3u8:String = stream.toString();
- hls.parse(user_url, m3u8);
-
- // redirect by variant m3u8.
- if (hls.variant) {
- var smu:String = hls.getTsUrl(0);
- log("variant hls=" + user_url + ", redirect2=" + smu);
- user_url = smu;
- setTimeout(refresh_m3u8, 0);
- return;
- }
-
- // fetch from the last one.
- if (parsed_ts_seq_no == -1) {
- parsed_ts_seq_no = hls.seq_no + hls.tsCount - 1;
- }
-
- // not changed.
- if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) {
- refresh_ts();
- return;
- }
-
- // parse each ts.
- var nb_ts:Number = hls.seq_no + hls.tsCount - parsed_ts_seq_no;
- log("m3u8 changed, got " + nb_ts + " new ts, count=" + hls.tsCount + ", seqno=" + hls.seq_no + ", parsed=" + parsed_ts_seq_no);
-
- refresh_ts();
- })
- }
-
- private var metadata:Object = null;
- private function refresh_ts():void {
- // all ts parsed.
- if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) {
- var to:Number = 1000;
- if (hls.tsCount > 0) {
- to = hls.duration * 1000 / hls.tsCount * m3u8_refresh_ratio;
- }
- setTimeout(refresh_m3u8, to);
- log("m3u8 not changed, retry after " + to.toFixed(2) + "ms, duration="
- + hls.duration.toFixed(2) + "s, count=" + hls.tsCount.toFixed(0)
- + ", refresh-ratio=" + m3u8_refresh_ratio.toFixed(2));
- return;
- }
-
- // parse current ts.
- var uri:String = hls.getTsUrl(parsed_ts_seq_no - hls.seq_no);
-
- // parse metadata from uri.
- if (uri.indexOf("?") >= 0) {
- var uv:URLVariables = new URLVariables(uri.substr(uri.indexOf("?") + 1));
- var obj:Object = {};
- for (var k:String in uv) {
- var v:String = uv[k];
- if (k == "shp_sip1") {
- obj.srs_server_ip = v;
- } else if (k == "shp_cid") {
- obj.srs_id = v;
- } else if (k == "shp_pid") {
- obj.srs_pid = v;
- }
- //log("uv[" + k + "]=" + v);
- }
-
- // ignore when not changed.
- if (!metadata || metadata.srs_server_ip != obj.srs_server_ip || metadata.srs_id != obj.srs_id || metadata.srs_pid != obj.srs_pid) {
- if (client && client.hasOwnProperty("onMetaData")) {
- log("got metadata for url " + uri);
- client.onMetaData(obj);
- }
- }
- metadata = obj;
- }
-
- download(uri, function(stream:ByteArray):void{
- log("got ts seqno=" + parsed_ts_seq_no + ", " + stream.length + " bytes");
-
- var flv:FlvPiece = new FlvPiece(parsed_ts_seq_no);
- var body:ByteArray = new ByteArray();
- stream.position = 0;
- hls.parseBodyAsync(flv, stream, body, function():void{
- body.position = 0;
- //log("ts parsed, seqno=" + parsed_ts_seq_no + ", flv=" + body.length + "B");
- onFlvBody(uri, body);
-
- parsed_ts_seq_no++;
- setTimeout(refresh_ts, 0);
- });
- });
- }
- private function download(uri:String, completed:Function):void {
- // http get.
- var url:URLStream = new URLStream();
- var stream:ByteArray = new ByteArray();
-
- url.addEventListener(ProgressEvent.PROGRESS, function(evt:ProgressEvent):void {
- if (url.bytesAvailable <= 0) {
- return;
- }
-
- //log(uri + " total=" + evt.bytesTotal + ", loaded=" + evt.bytesLoaded + ", available=" + url.bytesAvailable);
- var bytes:ByteArray = new ByteArray();
- url.readBytes(bytes, 0, url.bytesAvailable);
- stream.writeBytes(bytes);
- });
-
- url.addEventListener(Event.COMPLETE, function(evt:Event):void {
- log(uri + " completed, total=" + stream.length + "bytes");
- if (url.bytesAvailable <= 0) {
- completed(stream);
- return;
- }
-
- //log(uri + " completed" + ", available=" + url.bytesAvailable);
- var bytes:ByteArray = new ByteArray();
- url.readBytes(bytes, 0, url.bytesAvailable);
- stream.writeBytes(bytes);
-
- completed(stream);
- });
-
- url.addEventListener(IOErrorEvent.IO_ERROR, function(evt:IOErrorEvent):void{
- onPlayFailed(evt);
- });
-
- url.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(evt:SecurityErrorEvent):void{
- onPlayRejected(evt);
- });
-
- // we set to the query.
- uri += ((uri.indexOf("?") == -1)? "?":"&") + "shp_xpsid=" + XPlaybackSessionId;
- var r:URLRequest = new URLRequest(uri);
- // seems flash not allow set this header.
- // @remark disable it for it will cause security exception.
- //r.requestHeaders.push(new URLRequestHeader("X-Playback-Session-Id", XPlaybackSessionId));
-
- log("start download " + uri);
- url.load(r);
- }
-
- // the uuid similar to Safari, to identify this play session.
- // @see https://github.com/winlinvip/srs-plus/blob/bms/trunk/src/app/srs_app_http_stream.cpp#L45
- public var XPlaybackSessionId:String = createRandomIdentifier(32);
-
- private function createRandomIdentifier(length:uint, radix:uint = 61):String {
- var characters:Array = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
- 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
- 'z');
- var id:Array = new Array();
- radix = (radix > 61) ? 61 : radix;
- while (length--) {
- id.push(characters[randomIntegerWithinRange(0, radix)]);
- }
- return id.join('');
- }
-
- private function randomIntegerWithinRange(min:int, max:int):int {
- return Math.floor(Math.random() * (1 + max - min) + min);
- }
-
- // callback for hls.
- public var flvHeader:ByteArray = null;
- public function onSequenceHeader():void {
- var s:NetStream = super;
- s.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
- s.appendBytes(flvHeader);
- log("FLV: sps/pps " + flvHeader.length + " bytes");
-
- writeFlv(flvHeader);
- onPlayStart();
- }
-
- private function onPlayStart():void {
- log("dispatch NetStream.Play.Start.");
- dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
- code: "NetStream.Play.Start",
- stream: user_url,
- descrption: "play start"
- }));
- }
-
- private function onPlayFailed(evt:IOErrorEvent):void {
- log("dispatch NetConnection.Connect.Failed.");
- this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
- code: "NetConnection.Connect.Failed",
- stream: user_url,
- descrption: evt.text
- }));
- }
-
- private function onPlayRejected(evt:SecurityErrorEvent):void {
- log("dispatch NetConnection.Connect.Rejected.");
- this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
- code: "NetConnection.Connect.Rejected",
- stream: user_url,
- descrption: evt.text
- }));
- }
-
- private function onFlvBody(uri:String, flv:ByteArray):void {
- if (!flvHeader) {
- return;
- }
-
- var s:NetStream = super;
- s.appendBytes(flv);
- log("FLV: ts " + uri + " parsed to flv " + flv.length + " bytes");
-
- writeFlv(flv);
- }
-
- private function writeFlv(data:ByteArray):void {
- return;
-
- var r:URLRequest = new URLRequest("http://192.168.1.117:8088/api/v1/flv");
- r.method = URLRequestMethod.POST;
- r.data = data;
-
- var pf:URLLoader = new URLLoader();
- pf.dataFormat = URLLoaderDataFormat.BINARY;
- pf.load(r);
- }
-
- private function log(msg:String):void {
- msg = "[" + new Date() +"][srs-player] " + msg;
-
- trace(msg);
-
- if (!flash.external.ExternalInterface.available) {
- return;
- }
-
- ExternalInterface.call("console.log", msg);
- }
- }
-}
-
-import flash.events.Event;
-import flash.net.URLLoader;
-import flash.net.URLRequest;
-import flash.net.URLRequestMethod;
-import flash.utils.ByteArray;
-
-/**
- * the hls main class.
- */
-class HlsCodec
-{
- private var m3u8:M3u8;
-
- private var avc:SrsRawH264Stream;
- private var h264_sps:ByteArray;
- private var h264_pps:ByteArray;
-
- private var aac:SrsRawAacStream;
- private var aac_specific_config:ByteArray;
- private var width:int;
- private var height:int;
-
- private var video_sh_tag:ByteArray;
- private var audio_sh_tag:ByteArray;
-
- private var owner:HlsNetStream;
- private var _log:ILogger = new TraceLogger("HLS");
-
- public static const SRS_TS_PACKET_SIZE:int = 188;
-
- public function HlsCodec(o:HlsNetStream)
- {
- owner = o;
- m3u8 = new M3u8(this);
-
- reset();
- }
-
- /**
- * parse the m3u8.
- * @param url, the m3u8 url, for m3u8 to generate the ts url.
- * @param v, the m3u8 string.
- */
- public function parse(url:String, v:String):void
- {
- // TODO: FIXME: reset the hls when parse.
- m3u8.parse(url, v);
- }
-
- /**
- * get the total count of ts in m3u8.
- */
- public function get tsCount():Number
- {
- return m3u8.tsCount;
- }
-
- /**
- * get the total duration in seconds of m3u8.
- */
- public function get duration():Number
- {
- return m3u8.duration;
- }
-
- /**
- * get the sequence number, the id of first ts.
- */
- public function get seq_no():Number
- {
- return m3u8.seq_no;
- }
-
- /**
- * whether the m3u8 contains variant m3u8.
- */
- public function get variant():Boolean
- {
- return m3u8.variant;
- }
-
- /**
- * dumps the metadata, for example, set the width and height,
- * which is decoded from sps.
- */
- public function dumpMetaData(metadata:Object):void
- {
- if (width > 0) {
- metadata.width = width;
- }
- if (height > 0) {
- metadata.height = height;
- }
- }
-
- /**
- * get the ts url by piece id, which is actually the piece index.
- */
- public function getTsUrl(pieceId:Number):String
- {
- return m3u8.getTsUrl(pieceId);
- }
-
- /**
- * reset the HLS when parse m3u8.
- */
- public function reset():void
- {
- avc = new SrsRawH264Stream();
- h264_sps = new ByteArray();
- h264_pps = new ByteArray();
-
- aac = new SrsRawAacStream();
- aac_specific_config = new ByteArray();
-
- width = 0;
- height = 0;
-
- video_sh_tag = new ByteArray();
- audio_sh_tag = new ByteArray();
- }
-
- /**
- * parse the piece in hls format,
- * set the piece.skip if error.
- * @param onParsed, a function(piece:FlvPiece, body:ByteArray):void callback.
- */
- public function parseBodyAsync(piece:FlvPiece, data:ByteArray, body:ByteArray, onParsed:Function):void
- {
- var handler:SrsTsHanlder = new SrsTsHanlder(
- avc, aac,
- h264_sps, h264_pps,
- aac_specific_config,
- video_sh_tag, audio_sh_tag,
- this, body,
- _on_size_changed, _on_sequence_changed
- );
-
- // the context used to parse the whole ts file.
- var context:SrsTsContext = new SrsTsContext(this);
-
- // we assumpt to parse the piece in 10 times.
- // the total parse time is 10*AlgP2P.HlsAsyncParseTimeout
- var ts_packets:uint = data.length / SRS_TS_PACKET_SIZE;
- var each_parse:uint = ts_packets / 10;
- var nb_parsed:uint = 0;
- var aysncParse:Function = function():void {
- try {
- // do the parse.
- doParseBody(piece, data, body, handler, context, each_parse);
-
- // check whether parsed.
- nb_parsed += each_parse;
-
- if (nb_parsed < ts_packets) {
- flash.utils.setTimeout(aysncParse, owner.ts_parse_async_interval);
- return;
- }
-
- // flush the messages in queue.
- handler.flush_message_queue(body);
-
- __report(body);
- _log.info("hls async parsed to flv, piece={0}, hls={1}B, flv={2}B", piece.pieceId, data.length, body.length);
- } catch (e:Error) {
- piece.skip = true;
- _log.error("hls async parse piece={0}, exception={1}, stack={2}",
- piece.pieceId, e.message, e.getStackTrace());
- }
-
- onParsed(piece, body);
- };
-
- aysncParse();
- }
-
- /**
- * parse the piece in hls format,
- * set the piece.skip if error.
- */
- public function parseBody(piece:FlvPiece, data:ByteArray, body:ByteArray):void
- {
- try {
- var handler:SrsTsHanlder = new SrsTsHanlder(
- avc, aac,
- h264_sps, h264_pps,
- aac_specific_config,
- video_sh_tag, audio_sh_tag,
- this, body,
- _on_size_changed, _on_sequence_changed
- );
-
- // the context used to parse the whole ts file.
- var context:SrsTsContext = new SrsTsContext(this);
-
- // do the parse.
- doParseBody(piece, data, body, handler, context, -1);
-
- // flush the messages in queue.
- handler.flush_message_queue(body);
-
- __report(body);
- _log.info("hls sync parsed to flv, piece={0}, hls={1}B, flv={2}B", piece.pieceId, data.length, body.length);
- } catch (e:Error) {
- piece.skip = true;
- _log.error("hls sync parse piece={0}, exception={1}, stack={2}",
- piece.pieceId, e.message, e.getStackTrace());
- }
- }
-
- private function _on_size_changed(w:int, h:int):void
- {
- width = w;
- height = h;
- }
-
- private function _on_sequence_changed(
- pavc:SrsRawH264Stream, paac:SrsRawAacStream,
- ph264_sps:ByteArray, ph264_pps:ByteArray,
- paac_specific_config:ByteArray,
- pvideo_sh_tag:ByteArray, paudio_sh_tag:ByteArray,
- sh:ByteArray):void
- {
- // when sequence header not changed, ignore.
- if (SrsUtils.array_equals(h264_sps, ph264_sps)) {
- if (SrsUtils.array_equals(h264_pps, ph264_pps)) {
- if (SrsUtils.array_equals(aac_specific_config, paac_specific_config)) {
- return;
- }
- }
- }
-
- avc = pavc;
- h264_sps = ph264_sps;
- h264_pps = ph264_pps;
-
- aac = paac;
- aac_specific_config = paac_specific_config;
-
- video_sh_tag = pvideo_sh_tag;
- audio_sh_tag = paudio_sh_tag;
-
- _log.info("hls: got sequence header, ash={0}B, bsh={1}B", audio_sh_tag.length, video_sh_tag.length);
- owner.flvHeader = sh;
- owner.onSequenceHeader();
-
- __report(sh);
- }
-
- /**
- * do the parse.
- * @maxTsPackets the max ts packets to parse, stop when exceed this ts packet.
- * -1 to parse all packets.
- */
- private function doParseBody(
- piece:FlvPiece, data:ByteArray, body:ByteArray,
- handler:SrsTsHanlder, context:SrsTsContext, maxTsPackets:int):void
- {
- for (var i:int = 0; (maxTsPackets == -1 || i < maxTsPackets) && data.bytesAvailable > 0; i++) {
- var tsBytes:ByteArray = new ByteArray();
- data.readBytes(tsBytes, 0, HlsCodec.SRS_TS_PACKET_SIZE);
- context.decode(tsBytes, handler);
- }
- }
-
- private function __report(flv:ByteArray):void
- {
- // report only for debug.
- return;
-
- var url:URLRequest = new URLRequest("http://192.168.10.108:1980/api/v3/file");
- url.data = flv;
- url.method = URLRequestMethod.POST;
-
- var loader:URLLoader = new URLLoader();
- loader.addEventListener(Event.COMPLETE, function(e:Event):void {
- loader.close();
- });
- loader.load(url);
- }
-}
-
-import flash.utils.Dictionary;
-
-class Dict
-{
- private var _dict:Dictionary;
- private var _size:uint;
-
- public function Dict()
- {
- clear();
- }
-
- /**
- * get the underlayer dict.
- * @remark for core-ng.
- */
- public function get dict():Dictionary
- {
- return _dict;
- }
-
- public function has(key:Object):Boolean
- {
- return (key in _dict);
- }
-
- public function get(key:Object):Object
- {
- return ((key in _dict) ? _dict[key] : null);
- }
-
- public function set(key:Object, object:Object):void
- {
- if (!(key in _dict))
- {
- _size++;
- }
- _dict[key] = object;
- }
-
- public function remove(key:Object):Object
- {
- var object:Object;
- if (key in _dict)
- {
- object = _dict[key];
- delete _dict[key];
- _size--;
- }
- return (object);
- }
-
- public function keys():Array
- {
- var array:Array = new Array(_size);
- var index:int;
- for (var key:Object in _dict)
- {
- var _local6:int = index++;
- array[_local6] = key;
- }
- return (array);
- }
-
- public function values():Array
- {
- var array:Array = new Array(_size);
- var index:int;
- for each (var value:Object in _dict)
- {
- var _local6:int = index++;
- array[_local6] = value;
- };
- return (array);
- }
-
- public function clear():void
- {
- _dict = new Dictionary();
- _size = 0;
- }
-
- public function toArray():Array
- {
- var array:Array = new Array(_size * 2);
- var index:int;
- for (var key:Object in _dict)
- {
- var _local6:int = index++;
- array[_local6] = key;
- var _local7:int = index++;
- array[_local7] = _dict[key];
- };
- return (array);
- }
-
- public function toObject():Object
- {
- return (toArray());
- }
-
- public function fromObject(object:Object):void
- {
- clear();
- var index:uint;
- while (index < (object as Array).length) {
- set((object as Array)[index], (object as Array)[(index + 1)]);
- index += 2;
- };
- }
-
- public function get size():uint
- {
- return (_size);
- }
-
-}
-
-import flash.utils.ByteArray;
-
-/**
- * a piece of flv, fetch from cdn or p2p.
- */
-class FlvPiece
-{
- private var _pieceId:Number;
- protected var _flv:ByteArray;
- /**
- * the private object for the channel,
- * for example, the cdn channel will set to CdnEdge object.
- */
- private var _privateObject:Object;
- /**
- * when encoder error, this piece cannot be generated,
- * and it should be skip. default to false.
- */
- private var _skip:Boolean;
-
- public function FlvPiece(pieceId:Number)
- {
- _pieceId = pieceId;
- _flv = null;
- _skip = false;
- }
-
- /**
- * when piece is fetch ok.
- */
- public function onPieceDone(flv:ByteArray):void
- {
- // save body.
- _flv = flv;
- }
-
- /**
- * when piece is fetch error.
- */
- public function onPieceError():void
- {
- }
-
- /**
- * when piece is empty.
- */
- public function onPieceEmpty():void
- {
- }
-
- /**
- * destroy the object, set reference to null.
- */
- public function destroy():void
- {
- _privateObject = null;
- _flv = null;
- }
-
- public function get privateObject():Object
- {
- return _privateObject;
- }
-
- public function set privateObject(v:Object):void
- {
- _privateObject = v;
- }
-
- public function get skip():Boolean
- {
- return _skip;
- }
-
- public function set skip(v:Boolean):void
- {
- _skip = v;
- }
-
- public function get pieceId():Number
- {
- return _pieceId;
- }
-
- public function get flv():ByteArray
- {
- return _flv;
- }
-
- public function get completed():Boolean
- {
- return _flv != null;
- }
-}
-
-interface ILogger
-{
- function debug0(message:String, ... rest):void;
- function debug(message:String, ... rest):void;
- function info(message:String, ... rest):void;
- function warn(message:String, ... rest):void;
- function error(message:String, ... rest):void;
- function fatal(message:String, ... rest):void;
-}
-
-import flash.globalization.DateTimeFormatter;
-import flash.external.ExternalInterface;
-
-class TraceLogger implements ILogger
-{
- private var _category:String;
-
- public function get category():String
- {
- return _category;
- }
- public function TraceLogger(category:String)
- {
- _category = category;
- }
- public function debug0(message:String, ...rest):void
- {
- }
-
- public function debug(message:String, ...rest):void
- {
- }
-
- public function info(message:String, ...rest):void
- {
- logMessage(LEVEL_INFO, message, rest);
- }
-
- public function warn(message:String, ...rest):void
- {
- logMessage(LEVEL_WARN, message, rest);
- }
-
- public function error(message:String, ...rest):void
- {
- logMessage(LEVEL_ERROR, message, rest);
- }
-
- public function fatal(message:String, ...rest):void
- {
- logMessage(LEVEL_FATAL, message, rest);
- }
- protected function logMessage(level:String, message:String, params:Array):void
- {
- var msg:String = "";
-
- // add datetime
- var date:Date = new Date();
- var dtf:DateTimeFormatter = new DateTimeFormatter("UTC");
- dtf.setDateTimePattern("yyyy-MM-dd HH:mm:ss");
-
- // TODO: FIXME: the SSS format not run, use date.milliseconds instead.
- msg += '[' + dtf.format(date) + "." + date.milliseconds + ']';
- msg += " [" + level + "] ";
-
- // add category and params
- msg += "[" + category + "] " + applyParams(message, params);
-
- // trace the message
- trace(msg);
-
- if (!flash.external.ExternalInterface.available) {
- return;
- }
-
- ExternalInterface.call("console.log", msg);
- }
- private function leadingZeros(x:Number):String
- {
- if (x < 10) {
- return "00" + x.toString();
- }
-
- if (x < 100) {
- return "0" + x.toString();
- }
-
- return x.toString();
- }
- private function applyParams(message:String, params:Array):String
- {
- var result:String = message;
-
- var numParams:int = params.length;
-
- for (var i:int = 0; i < numParams; i++) {
- result = result.replace(new RegExp("\\{" + i + "\\}", "g"), params[i]);
- }
- return result;
- }
-
- private static const LEVEL_DEBUG:String = "DEBUG";
- private static const LEVEL_WARN:String = "WARN";
- private static const LEVEL_INFO:String = "INFO";
- private static const LEVEL_ERROR:String = "ERROR";
- private static const LEVEL_FATAL:String = "FATAL";
-}
-
-import flash.utils.ByteArray;
-
-class SrsTsHanlder implements ISrsTsHandler
-{
- private var avc:SrsRawH264Stream;
- private var h264_sps:ByteArray;
- private var h264_pps:ByteArray;
- private var h264_sps_changed:Boolean;
- private var h264_pps_changed:Boolean;
-
- private var aac:SrsRawAacStream;
- private var aac_specific_config:ByteArray;
- private var width:int;
- private var height:int;
-
- private var video_sh_tag:ByteArray;
- private var audio_sh_tag:ByteArray;
-
- private var queue:Array;
-
- // hls data.
- private var _hls:HlsCodec;
- private var _body:ByteArray;
- private var _on_size_changed:Function;
- private var _on_sequence_changed:Function;
-
- private var _log:ILogger = new TraceLogger("HLS");
-
- public function SrsTsHanlder(
- pavc:SrsRawH264Stream, paac:SrsRawAacStream,
- ph264_sps:ByteArray, ph264_pps:ByteArray,
- paac_specific_config:ByteArray,
- pvideo_sh_tag:ByteArray, paudio_sh_tag:ByteArray,
- hls:HlsCodec, body:ByteArray, oszc:Function, oshc:Function)
- {
- _hls = hls;
- _body = body;
- _on_size_changed = oszc;
- _on_sequence_changed = oshc;
-
- avc = pavc;
- h264_sps = ph264_sps;
- h264_pps = ph264_pps;
-
- aac = paac;
- aac_specific_config = paac_specific_config;
-
- video_sh_tag = pvideo_sh_tag;
- audio_sh_tag = paudio_sh_tag;
-
- queue = new Array();
- width = 0;
- height = 0;
- h264_sps_changed = false;
- h264_pps_changed = false;
- }
-
- public function on_ts_message(msg:SrsTsMessage):void
- {
- do_on_ts_message(msg, _body);
- }
-
- private function do_on_ts_message(msg:SrsTsMessage, body:ByteArray):void
- {
- // @see SrsMpegtsOverUdp::on_ts_message
- if (false) {
- _log.info("got ts {4} message, dts={0}, pts={1}, size={2}/{3}",
- msg.dts, msg.pts, msg.PES_packet_length, msg.payload.length,
- (msg.channel.apply.equals(SrsTsPidApply.Video)? "Video":"Audio"));
- } else {
- _log.debug("got ts {4} message, dts={0}, pts={1}, size={2}/{3}",
- msg.dts, msg.pts, msg.PES_packet_length, msg.payload.length,
- (msg.channel.apply.equals(SrsTsPidApply.Video)? "Video":"Audio"));
- }
-
- // when not audio/video, or not adts/annexb format, donot support.
- if (msg.stream_number() != 0) {
- throw new Error("mpegts: unsupported stream format, sid=" + msg.stream_number());
- }
-
- // check supported codec
- if (msg.channel.stream != SrsTsStream.VideoH264 && msg.channel.stream != SrsTsStream.AudioAAC) {
- throw new Error("mpegts: unsupported stream codec=" + msg.channel.stream.toString());
- }
-
- // we must use queue to cache the msg, then parse it if possible.
- queue.push(msg);
- parse_message_queue(body);
- }
-
- private function parse_message_queue(body:ByteArray):void
- {
- if (queue.length == 0) {
- return;
- }
-
- var first_ts_msg:SrsTsMessage = queue[0] as SrsTsMessage;
- var context:SrsTsContext = first_ts_msg.channel.context;
- var cpa:Boolean = context.is_pure_audio();
-
- var nb_videos:uint = 0;
- if (!cpa) {
- for (var i:int = 0; i < queue.length; i++) {
- var msg:SrsTsMessage = queue[i] as SrsTsMessage;
-
- // publish audio or video.
- if (msg.channel.stream == SrsTsStream.VideoH264) {
- nb_videos++;
- }
- }
-
- // always wait 2+ videos, to left one video in the queue.
- // TODO: FIXME: support pure audio hls.
- if (nb_videos <= 1) {
- return;
- }
- }
-
- // we must sort the adio and videos, for they maybe not monotonically increase.
- queue.sort(function(a:SrsTsMessage, b:SrsTsMessage):int{
- return a.dts - b.dts;
- });
-
- // parse messages util the last video.
- while ((cpa && queue.length > 1) || nb_videos > 1) {
- if (queue.length == 0) {
- throw new Error("assert queue not empty.");
- }
-
- msg = queue[0] as SrsTsMessage;
- if (msg.channel.stream == SrsTsStream.VideoH264) {
- nb_videos--;
- }
- queue.splice(0, 1);
-
- // publish audio or video.
- if (msg.channel.stream == SrsTsStream.VideoH264) {
- on_ts_video(msg, body);
- }
- if (msg.channel.stream == SrsTsStream.AudioAAC) {
- on_ts_audio(msg, body);
- }
- }
- }
-
- public function flush_message_queue(body:ByteArray):void
- {
- for (var i:int = 0; i < queue.length; i++) {
- var msg:SrsTsMessage = queue[i] as SrsTsMessage;
-
- // publish audio or video.
- if (msg.channel.stream == SrsTsStream.VideoH264) {
- on_ts_video(msg, body);
- }
- if (msg.channel.stream == SrsTsStream.AudioAAC) {
- on_ts_audio(msg, body);
- }
- }
-
- // clear queue.
- queue = new Array();
- }
-
- private function on_ts_video(msg:SrsTsMessage, body:ByteArray):void
- {
- // ts tbn to flv tbn.
- var dts:uint = (uint)(msg.dts / 90);
- var pts:uint = (uint)(msg.pts / 90);
-
- var ibps:ByteArray = new ByteArray();
- var frame_type:uint = SrsConsts.SrsCodecVideoAVCFrameInterFrame;
-
- // each frame must prefixed by annexb format.
- // first check the msg.payload outside the while cycle, to avoid throw error inside.
- // if msg.payload not startwith annexb, just return.
- var annexb:Object = SrsUtils.srs_avc_startswith_annexb(msg.payload);
- if (!annexb.ok) {
- _log.warn("msg.payload not startwith annexb, drop size={0}B, dts={1}", msg.payload.length, dts);
- return;
- }
-
- // group each NALU frame to a RTMP/flv/ts message
- while (msg.payload.bytesAvailable) {
- var frame:ByteArray = avc.annexb_demux(msg.payload);
-
- // 5bits, 7.3.1 NAL unit syntax,
- // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
- // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
- var nal_unit_type:uint = (uint)(frame[0] & 0x1f);
-
- // for IDR frame, the frame is keyframe.
- if (nal_unit_type == SrsConsts.SrsAvcNaluTypeIDR) {
- frame_type = SrsConsts.SrsCodecVideoAVCFrameKeyFrame;
- }
-
- // ignore the nalu type aud(9)
- if (nal_unit_type == SrsConsts.SrsAvcNaluTypeAccessUnitDelimiter) {
- var aud_nalu:String = "";
- for (var i:int = 0; i < frame.length; i++) {
- aud_nalu += " 0x" + int(frame[i]).toString(16);
- }
- _log.debug("hls, aud nalu: {0}", aud_nalu);
- continue;
- }
-
- // for sps
- if (avc.is_sps(frame)) {
- var sps:ByteArray = avc.sps_demux(frame);
-
- if (SrsUtils.array_equals(h264_sps, sps)) {
- continue;
- }
- h264_sps = sps;
- h264_sps_changed = true;
-
- // demux the sps, get the width x height.
- avc_demux_sps(sps);
-
- if (false) {
- _log.info("hls: got sps, size={0}B", sps.length);
- } else {
- _log.debug("hls: got sps, size={0}B", sps.length);
- }
- continue;
- }
-
- // for pps
- if (avc.is_pps(frame)) {
- var pps:ByteArray = avc.pps_demux(frame);
-
- if (SrsUtils.array_equals(h264_pps, pps)) {
- continue;
- }
- h264_pps = pps;
- h264_pps_changed = true;
-
- if (false) {
- _log.info("hls: got pps, size={0}B", pps.length);
- } else {
- _log.debug("hls: got pps, size={0}B", pps.length);
- }
- continue;
- }
-
- // ibp frame.
- //info("mpegts: demux avc ibp frame size=%d, dts=%d", ibpframe_size, dts);
- var ibp:ByteArray = avc.mux_ipb_frame(frame);
- ibps.writeBytes(ibp);
- }
-
- write_h264_sps_pps(msg.channel.context, dts, pts);
- write_h264_ipb_frame(ibps, frame_type, dts, pts, body);
- }
-
- private function on_ts_audio(msg:SrsTsMessage, piece:ByteArray):void
- {
- // ts tbn to flv tbn.
- var dts:uint = msg.dts / 90;
-
- // got the next message to calc the delta duration for each audio.
- var duration:uint = 0;
- if (queue.length > 0) {
- var nm:SrsTsMessage = queue[0] as SrsTsMessage;
- duration = (uint)(Math.max(0, nm.dts - msg.dts) / 90);
- }
- var min_dts:uint = dts;
- var max_dts:uint = min_dts + duration;
-
- // send each frame.
- while (msg.payload.bytesAvailable) {
- var ret:Object = aac.adts_demux(msg.payload);
- var frame:ByteArray = ret.frame;
- var codec:SrsRawAacStreamCodec = ret.codec;
-
- // ignore invalid frame,
- // * atleast 1bytes for aac to decode the data.
- if (!frame.bytesAvailable) {
- continue;
- }
- //info("mpegts: demux aac frame size=%d, dts=%d", frame_size, dts);
-
- // generate sh.
- if (!aac_specific_config.length) {
- aac_specific_config = aac.mux_sequence_header(codec);
- codec.aac_packet_type = 0;
- if (false) {
- _log.info("hls: got audio specific config, size={0}B", aac_specific_config.length);
- } else {
- _log.debug("hls: got audio specific config, size={0}B", aac_specific_config.length);
- }
-
- var tag_body:ByteArray = aac.mux_aac2flv(aac_specific_config, codec, dts);
- audio_sh_tag = mux_flv_packet(SrsConsts.SrsCodecFlvTagAudio, dts, tag_body);
- on_sequence_header(msg.channel.context);
- }
-
- // audio raw data.
- codec.aac_packet_type = 1;
- write_audio_raw_frame(frame, codec, dts, piece);
-
- // calc the delta of dts, when previous frame output.
- var delta:uint = duration / (msg.payload.length / frame.length);
- dts = (uint)(Math.min(max_dts, dts + delta));
-
- if (msg.payload.bytesAvailable) {
- _log.debug("Audio [{0}, {1}], the A2+ is {2}", min_dts, max_dts, dts);
- }
- }
- }
-
- private function write_audio_raw_frame(frame:ByteArray, codec:SrsRawAacStreamCodec, dts:uint, piece:ByteArray):void
- {
- var tag_body:ByteArray = aac.mux_aac2flv(frame, codec, dts);
- var tag:ByteArray = mux_flv_packet(SrsConsts.SrsCodecFlvTagAudio, dts, tag_body);
-
- // append flv packet to piece.
- piece.writeBytes(tag);
- }
-
- private function avc_demux_sps(sps:ByteArray):void
- {
- sps.position = 0;
-
- if (false) {
- var str:String = "";
- for (var i:int = 0; i < sps.length; i++) {
- str += " 0x" + int(sps[i]).toString(16);
- }
- }
-
- var nalu_type:uint = sps.readUnsignedByte();
- if ((nalu_type & 0x1f) != SrsConsts.SrsAvcNaluTypeSPS) {
- _log.warn("avc: sps nalu type invalid.");
- return;
- }
-
- var rbsp:ByteArray = new ByteArray();
- while (sps.bytesAvailable) {
- rbsp.writeByte(sps.readByte());
-
- // XX 00 00 03 XX, the 03 byte should be drop.
- var nb_rbsp:uint = rbsp.length;
- if (nb_rbsp > 2) {
- var p2:uint = rbsp[nb_rbsp - 3];
- var p1:uint = rbsp[nb_rbsp - 2];
- var p0:uint = rbsp[nb_rbsp - 1];
- if (p2 == 0 && p1 == 0 && p0 == 3) {
- rbsp.position = rbsp.length - 1;
-
- // read 1 byte more.
- if (!sps.bytesAvailable) {
- break;
- }
- rbsp.writeByte(sps.readByte());
- }
- }
- }
-
- try {
- avc_demux_sps_rbsp(rbsp);
- } catch (e:Error) {
- _log.warn(e.message);
- }
- }
- private function avc_demux_sps_rbsp(rbsp:ByteArray):void
- {
- rbsp.position = 0;
-
- // for SPS, 7.3.2.1.1 Sequence parameter set data syntax
- // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62.
- if (rbsp.bytesAvailable < 3) {
- _log.warn("avc: sps shall atleast 3bytes");
- return;
- }
-
- var profile_idc:uint = rbsp.readUnsignedByte();
- var flags:uint = rbsp.readUnsignedByte();
- var level_idc:uint = rbsp.readUnsignedByte();
-
- var bs:SrsBitStream = new SrsBitStream(rbsp);
- var seq_parameter_set_id:uint = SrsUtils.srs_avc_nalu_read_uev(bs);
- _log.debug("sps parse profile={0}, level={1}, sps_id={2}", profile_idc, level_idc, seq_parameter_set_id);
-
- if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244
- || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118
- || profile_idc == 128
- ) {
- var chroma_format_idc:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- if (chroma_format_idc == 3) {
- var separate_colour_plane_flag:int = SrsUtils.srs_avc_nalu_read_bit(bs);
- }
- var bit_depth_luma_minus8:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var bit_depth_chroma_minus8:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var qpprime_y_zero_transform_bypass_flag:int = SrsUtils.srs_avc_nalu_read_bit(bs);
- var seq_scaling_matrix_present_flag:int = SrsUtils.srs_avc_nalu_read_bit(bs);
- if (seq_scaling_matrix_present_flag) {
- throw new Error("sps seq_scaling_matrix_present_flag not zero.");
- }
- _log.debug("sps cfi={0}, bdlm={1}, bdcm={2}, qyztb={3}, ssmpf={4}",
- chroma_format_idc, bit_depth_luma_minus8, bit_depth_chroma_minus8,
- qpprime_y_zero_transform_bypass_flag, seq_scaling_matrix_present_flag);
- }
-
- var log2_max_frame_num_minus4:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var pic_order_cnt_type:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- if (pic_order_cnt_type == 0) {
- var log2_max_pic_order_cnt_lsb_minus4:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- _log.debug("sps lmpoclm={0}", log2_max_pic_order_cnt_lsb_minus4);
- } else if (pic_order_cnt_type == 1) {
- var delta_pic_order_always_zero_flag:int = SrsUtils.srs_avc_nalu_read_bit(bs);
- var offset_for_non_ref_pic:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var offset_for_top_to_bottom_field:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var num_ref_frames_in_pic_order_cnt_cycle:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- _log.debug("sps dpoazf={0}, ofnrp={1}, ofttbf={2}, nrfipocc={3}",
- delta_pic_order_always_zero_flag, offset_for_non_ref_pic, offset_for_top_to_bottom_field,
- num_ref_frames_in_pic_order_cnt_cycle);
- }
- var max_num_ref_frames:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var gaps_in_frame_num_value_allowed_flag:int = SrsUtils.srs_avc_nalu_read_bit(bs);
- var pic_width_in_mbs_minus1:int = SrsUtils.srs_avc_nalu_read_uev(bs);
- var pic_height_in_map_units_minus1:int = SrsUtils.srs_avc_nalu_read_uev(bs);
-
- width = (int)(pic_width_in_mbs_minus1 + 1) * 16;
- height = (int)(pic_height_in_map_units_minus1 + 1) * 16;
- _log.info("sps parse profile={0}, level={1}, size={2}x{3}", profile_idc, level_idc, width, height);
-
- _on_size_changed(width, height);
- }
-
- private function write_h264_sps_pps(context:SrsTsContext, dts:uint, pts:uint):void
- {
- if (!h264_sps_changed && !h264_pps_changed) {
- return;
- }
-
- // when not got sps/pps, wait.
- if (h264_pps.length == 0 || h264_sps.length == 0) {
- return;
- }
-
- // h264 raw to h264 packet.
- var sh:ByteArray = avc.mux_sequence_header(h264_sps, h264_pps, dts, pts);
-
- // h264 packet to flv packet.
- var frame_type:uint = SrsConsts.SrsCodecVideoAVCFrameKeyFrame;
- var avc_packet_type:uint = SrsConsts.SrsCodecVideoAVCTypeSequenceHeader;
- var tag_body:ByteArray = avc.mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts);
-
- // the timestamp in rtmp message header is dts.
- video_sh_tag = mux_flv_packet(SrsConsts.SrsCodecFlvTagVideo, dts, tag_body);
- on_sequence_header(context);
- }
-
- private function write_h264_ipb_frame(ibps:ByteArray, frame_type:uint, dts:uint, pts:uint, piece:ByteArray):void
- {
- // when sps or pps not sent, ignore the packet.
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
- if (video_sh_tag.length == 0) {
- return;
- }
-
- var avc_packet_type:uint = SrsConsts.SrsCodecVideoAVCTypeNALU;
- var tag_body:ByteArray = avc.mux_avc2flv(ibps, frame_type, avc_packet_type, dts, pts);
-
- // the timestamp in rtmp message header is dts.
- var timestamp:uint = dts;
- var tag:ByteArray = mux_flv_packet(SrsConsts.SrsCodecFlvTagVideo, timestamp, tag_body);
-
- // append flv packet to piece.
- piece.writeBytes(tag);
- }
-
- private function mux_flv_packet(type:uint, timestamp:uint, flv:ByteArray):ByteArray
- {
- // E.4.1 FLV Tag
- var packet:ByteArray = new ByteArray();
-
- // Reserved UB [2]
- // Filter UB [1]
- // TagType UB [5]
- packet.writeByte(type & 0x1f);
-
- // DataSize UI24
- var size:uint = flv.length;
- packet.writeByte(size >> 16);
- packet.writeByte(size >> 8);
- packet.writeByte(size);
-
- // Timestamp UI24
- var dts:uint = timestamp;
- packet.writeByte(dts >> 16);
- packet.writeByte(dts >> 8);
- packet.writeByte(dts);
-
- // TimestampExtended UI8
- packet.writeByte(dts >> 24);
-
- // StreamID, UI24, Always 0.
- packet.writeByte(0x00);
- packet.writeByte(0x00);
- packet.writeByte(0x00);
-
- // tag body.
- packet.writeBytes(flv);
-
- // PreviousTagSizeN, UI32, Size of last tag, including its header, in bytes.
- size = packet.length;
- packet.writeUnsignedInt(size);
-
- if (false) {
- _log.info("FLV: mux flv type={0}, time={1}, size={3}", type, timestamp, dts, packet.length);
- } else {
- _log.debug("mux flv type={0}, time={1}, size={3}", type, timestamp, dts, packet.length);
- }
-
- return packet;
- }
-
- private function on_sequence_header(context:SrsTsContext):void
- {
- if (!audio_sh_tag.length) {
- return;
- }
- if (!context.is_pure_audio() && !video_sh_tag.length) {
- return;
- }
-
- var sh:ByteArray = new ByteArray();
-
- // @remark HSS without flv header.
- // 9bytes header and 4bytes first previous-tag-size
- // Signatures "FLV"
- sh.writeByte(0x46); // 'F'
- sh.writeByte(0x4c); // 'L'
- sh.writeByte(0x56); // 'V'
- // File version (for example, 0x01 for FLV version 1)
- sh.writeByte(0x01);
- // 4, audio; 1, video; 5 audio+video.
- if (context.is_pure_audio()) {
- sh.writeByte(0x04);
- } else {
- sh.writeByte(0x05);
- }
- // DataOffset UI32 The length of this header in bytes
- sh.writeUnsignedInt(0x00000009);
- // previous tag size.
- sh.writeUnsignedInt(0x00000000);
-
- // append video and audio sequence header.
- if (!context.is_pure_audio()) {
- sh.writeBytes(video_sh_tag);
- }
- sh.writeBytes(audio_sh_tag);
-
- // reset the positions.
- h264_sps.position = 0;
- h264_pps.position = 0;
- aac_specific_config.position = 0;
- video_sh_tag.position = 0;
- audio_sh_tag.position = 0;
-
- // notice the HLS to change sh if should to.
- _on_sequence_changed(
- avc, aac,
- h264_sps, h264_pps,
- aac_specific_config,
- video_sh_tag, audio_sh_tag,
- sh
- );
- }
-}
-
-class SrsConsts
-{
- // E.4.3.1 VIDEODATA
- // Frame Type UB [4]
- // Type of video frame. The following values are defined:
- // 1 = key frame (for AVC, a seekable frame)
- // 2 = inter frame (for AVC, a non-seekable frame)
- // 3 = disposable inter frame (H.263 only)
- // 4 = generated key frame (reserved for server use only)
- // 5 = video info/command frame
- public static const SrsCodecVideoAVCFrameReserved:uint = 0;
- public static const SrsCodecVideoAVCFrameReserved1:uint = 6;
-
- public static const SrsCodecVideoAVCFrameKeyFrame:uint = 1;
- public static const SrsCodecVideoAVCFrameInterFrame:uint = 2;
- public static const SrsCodecVideoAVCFrameDisposableInterFrame:uint = 3;
- public static const SrsCodecVideoAVCFrameGeneratedKeyFrame:uint = 4;
- public static const SrsCodecVideoAVCFrameVideoInfoFrame:uint = 5;
-
- // AACPacketType IF SoundFormat == 10 UI8
- // The following values are defined:
- // 0 = AAC sequence header
- // 1 = AAC raw
- public static const SrsCodecAudioTypeReserved:uint = 2;
-
- public static const SrsCodecAudioTypeSequenceHeader:uint = 0;
- public static const SrsCodecAudioTypeRawData:uint = 1;
-
- // AVCPacketType IF CodecID == 7 UI8
- // The following values are defined:
- // 0 = AVC sequence header
- // 1 = AVC NALU
- // 2 = AVC end of sequence (lower level NALU sequence ender is
- // not required or supported)
- public static const SrsCodecVideoAVCTypeReserved:uint = 3;
-
- public static const SrsCodecVideoAVCTypeSequenceHeader:uint = 0;
- public static const SrsCodecVideoAVCTypeNALU:uint = 1;
- public static const SrsCodecVideoAVCTypeSequenceHeaderEOF:uint = 2;
-
- // E.4.3.1 VIDEODATA
- // CodecID UB [4]
- // Codec Identifier. The following values are defined:
- // 2 = Sorenson H.263
- // 3 = Screen video
- // 4 = On2 VP6
- // 5 = On2 VP6 with alpha channel
- // 6 = Screen video version 2
- // 7 = AVC
- public static const SrsCodecVideoReserved:uint = 0;
- public static const SrsCodecVideoReserved1:uint = 1;
- public static const SrsCodecVideoReserved2:uint = 9;
-
- // for user to disable video, for example, use pure audio hls.
- public static const SrsCodecVideoDisabled:uint = 8;
-
- public static const SrsCodecVideoSorensonH263:uint = 2;
- public static const SrsCodecVideoScreenVideo:uint = 3;
- public static const SrsCodecVideoOn2VP6:uint = 4;
- public static const SrsCodecVideoOn2VP6WithAlphaChannel:uint = 5;
- public static const SrsCodecVideoScreenVideoVersion2:uint = 6;
- public static const SrsCodecVideoAVC:uint = 7;
-
- // SoundFormat UB [4]
- // Format of SoundData. The following values are defined:
- // 0 = Linear PCM, platform endian
- // 1 = ADPCM
- // 2 = MP3
- // 3 = Linear PCM, little endian
- // 4 = Nellymoser 16 kHz mono
- // 5 = Nellymoser 8 kHz mono
- // 6 = Nellymoser
- // 7 = G.711 A-law logarithmic PCM
- // 8 = G.711 mu-law logarithmic PCM
- // 9 = reserved
- // 10 = AAC
- // 11 = Speex
- // 14 = MP3 8 kHz
- // 15 = Device-specific sound
- // Formats 7, 8, 14, and 15 are reserved.
- // AAC is supported in Flash Player 9,0,115,0 and higher.
- // Speex is supported in Flash Player 10 and higher.
- public static const SrsCodecAudioReserved1:uint = 16;
-
- public static const SrsCodecAudioLinearPCMPlatformEndian:uint = 0;
- public static const SrsCodecAudioADPCM:uint = 1;
- public static const SrsCodecAudioMP3:uint = 2;
- public static const SrsCodecAudioLinearPCMLittleEndian:uint = 3;
- public static const SrsCodecAudioNellymoser16kHzMono:uint = 4;
- public static const SrsCodecAudioNellymoser8kHzMono:uint = 5;
- public static const SrsCodecAudioNellymoser:uint = 6;
- public static const SrsCodecAudioReservedG711AlawLogarithmicPCM:uint = 7;
- public static const SrsCodecAudioReservedG711MuLawLogarithmicPCM:uint = 8;
- public static const SrsCodecAudioReserved:uint = 9;
- public static const SrsCodecAudioAAC:uint = 10;
- public static const SrsCodecAudioSpeex:uint = 11;
- public static const SrsCodecAudioReservedMP3_8kHz:uint = 14;
- public static const SrsCodecAudioReservedDeviceSpecificSound:uint = 15;
-
- /**
- * the FLV/RTMP supported audio sample rate.
- * Sampling rate. The following values are defined:
- * 0 = 5.5 kHz = 5512 Hz
- * 1 = 11 kHz = 11025 Hz
- * 2 = 22 kHz = 22050 Hz
- * 3 = 44 kHz = 44100 Hz
- */
- public static const SrsCodecAudioSampleRateReserved:uint = 4;
-
- public static const SrsCodecAudioSampleRate5512:uint = 0;
- public static const SrsCodecAudioSampleRate11025:uint = 1;
- public static const SrsCodecAudioSampleRate22050:uint = 2;
- public static const SrsCodecAudioSampleRate44100:uint = 3;
-
- /**
- * E.4.1 FLV Tag, page 75
- */
- public static const SrsCodecFlvTagReserved:uint = 0;
-
- // 8 = audio
- public static const SrsCodecFlvTagAudio:uint = 8;
- // 9 = video
- public static const SrsCodecFlvTagVideo:uint = 9;
- // 18 = script data
- public static const SrsCodecFlvTagScript:uint = 18;
-
- /**
- * Table 7-1 – NAL unit type codes, syntax element categories, and NAL unit type classes
- * H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
- */
- // Coded slice of a non-IDR picture slice_layer_without_partitioning_rbsp( )
- public static const SrsAvcNaluTypeNonIDR:uint = 1;
- // Coded slice data partition A slice_data_partition_a_layer_rbsp( )
- public static const SrsAvcNaluTypeDataPartitionA:uint = 2;
- // Coded slice data partition B slice_data_partition_b_layer_rbsp( )
- public static const SrsAvcNaluTypeDataPartitionB:uint = 3;
- // Coded slice data partition C slice_data_partition_c_layer_rbsp( )
- public static const SrsAvcNaluTypeDataPartitionC:uint = 4;
- // Coded slice of an IDR picture slice_layer_without_partitioning_rbsp( )
- public static const SrsAvcNaluTypeIDR:uint = 5;
- // Supplemental enhancement information (SEI) sei_rbsp( )
- public static const SrsAvcNaluTypeSEI:uint = 6;
- // Sequence parameter set seq_parameter_set_rbsp( )
- public static const SrsAvcNaluTypeSPS:uint = 7;
- // Picture parameter set pic_parameter_set_rbsp( )
- public static const SrsAvcNaluTypePPS:uint = 8;
- // Access unit delimiter access_unit_delimiter_rbsp( )
- public static const SrsAvcNaluTypeAccessUnitDelimiter:uint = 9;
- // End of sequence end_of_seq_rbsp( )
- public static const SrsAvcNaluTypeEOSequence:uint = 10;
- // End of stream end_of_stream_rbsp( )
- public static const SrsAvcNaluTypeEOStream:uint = 11;
- // Filler data filler_data_rbsp( )
- public static const SrsAvcNaluTypeFilterData:uint = 12;
- // Sequence parameter set extension seq_parameter_set_extension_rbsp( )
- public static const SrsAvcNaluTypeSPSExt:uint = 13;
- // Prefix NAL unit prefix_nal_unit_rbsp( )
- public static const SrsAvcNaluTypePrefixNALU:uint = 14;
- // Subset sequence parameter set subset_seq_parameter_set_rbsp( )
- public static const SrsAvcNaluTypeSubsetSPS:uint = 15;
- // Coded slice of an auxiliary coded picture without partitioning slice_layer_without_partitioning_rbsp( )
- public static const SrsAvcNaluTypeLayerWithoutPartition:uint = 19;
- // Coded slice extension slice_layer_extension_rbsp( )
- public static const SrsAvcNaluTypeCodedSliceExt:uint = 20;
-}
-
-class SrsUtils
-{
- /*
- * MPEG2 transport stream (aka DVB) mux
- * Copyright (c) 2003 Fabrice Bellard.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- private static const crc_table:Array = [
- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
- 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
- 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
- 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
- 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
- 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
- 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
- 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
- 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
- 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
- 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
- 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
- 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
- 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
- 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
- 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
- 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
- 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
- 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
- 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
- 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
- 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
- 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
- ];
-
- // @see http://www.stmc.edu.hk/~vincent/ffmpeg_0.4.9-pre1/libavformat/mpegtsenc.c
- private static function mpegts_crc32(bytes:ByteArray):uint
- {
- var crc:uint = 0xffffffff;
-
- for (var i:int = 0; i < bytes.length; i++) {
- crc = (crc << 8) ^ crc_table[((crc >> 24) ^ bytes[i]) & 0xff];
- }
-
- return crc;
- }
-
- public static function srs_crc32(bytes:ByteArray):uint
- {
- return mpegts_crc32(bytes);
- }
-
- /**
- * parse the annexb header.
- * @return an object which is:
- * nb_header, an int start code, the header size.
- * ok, a bool indicates whether the stream is annexb.
- */
- public static function srs_avc_startswith_annexb(stream:ByteArray):Object
- {
- var nb_start_code:int = 0;
- var is_annexb:Boolean = false;
-
- var bytes:uint = stream.position;
- var p:uint = bytes;
- for (;;) {
- if (stream.bytesAvailable < p - bytes + 3) {
- break;
- }
-
- // not match
- if (stream[p] != 0x00 || stream[p + 1] != 0x00) {
- break;
- }
-
- // match N[00] 00 00 01, where N>=0
- if (stream[p + 2] == 0x01) {
- nb_start_code = p - bytes + 3;
- is_annexb = true;
- break;
- }
-
- p++;
- }
-
- return {
- nb_header: nb_start_code,
- ok: is_annexb
- };
- }
-
- /**
- * whether stream starts with the aac ADTS
- * from aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS.
- * start code must be '1111 1111 1111'B, that is 0xFFF
- */
- public static function srs_aac_startswith_adts(stream:ByteArray):Boolean
- {
- if (stream.bytesAvailable < 2) {
- return false;
- }
-
- // matched 12bits 0xFFF,
- // @remark, we must cast the 0xff to char to compare.
- var p:uint = stream.position;
- if (stream[p] != 0xff || (stream[p + 1] & 0xf0) != 0xf0) {
- return false;
- }
-
- return true;
- }
-
- public static function array_equals(a:ByteArray, b:ByteArray):Boolean
- {
- if ((a && !b) || (!b && a) || a.length != b.length) {
- return false;
- }
-
- for (var i:int = 0; i < a.length; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * read the ue(v) of h.264 bit stream.
- */
- public static function srs_avc_nalu_read_uev(stream:SrsBitStream):int
- {
- if (stream.empty()) {
- throw new Error("avc: h.264 bit stream empty.");
- }
-
- // ue(v) in 9.1 Parsing process for Exp-Golomb codes
- // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 227.
- // Syntax elements coded as ue(v), me(v), or se(v) are Exp-Golomb-coded.
- // leadingZeroBits = -1;
- // for( b = 0; !b; leadingZeroBits++ )
- // b = read_bits( 1 )
- // The variable codeNum is then assigned as follows:
- // codeNum = (2<= 31) {
- throw new Error("avc: h.264 ue(v) overflow.");
- }
-
- var v:int = (1 << leadingZeroBits) - 1;
- for (var i:int = 0; i < leadingZeroBits; i++) {
- b = stream.read_bit();
- v += b << (leadingZeroBits - 1 - i);
- }
-
- return v;
- }
-
- /**
- * read a bit from the h.264 avc bit stream.
- */
- public static function srs_avc_nalu_read_bit(stream:SrsBitStream):int
- {
- if (stream.empty()) {
- throw new Error("avc: h.264 bit stream empty.");
- }
-
- var v:int = stream.read_bit();
-
- return v;
- }
-
- public static function srs_print_bytes(bytes:ByteArray, len:int):void
- {
- var prt_len:int;
- var print:String = "";
-
- prt_len = len == -1? (bytes.length - bytes.position): len;
- prt_len = Math.min(prt_len, Math.min((bytes.length - bytes.position), 2048));
-
- for (var i:int = 0; i < prt_len; i++)
- {
- print += bytes[i + bytes.position].toString(16).toUpperCase() + " ";
- }
- trace(print);
- }
-}
-
-class SrsBitStream
-{
- private var stream:ByteArray;
- private var cb:uint;
- private var cb_left:uint;
-
- public function SrsBitStream(s:ByteArray)
- {
- cb = 0;
- cb_left = 0;
- stream = s;
- }
-
- public function empty():Boolean
- {
- if (cb_left) {
- return false;
- }
- return stream.bytesAvailable == 0;
- }
-
- public function read_bit():uint
- {
- if (!cb_left) {
- cb = stream.readUnsignedByte();
- cb_left = 8;
- }
-
- var v:uint = (cb >> (cb_left - 1)) & 0x01;
- cb_left--;
- return v;
- }
-}
-
-/**
- * the raw h.264 stream, in annexb.
- */
-class SrsRawH264Stream
-{
- private var _log:ILogger = new TraceLogger("HLS");
-
- public function SrsRawH264Stream()
- {
- }
-
- /**
- * demux the stream in annexb format.
- */
- public function annexb_demux(stream:ByteArray):ByteArray
- {
- var frame:ByteArray = new ByteArray();
- while (stream.bytesAvailable) {
- // each frame must prefixed by annexb format.
- // about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
- var annexb:Object = SrsUtils.srs_avc_startswith_annexb(stream);
- if (!annexb.ok) {
- throw new Error("avc: not annexb format.");
- }
-
- var nb_annexb_header:uint = annexb.nb_header;
- var start:uint = stream.position + annexb.nb_header;
- stream.position += annexb.nb_header;
-
- // find the last frame prefixed by annexb format.
- while (stream.bytesAvailable) {
- annexb = SrsUtils.srs_avc_startswith_annexb(stream);
- if (annexb.ok) {
- break;
- }
- stream.position++;
- }
-
- // demux the frame.
- var pos:uint = stream.position;
- var nb_frame:int = pos - start;
- stream.position = start;
- stream.readBytes(frame, 0, nb_frame);
- stream.position = pos;
- _log.debug("avc: annexb {0}B header, {1}B frame", nb_annexb_header, nb_frame);
- break;
- }
- return frame;
- }
- /**
- * whether the frame is sps or pps.
- */
- public function is_sps(frame:ByteArray):Boolean
- {
- // 5bits, 7.3.1 NAL unit syntax,
- // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
- // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
- var nal_unit_type:uint = (frame[0] & 0x1f);
-
- return nal_unit_type == 7;
- }
- public function is_pps(frame:ByteArray):Boolean
- {
- // 5bits, 7.3.1 NAL unit syntax,
- // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
- // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
- var nal_unit_type:uint = (frame[0] & 0x1f);
-
- return nal_unit_type == 8;
- }
- /**
- * demux the sps or pps to string.
- * @param sps/pps output the sps/pps.
- */
- public function sps_demux(frame:ByteArray):ByteArray
- {
- // atleast 1bytes for SPS to decode the type, profile, constrain and level.
- if (frame.bytesAvailable < 4) {
- return null;
- }
-
- return frame;
- }
- public function pps_demux(frame:ByteArray):ByteArray
- {
- if (!frame.bytesAvailable) {
- return null;
- }
- return frame;
- }
-
- /**
- * h264 raw data to h264 packet, without flv payload header.
- * mux the sps/pps to flv sequence header packet.
- * @param sh output the sequence header.
- */
- public function mux_sequence_header(sps:ByteArray, pps:ByteArray, dts:uint, pts:uint):ByteArray
- {
- var sh:ByteArray = new ByteArray();
-
- // 5bytes sps/pps header:
- // configurationVersion, AVCProfileIndication, profile_compatibility,
- // AVCLevelIndication, lengthSizeMinusOne
- // 3bytes size of sps:
- // numOfSequenceParameterSets, sequenceParameterSetLength(2B)
- // Nbytes of sps.
- // sequenceParameterSetNALUnit
- // 3bytes size of pps:
- // numOfPictureParameterSets, pictureParameterSetLength
- // Nbytes of pps:
- // pictureParameterSetNALUnit
-
- // decode the SPS:
- // @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62
- if (true) {
- if (sps.length < 4) {
- throw new Error("sps atleast 4bytes.");
- }
- var frame:ByteArray = sps;
-
- // @see: Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205
- // Baseline profile profile_idc is 66(0x42).
- // Main profile profile_idc is 77(0x4d).
- // Extended profile profile_idc is 88(0x58).
- var profile_idc:int = (int)(frame[1]);
- //u_int8_t constraint_set = frame[2];
- var level_idc:int = (int)(frame[3]);
-
- // generate the sps/pps header
- // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
- // configurationVersion
- sh.writeByte(0x01);
- // AVCProfileIndication
- sh.writeByte(profile_idc);
- // profile_compatibility
- sh.writeByte(0x00);
- // AVCLevelIndication
- sh.writeByte(level_idc);
- // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size,
- // so we always set it to 0x03.
- sh.writeByte(0x03);
- }
-
- // sps
- if (true) {
- // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
- // numOfSequenceParameterSets, always 1
- sh.writeByte(0x01);
- // sequenceParameterSetLength
- sh.writeShort(sps.length);
- // sequenceParameterSetNALUnit
- sh.writeBytes(sps);
- }
-
- // pps
- if (true) {
- // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
- // numOfPictureParameterSets, always 1
- sh.writeByte(0x01);
- // pictureParameterSetLength
- sh.writeShort(pps.length);
- // pictureParameterSetNALUnit
- sh.writeBytes(pps);
- }
-
- // TODO: FIXME: for more profile.
- // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
- // profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144
-
- return sh;
- }
- /**
- * h264 raw data to h264 packet, without flv payload header.
- * mux the ibp to flv ibp packet.
- * @return ibp an ByteArray contains the bytes.
- */
- public function mux_ipb_frame(frame:ByteArray):ByteArray
- {
- var ibp:ByteArray = new ByteArray();
-
- // 4bytes size of nalu:
- // NALUnitLength
- // Nbytes of nalu.
- // NALUnit
-
- // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
- // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size
- var NAL_unit_length:uint = frame.length;
-
- // mux the avc NALU in "ISO Base Media File Format"
- // from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
- // NALUnitLength
- ibp.writeUnsignedInt(NAL_unit_length);
- // NALUnit
- ibp.writeBytes(frame);
-
- return ibp;
- }
- /**
- * mux the avc video packet to flv video packet.
- * @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.
- * @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU.
- * @param video the h.264 raw data.
- * @param flv output the muxed flv packet.
- * @param nb_flv output the muxed flv size.
- */
- public function mux_avc2flv(frame:ByteArray, frame_type:uint, avc_packet_type:uint, dts:uint, pts:uint):ByteArray
- {
- var flv:ByteArray = new ByteArray();
-
- // for h264 in RTMP video payload, there is 5bytes header:
- // 1bytes, FrameType | CodecID
- // 1bytes, AVCPacketType
- // 3bytes, CompositionTime, the cts.
- // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
-
- // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
- // Frame Type, Type of video frame.
- // CodecID, Codec Identifier.
- // set the rtmp header
- flv.writeByte((frame_type << 4) | SrsConsts.SrsCodecVideoAVC);
-
- // AVCPacketType
- flv.writeByte(avc_packet_type);
-
- // CompositionTime
- // pts = dts + cts, or
- // cts = pts - dts.
- // where cts is the header in rtmp video packet payload header.
- var cts:uint = pts - dts;
- flv.writeByte(cts >> 16);
- flv.writeByte(cts >> 8);
- flv.writeByte(cts);
-
- // h.264 raw data.
- flv.writeBytes(frame);
-
- return flv;
- }
-};
-
-/**
- * the header of adts sample.
- */
-class SrsRawAacStreamCodec
-{
- public var protection_absent:uint;
- public var aac_object:SrsAacObjectType;
- public var sampling_frequency_index:uint;
- public var channel_configuration:uint;
- public var frame_length:uint;
-
- public var sound_format:uint;
- public var sound_rate:uint;
- public var sound_size:uint;
- public var sound_type:uint;
- // 0 for sh; 1 for raw data.
- public var aac_packet_type:uint;
-};
-
-/**
- * the raw aac stream, in adts.
- */
-class SrsRawAacStream
-{
- private var _log:ILogger = new TraceLogger("HLS");
-
- public function SrsRawAacStream()
- {
- }
-
- /**
- * demux the stream in adts format.
- * @param stream the input stream bytes.
- * @return an object which is:
- * frame a byte array contains the demuxed aac frame.
- * code a aac stream codec info.
- */
- public function adts_demux(stream:ByteArray):Object
- {
- var frame:ByteArray = new ByteArray();
- var codec:SrsRawAacStreamCodec = new SrsRawAacStreamCodec();
-
- while (stream.bytesAvailable) {
- var adts_header_start:uint = stream.position;
-
- // decode the ADTS.
- // @see aac-iso-13818-7.pdf, page 26
- // 6.2 Audio Data Transport Stream, ADTS
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885
- // byte_alignment()
-
- // adts_fixed_header:
- // 12bits syncword,
- // 16bits left.
- // adts_variable_header:
- // 28bits
- // 12+16+28=56bits
- // adts_error_check:
- // 16bits if protection_absent
- // 56+16=72bits
- // if protection_absent:
- // require(7bytes)=56bits
- // else
- // require(9bytes)=72bits
- if (stream.bytesAvailable < 7) {
- throw new Error("aac: adts required atleast 7bytes.");
- }
-
- // for aac, the frame must be ADTS format.
- if (!SrsUtils.srs_aac_startswith_adts(stream)) {
- throw new Error("aac: adts schema invalid.");
- }
-
- // syncword 12 bslbf
- stream.readByte();
- // 4bits left.
- // adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS
- // ID 1 bslbf
- // layer 2 uimsbf
- // protection_absent 1 bslbf
- var pav:uint = (stream.readUnsignedByte() & 0x0f);
- var id:uint = (uint)((pav >> 3) & 0x01);
- /*int8_t layer = (pav >> 1) & 0x03;*/
- var protection_absent:uint = pav & 0x01;
-
- /**
- * ID: MPEG identifier, set to ‘1’ if the audio data in the ADTS stream are MPEG-2 AAC (See ISO/IEC 13818-7)
- * and set to ‘0’ if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3.
- */
- if (id != 0x01) {
- //warn("adts: id must be 1(aac), actual 0(mp4a).");
-
- // well, some system always use 0, but actually is aac format.
- // for example, houjian vod ts always set the aac id to 0, actually 1.
- // we just ignore it, and alwyas use 1(aac) to demux.
- id = 0x01;
- }
-
- var sfiv:uint = stream.readUnsignedShort();
- // profile 2 uimsbf
- // sampling_frequency_index 4 uimsbf
- // private_bit 1 bslbf
- // channel_configuration 3 uimsbf
- // original/copy 1 bslbf
- // home 1 bslbf
- var profile:uint = (sfiv >> 14) & 0x03;
- var sampling_frequency_index:uint = (sfiv >> 10) & 0x0f;
- /*int8_t private_bit = (sfiv >> 9) & 0x01;*/
- var channel_configuration:uint = (sfiv >> 6) & 0x07;
- /*int8_t original = (sfiv >> 5) & 0x01;*/
- /*int8_t home = (sfiv >> 4) & 0x01;*/
- //int8_t Emphasis; @remark, Emphasis is removed, @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
- // 4bits left.
- // adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
- // copyright_identification_bit 1 bslbf
- // copyright_identification_start 1 bslbf
- /*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/
- /*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/
- // frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.
- // use the left 2bits as the 13 and 12 bit,
- // the frame_length is 13bits, so we move 13-2=11.
- var frame_length:uint = (sfiv << 11) & 0x1800;
-
- // skip -1 to read 4B for actually read 3B
- stream.position -= 1;
- var abfv:uint = (stream.readUnsignedInt() & 0x00ffffff);
- // frame_length 13 bslbf: consume the first 13-2=11bits
- // the fh2 is 24bits, so we move right 24-11=13.
- frame_length |= (abfv >> 13) & 0x07ff;
- // adts_buffer_fullness 11 bslbf
- /*int16_t fh_adts_buffer_fullness = (abfv >> 2) & 0x7ff;*/
- // number_of_raw_data_blocks_in_frame 2 uimsbf
- /*int16_t number_of_raw_data_blocks_in_frame = abfv & 0x03;*/
- // adts_error_check(), 1.A.2.2.3 Error detection
- if (!protection_absent) {
- if (stream.bytesAvailable < 2) {
- throw new Error("aac: adts header corrupt.");
- }
- // crc_check 16 Rpchof
- /*int16_t crc_check = */ stream.readUnsignedShort();
- }
-
- // TODO: check the sampling_frequency_index
- // TODO: check the channel_configuration
-
- // raw_data_blocks
- var adts_header_size:uint = stream.position - adts_header_start;
- var raw_data_size:uint = frame_length - adts_header_size;
- if (stream.bytesAvailable < raw_data_size) {
- throw new Error("aac: adts raw data corrupt.");
- }
-
- // the codec info.
- codec.protection_absent = protection_absent;
- codec.aac_object = SrsAacProfile.parse(profile).toRtmpObjectType();
- codec.sampling_frequency_index = sampling_frequency_index;
- codec.channel_configuration = channel_configuration;
- codec.frame_length = frame_length;
-
- // @see srs_audio_write_raw_frame().
- codec.sound_format = 10; // AAC
- // TODO: FIXME: maybe need to resample audio.
- if (sampling_frequency_index <= 0x0c && sampling_frequency_index > 0x0a) {
- codec.sound_rate = SrsConsts.SrsCodecAudioSampleRate5512;
- } else if (sampling_frequency_index <= 0x0a && sampling_frequency_index > 0x07) {
- codec.sound_rate = SrsConsts.SrsCodecAudioSampleRate11025;
- } else if (sampling_frequency_index <= 0x07 && sampling_frequency_index > 0x04) {
- codec.sound_rate = SrsConsts.SrsCodecAudioSampleRate22050;
- } else if (sampling_frequency_index <= 0x04) {
- codec.sound_rate = SrsConsts.SrsCodecAudioSampleRate44100;
- } else {
- codec.sound_rate = SrsConsts.SrsCodecAudioSampleRate44100;
- _log.warn("adts invalid sample rate for flv, rate=%{0}", sampling_frequency_index);
- }
- codec.sound_type = (uint)(Math.max(0, Math.min(1, channel_configuration - 1)));
- // TODO: FIXME: finger it out the sound size by adts.
- codec.sound_size = 1; // 0(8bits) or 1(16bits).
-
- // frame data.
- stream.readBytes(frame, 0, raw_data_size);
-
- break;
- }
-
- return {
- frame: frame,
- codec: codec
- };
- }
- /**
- * aac raw data to aac packet, without flv payload header.
- * mux the aac specific config to flv sequence header packet.
- * @param sh output the sequence header.
- */
- public function mux_sequence_header(codec:SrsRawAacStreamCodec):ByteArray
- {
- var sh:ByteArray = new ByteArray();
-
- // only support aac profile 1-4.
- if (codec.aac_object == SrsAacObjectType.Reserved) {
- throw new Error("aac: profile invalid.");
- }
-
- var audioObjectType:SrsAacObjectType = codec.aac_object;
- var channelConfiguration:uint = codec.channel_configuration;
- var samplingFrequencyIndex:uint = codec.sampling_frequency_index;
-
- // override the aac samplerate by user specified.
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899
- switch (codec.sound_rate) {
- case SrsConsts.SrsCodecAudioSampleRate11025:
- samplingFrequencyIndex = 0x0a; break;
- case SrsConsts.SrsCodecAudioSampleRate22050:
- samplingFrequencyIndex = 0x07; break;
- case SrsConsts.SrsCodecAudioSampleRate44100:
- samplingFrequencyIndex = 0x04; break;
- default:
- break;
- }
-
- var ch:uint = 0;
- // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf
- // AudioSpecificConfig (), page 33
- // 1.6.2.1 AudioSpecificConfig
- // audioObjectType; 5 bslbf
- ch = (audioObjectType.toInt() << 3) & 0xf8;
- // 3bits left.
-
- // samplingFrequencyIndex; 4 bslbf
- ch |= (samplingFrequencyIndex >> 1) & 0x07;
- sh.writeByte(ch);
- ch = (samplingFrequencyIndex << 7) & 0x80;
- if (samplingFrequencyIndex == 0x0f) {
- throw new Error("aac: sample rate invalid.");
- }
- // 7bits left.
-
- // channelConfiguration; 4 bslbf
- ch |= (channelConfiguration << 3) & 0x78;
- // 3bits left.
-
- // GASpecificConfig(), page 451
- // 4.4.1 Decoder configuration (GASpecificConfig)
- // frameLengthFlag; 1 bslbf
- // dependsOnCoreCoder; 1 bslbf
- // extensionFlag; 1 bslbf
- sh.writeByte(ch);
-
- return sh;
- }
- /**
- * mux the aac audio packet to flv audio packet.
- * @param frame the aac raw data.
- * @param nb_frame the count of aac frame.
- * @param codec the codec info of aac.
- * @param flv output the muxed flv packet.
- * @param nb_flv output the muxed flv size.
- */
- public function mux_aac2flv(frame:ByteArray, codec:SrsRawAacStreamCodec, dts:uint):ByteArray
- {
- var flv:ByteArray = new ByteArray();
-
- var sound_format:uint = codec.sound_format;
- var sound_type:uint = codec.sound_type;
- var sound_size:uint = codec.sound_size;
- var sound_rate:uint = codec.sound_rate;
- var aac_packet_type:uint = codec.aac_packet_type;
-
- // for audio frame, there is 1 or 2 bytes header:
- // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType
- // 1bytes, AACPacketType for SoundFormat == 10, 0 is sequence header.
-
- var audio_header:uint = sound_type & 0x01;
- audio_header |= (sound_size << 1) & 0x02;
- audio_header |= (sound_rate << 2) & 0x0c;
- audio_header |= (sound_format << 4) & 0xf0;
-
- flv.writeByte(audio_header);
-
- if (sound_format == SrsConsts.SrsCodecAudioAAC) {
- flv.writeByte(aac_packet_type);
- }
-
- flv.writeBytes(frame);
-
- return flv;
- }
-};
-
-/**
- * the fake enum.
- */
-class SrsEnum
-{
- protected var value:int;
-
- public function SrsEnum(v:int)
- {
- value = v;
- }
-
- public function equals(e:SrsEnum):Boolean
- {
- return value == e.value;
- }
-
- public function notEquals(e:SrsEnum):Boolean
- {
- return value != e.value;
- }
-
- public function equalsValue(v:int):Boolean
- {
- return value == v;
- }
-
- public function toString():String
- {
- return String(value);
- }
-
- public function toInt():int
- {
- return value;
- }
-}
-
-/**
- * the aac profile, for ADTS(HLS/TS)
- * @see https://github.com/winlinvip/simple-rtmp-server/issues/310
- */
-class SrsAacProfile extends SrsEnum
-{
- public function SrsAacProfile(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsAacProfile
- {
- switch (v) {
- case 0x00: return SrsAacProfile.Main;
- case 0x01: return SrsAacProfile.LC;
- case 0x02: return SrsAacProfile.SSR;
- default: case 0x03: return SrsAacProfile.Reserved;
- }
- }
-
- public static const Reserved:SrsAacProfile = new SrsAacProfile(0x03);
-
- // @see 7.1 Profiles, aac-iso-13818-7.pdf, page 40
- public static const Main:SrsAacProfile = new SrsAacProfile(0x00);
- public static const LC:SrsAacProfile = new SrsAacProfile(0x01);
- public static const SSR:SrsAacProfile = new SrsAacProfile(0x02);
-
- // ts/hls/adts audio header profile to RTMP sequence header object type.
- public function toRtmpObjectType():SrsAacObjectType
- {
- if (SrsAacProfile.Main.equals(this)) {
- return SrsAacObjectType.AacMain;
- } else if (SrsAacProfile.LC.equals(this)) {
- return SrsAacObjectType.AacLC;
- } else if (SrsAacProfile.SSR.equals(this)) {
- return SrsAacObjectType.AacSSR;
- } else {
- return SrsAacObjectType.Reserved;
- }
- }
-};
-
-/**
- * the aac object type, for RTMP sequence header
- * for AudioSpecificConfig, @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33
- * for audioObjectType, @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23
- */
-class SrsAacObjectType extends SrsEnum
-{
- public function SrsAacObjectType(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsAacObjectType
- {
- switch (v) {
- case 0x01: return SrsAacObjectType.AacMain;
- case 0x02: return SrsAacObjectType.AacLC;
- case 0x03: return SrsAacObjectType.AacSSR;
- case 0x05: return SrsAacObjectType.AacHE;
- case 0x29: return SrsAacObjectType.AacHEV2;
- default: case 0x00: return SrsAacObjectType.Reserved;
- }
- }
-
- public static const Reserved:SrsAacObjectType = new SrsAacObjectType(0x00);
-
- // Table 1.1 – Audio Object Type definition
- // @see @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23
- public static const AacMain:SrsAacObjectType = new SrsAacObjectType(0x01);
- public static const AacLC:SrsAacObjectType = new SrsAacObjectType(0x02);
- public static const AacSSR:SrsAacObjectType = new SrsAacObjectType(0x03);
-
- // AAC HE = LC+SBR
- public static const AacHE:SrsAacObjectType = new SrsAacObjectType(0x05);
- // AAC HEv2 = LC+SBR+PS
- public static const AacHEV2:SrsAacObjectType = new SrsAacObjectType(0x29);
-
- // RTMP sequence header object type to ts/hls/adts audio header profile.
- public function toTsProfile():SrsAacProfile
- {
- if (SrsAacObjectType.AacMain.equals(this)) {
- return SrsAacProfile.Main;
- } else if (SrsAacObjectType.AacLC.equals(this)) {
- return SrsAacProfile.LC;
- } else if (SrsAacObjectType.AacHE.equals(this)) {
- return SrsAacProfile.LC;
- } else if (SrsAacObjectType.AacHEV2.equals(this)) {
- return SrsAacProfile.LC;
- } else if (SrsAacObjectType.AacSSR.equals(this)) {
- return SrsAacProfile.SSR;
- } else {
- return SrsAacProfile.Reserved;
- }
- }
-};
-
-/**
- * the pid of ts packet,
- * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37
- * NOTE - The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR.
- */
-class SrsTsPid extends SrsEnum
-{
- public function SrsTsPid(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsPid
- {
- switch (v) {
- case 0x00: return SrsTsPid.PAT;
- case 0x01: return SrsTsPid.CAT;
- case 0x02: return SrsTsPid.TSDT;
- case 0x03: return SrsTsPid.ReservedStart;
- case 0x0f: return SrsTsPid.ReservedEnd;
- case 0x10: return SrsTsPid.AppStart;
- case 0x1ffe: return SrsTsPid.AppEnd;
- case 0x01FFF: return SrsTsPid.NULL;
- default: return new SrsTsPid(v);
- }
- }
-
- // Program Association Table(see Table 2-25).
- public static const PAT:SrsTsPid = new SrsTsPid(0x00);
- // Conditional Access Table (see Table 2-27).
- public static const CAT:SrsTsPid = new SrsTsPid(0x01);
- // Transport Stream Description Table
- public static const TSDT:SrsTsPid = new SrsTsPid(0x02);
- // Reserved
- public static const ReservedStart:SrsTsPid = new SrsTsPid(0x03);
- public static const ReservedEnd:SrsTsPid = new SrsTsPid(0x0f);
- // May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes
- public static const AppStart:SrsTsPid = new SrsTsPid(0x10);
- public static const AppEnd:SrsTsPid = new SrsTsPid(0x1ffe);
- // null packets (see Table 2-3)
- public static const NULL:SrsTsPid = new SrsTsPid(0x01FFF);
-};
-
-/**
- * the transport_scrambling_control of ts packet,
- * Table 2-4 - Scrambling control values, hls-mpeg-ts-iso13818-1.pdf, page 38
- */
-class SrsTsScrambled extends SrsEnum
-{
- public function SrsTsScrambled(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsScrambled
- {
- switch (v) {
- case 0x01: return SrsTsScrambled.UserDefined1;
- case 0x02: return SrsTsScrambled.UserDefined2;
- case 0x03: return SrsTsScrambled.UserDefined3;
- default: case 0x00: return SrsTsScrambled.Disabled;
- }
- }
-
- // Not scrambled
- public static const Disabled:SrsTsScrambled = new SrsTsScrambled(0x00);
- // User-defined
- public static const UserDefined1:SrsTsScrambled = new SrsTsScrambled(0x01);
- // User-defined
- public static const UserDefined2:SrsTsScrambled = new SrsTsScrambled(0x02);
- // User-defined
- public static const UserDefined3:SrsTsScrambled = new SrsTsScrambled(0x03);
-};
-
-/**
- * the adaption_field_control of ts packet,
- * Table 2-5 - Adaptation field control values, hls-mpeg-ts-iso13818-1.pdf, page 38
- */
-class SrsTsAdaptationFieldType extends SrsEnum
-{
- public function SrsTsAdaptationFieldType(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsAdaptationFieldType
- {
- switch (v) {
- case 0x01: return SrsTsAdaptationFieldType.PayloadOnly;
- case 0x02: return SrsTsAdaptationFieldType.AdaptionOnly;
- case 0x03: return SrsTsAdaptationFieldType.Both;
- default: case 0x00: return SrsTsAdaptationFieldType.Reserved;
- }
- }
-
- // Reserved for future use by ISO/IEC
- public static const Reserved:SrsTsAdaptationFieldType = new SrsTsAdaptationFieldType(0x00);
- // No adaptation_field, payload only
- public static const PayloadOnly:SrsTsAdaptationFieldType = new SrsTsAdaptationFieldType(0x01);
- // Adaptation_field only, no payload
- public static const AdaptionOnly:SrsTsAdaptationFieldType = new SrsTsAdaptationFieldType(0x02);
- // Adaptation_field followed by payload
- public static const Both:SrsTsAdaptationFieldType = new SrsTsAdaptationFieldType(0x03);
-};
-
-/**
- * the actually parsed ts pid,
- * @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables.
- */
-class SrsTsPidApply extends SrsEnum
-{
- public function SrsTsPidApply(v:int)
- {
- super(v);
- }
-
- public static const Reserved:SrsTsPidApply = new SrsTsPidApply(0x00); // TSPidTypeReserved, nothing parsed, used reserved.
- public static const PAT:SrsTsPidApply = new SrsTsPidApply(0x01); // Program associtate table
- public static const PMT:SrsTsPidApply = new SrsTsPidApply(0x02); // Program map table.
-
- public static const Video:SrsTsPidApply = new SrsTsPidApply(0x03); // for video
- public static const Audio:SrsTsPidApply = new SrsTsPidApply(0x04); // vor audio
-};
-
-/**
- * Table 2-29 - Stream type assignments
- */
-class SrsTsStream extends SrsEnum
-{
- public function SrsTsStream(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsStream
- {
- switch (v) {
- case 0x8a: return SrsTsStream.AudioDTS;
- case 0x80: return SrsTsStream.AudioAC3;
- case 0x1b: return SrsTsStream.VideoH264;
- case 0x11: return SrsTsStream.AudioMpeg4;
- case 0x10: return SrsTsStream.VideoMpeg4;
- case 0x0f: return SrsTsStream.AudioAAC;
- case 0x04: return SrsTsStream.AudioMp3;
- default: case 0x00: return SrsTsStream.Reserved;
- }
- }
-
- // ITU-T | ISO/IEC Reserved
- public static const Reserved:SrsTsStream = new SrsTsStream(0x00);
- // ISO/IEC 11172 Video
- // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
- // ISO/IEC 11172 Audio
- // ISO/IEC 13818-3 Audio
- public static const AudioMp3:SrsTsStream = new SrsTsStream(0x04);
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
- // ISO/IEC 13522 MHEG
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC
- // ITU-T Rec. H.222.1
- // ISO/IEC 13818-6 type A
- // ISO/IEC 13818-6 type B
- // ISO/IEC 13818-6 type C
- // ISO/IEC 13818-6 type D
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary
- // ISO/IEC 13818-7 Audio with ADTS transport syntax
- public static const AudioAAC:SrsTsStream = new SrsTsStream(0x0f);
- // ISO/IEC 14496-2 Visual
- public static const VideoMpeg4:SrsTsStream = new SrsTsStream(0x10);
- // ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1
- public static const AudioMpeg4:SrsTsStream = new SrsTsStream(0x11);
- // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
- // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections.
- // ISO/IEC 13818-6 Synchronized Download Protocol
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved
- // 0x15-0x7F
- public static const VideoH264:SrsTsStream = new SrsTsStream(0x1b);
- // User Private
- // 0x80-0xFF
- public static const AudioAC3:SrsTsStream = new SrsTsStream(0x80);
- public static const AudioDTS:SrsTsStream = new SrsTsStream(0x8a);
-};
-
-/**
- * the ts channel.
- */
-class SrsTsChannel
-{
- public var pid:int;
- public var apply:SrsTsPidApply;
- public var stream:SrsTsStream;
- public var msg:SrsTsMessage;
- public var context:SrsTsContext;
-
- public function SrsTsChannel()
- {
- pid = 0;
- apply = SrsTsPidApply.Reserved;
- stream = SrsTsStream.Reserved;
- msg = null;
- context = null;
- }
-};
-
-/**
- * the stream_id of PES payload of ts packet.
- * Table 2-18 – Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52.
- */
-class SrsTsPESStreamId extends SrsEnum
-{
- public function SrsTsPESStreamId(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsPESStreamId
- {
- switch (v) {
- case 0xbc: return SrsTsPESStreamId.ProgramStreamMap;
- case 0xbd: return SrsTsPESStreamId.PrivateStream1;
- case 0xbe: return SrsTsPESStreamId.PaddingStream;
- case 0xbf: return SrsTsPESStreamId.PrivateStream2;
- case 0x06: return SrsTsPESStreamId.AudioChecker;
- case 0xc0: return SrsTsPESStreamId.AudioCommon;
- case 0x0e: return SrsTsPESStreamId.VideoChecker;
- case 0xe0: return SrsTsPESStreamId.VideoCommon;
- case 0xf0: return SrsTsPESStreamId.EcmStream;
- case 0xf1: return SrsTsPESStreamId.EmmStream;
- case 0xf2: return SrsTsPESStreamId.DsmccStream;
- case 0xf3: return SrsTsPESStreamId._13522Stream;
- case 0xf4: return SrsTsPESStreamId.H2221TypeA;
- case 0xf5: return SrsTsPESStreamId.H2221TypeB;
- case 0xf6: return SrsTsPESStreamId.H2221TypeC;
- case 0xf7: return SrsTsPESStreamId.H2221TypeD;
- case 0xf8: return SrsTsPESStreamId.H2221TypeE;
- case 0xf9: return SrsTsPESStreamId.AncillaryStream;
- case 0xfa: return SrsTsPESStreamId.SlPacketizedStream;
- case 0xfb: return SrsTsPESStreamId.FlexMuxStream;
- case 0xff: return SrsTsPESStreamId.ProgramStreamDirectory;
- default: case 0x00: return SrsTsPESStreamId.Reserved;
- }
- }
-
- // reserved
- public static const Reserved:SrsTsPESStreamId = new SrsTsPESStreamId(0x00);
-
- // program_stream_map
- public static const ProgramStreamMap:SrsTsPESStreamId = new SrsTsPESStreamId(0xbc);
- // private_stream_1
- public static const PrivateStream1:SrsTsPESStreamId = new SrsTsPESStreamId(0xbd);
- // padding_stream
- public static const PaddingStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xbe);
- // private_stream_2
- public static const PrivateStream2:SrsTsPESStreamId = new SrsTsPESStreamId(0xbf);
-
- // 110x xxxx
- // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
- // 14496-3 audio stream number x xxxx
- // ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
- // @remark, use SrsTsPESStreamIdAudioCommon as actually audio, SrsTsPESStreamIdAudio to check whether audio.
- public static const AudioChecker:SrsTsPESStreamId = new SrsTsPESStreamId(0x06);
- public static const AudioCommon:SrsTsPESStreamId = new SrsTsPESStreamId(0xc0);
-
- // 1110 xxxx
- // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
- // 14496-2 video stream number xxxx
- // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
- // @remark, use SrsTsPESStreamIdVideoCommon as actually video, SrsTsPESStreamIdVideo to check whether video.
- public static const VideoChecker:SrsTsPESStreamId = new SrsTsPESStreamId(0x0e);
- public static const VideoCommon:SrsTsPESStreamId = new SrsTsPESStreamId(0xe0);
-
- // ECM_stream
- public static const EcmStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xf0);
- // EMM_stream
- public static const EmmStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xf1);
- // DSMCC_stream
- public static const DsmccStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xf2);
- // 13522_stream
- public static const _13522Stream:SrsTsPESStreamId = new SrsTsPESStreamId(0xf3);
- // H_222_1_type_A
- public static const H2221TypeA:SrsTsPESStreamId = new SrsTsPESStreamId(0xf4);
- // H_222_1_type_B
- public static const H2221TypeB:SrsTsPESStreamId = new SrsTsPESStreamId(0xf5);
- // H_222_1_type_C
- public static const H2221TypeC:SrsTsPESStreamId = new SrsTsPESStreamId(0xf6);
- // H_222_1_type_D
- public static const H2221TypeD:SrsTsPESStreamId = new SrsTsPESStreamId(0xf7);
- // H_222_1_type_E
- public static const H2221TypeE:SrsTsPESStreamId = new SrsTsPESStreamId(0xf8);
- // ancillary_stream
- public static const AncillaryStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xf9);
- // SL_packetized_stream
- public static const SlPacketizedStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xfa);
- // FlexMux_stream
- public static const FlexMuxStream:SrsTsPESStreamId = new SrsTsPESStreamId(0xfb);
- // reserved data stream
- // 1111 1100 … 1111 1110
- // program_stream_directory
- public static const ProgramStreamDirectory:SrsTsPESStreamId = new SrsTsPESStreamId(0xff);
-};
-
-/**
- * the media audio/video message parsed from PES packet.
- */
-class SrsTsMessage
-{
- // decoder only,
- // the ts messgae does not use them,
- // for user to get the channel and packet.
- public var channel:SrsTsChannel;
- public var packet:SrsTsPacket;
- // the audio cache buffer start pts, to flush audio if full.
- // @remark the pts is not the adjust one, it's the orignal pts.
- public var start_pts:Number;
- // whether this message with pcr info,
- // generally, the video IDR(I frame, the keyframe of h.264) carray the pcr info.
- public var write_pcr:Boolean;
- // whether got discontinuity ts, for example, sequence header changed.
- public var discontinuity:Boolean;
- // the timestamp in 90khz
- public var dts:Number;
- public var pts:Number;
- // the id of pes stream to indicates the payload codec.
- // @remark use is_audio() and is_video() to check it, and stream_number() to finger it out.
- public var sid:SrsTsPESStreamId;
- // the size of payload, 0 indicates the length() of payload.
- public var PES_packet_length:uint;
- // the chunk id.
- public var continuity_counter:uint;
- // the payload bytes.
- public var payload:ByteArray;
-
- public function SrsTsMessage(c:SrsTsChannel, p:SrsTsPacket)
- {
- channel = c;
- packet = p;
-
- dts = pts = 0;
- sid = SrsTsPESStreamId.Reserved;
- continuity_counter = 0;
- PES_packet_length = 0;
- payload = new ByteArray();
-
- start_pts = 0;
- write_pcr = false;
- }
-
- // decoder
- /**
- * dumps all bytes in stream to ts message.
- */
- public function dump(stream:ByteArray):int
- {
- if (!stream.bytesAvailable) {
- return 0;
- }
-
- // xB
- var nb_bytes:int = stream.length - stream.position;
- if (PES_packet_length > 0) {
- nb_bytes = (int)(Math.min(nb_bytes, PES_packet_length - payload.length));
- }
-
- if (nb_bytes > 0) {
- if (stream.bytesAvailable < nb_bytes) {
- throw new Error("ts: dump PSE bytes failed, requires=" + nb_bytes + " bytes");
- }
-
- stream.readBytes(payload, payload.length, nb_bytes);
- }
-
- return nb_bytes;
- }
- /**
- * whether ts message is completed to reap.
- * @param payload_unit_start_indicator whether new ts message start.
- * PES_packet_length is 0, the payload_unit_start_indicator=1 to reap ts message.
- * PES_packet_length > 0, the payload.length() == PES_packet_length to reap ts message.
- * @remark when PES_packet_length>0, the payload_unit_start_indicator should never be 1 when not completed.
- * @remark when fresh, the payload_unit_start_indicator should be 1.
- */
- public function completed(payload_unit_start_indicator:Number):Boolean
- {
- if (PES_packet_length == 0) {
- return payload_unit_start_indicator != 0;
- }
- return payload.length >= PES_packet_length;
- }
- /**
- * whether the message is fresh.
- */
- public function fresh():Boolean
- {
- return payload.length == 0;
- }
-
- /**
- * whether the sid indicates the elementary stream audio.
- */
- public function is_audio():Boolean
- {
- var sidValue:int = (sid.toInt() >> 5) & 0x07;
- return SrsTsPESStreamId.AudioChecker.equalsValue(sidValue);
- }
- /**
- * whether the sid indicates the elementary stream video.
- */
- public function is_video():Boolean
- {
- var sidValue:int = (sid.toInt() >> 4) & 0x0f;
- return SrsTsPESStreamId.VideoChecker.equalsValue(sidValue);
- }
- /**
- * when audio or video, get the stream number which specifies the format of stream.
- * @return the stream number for audio/video; otherwise, -1.
- */
- public function stream_number():Number
- {
- if (is_audio()) {
- return sid.toInt() & 0x1f;
- } else if (is_video()) {
- return sid.toInt() & 0x0f;
- }
- return -1;
- }
-};
-
-/**
- * the ts message handler.
- */
-interface ISrsTsHandler
-{
- /**
- * when ts context got message, use handler to process it.
- * @param msg the ts msg, user should never free it.
- * @return an int error code.
- */
- function on_ts_message(msg:SrsTsMessage):void;
-};
-
-/**
- * the context of ts, to decode the ts stream.
- */
-class SrsTsContext
-{
- private var _hls:HlsCodec;
-
- // codec
- // key, a Number indicates the pid,
- // value, the SrsTsChannel object.
- private var _pids:Dict;
-
- // whether hls pure audio stream.
- private var _pure_audio:Boolean;
-
- public function SrsTsContext(hls:HlsCodec)
- {
- _hls = hls;
- _pure_audio = false;
- _pids = new Dict();
- }
-
- /**
- * whether the hls stream is pure audio stream.
- */
- public function is_pure_audio():Boolean
- {
- return _pure_audio;
- }
-
- /**
- * when PMT table parsed, we know some info about stream.
- */
- public function on_pmt_parsed():void
- {
- _pure_audio = true;
-
- var keys:Array = _pids.keys();
- for (var i:int = 0; i < keys.length; i++) {
- var channel:SrsTsChannel = _pids.get(keys[i]) as SrsTsChannel;
- if (channel.apply == SrsTsPidApply.Video) {
- _pure_audio = false;
- }
- }
- }
-
- // codec
- /**
- * get the pid apply, the parsed pid.
- * @return the apply channel; NULL for invalid.
- */
- public function getChannel(pid:Number):SrsTsChannel
- {
- if (!_pids.has(pid)) {
- return null;
- }
- return _pids.get(pid) as SrsTsChannel;
- }
-
- /**
- * set the pid apply, the parsed pid.
- */
- public function setChannel(pid:Number, apply_pid:SrsTsPidApply, stream:SrsTsStream):void
- {
- var channel:SrsTsChannel = null;
- if (!_pids.get(pid)) {
- channel = new SrsTsChannel();
- channel.context = this;
- _pids.set(pid, channel);
- } else {
- channel = _pids.get(pid) as SrsTsChannel;
- }
-
- channel.pid = pid;
- channel.apply = apply_pid;
- channel.stream = stream;
- }
-
- // decode methods
- /**
- * the stream contains only one ts packet.
- * @param handler the ts message handler to process the msg.
- * @remark we will consume all bytes in stream.
- */
- public function decode(stream:ByteArray, handler:ISrsTsHandler):void
- {
- // parse util EOF of stream.
- // for example, parse multiple times for the PES_packet_length(0) packet.
- while (stream.bytesAvailable) {
- var packet:SrsTsPacket = new SrsTsPacket(this);
- var msg:SrsTsMessage = packet.decode(stream);
-
- if (!msg) {
- continue;
- }
-
- handler.on_ts_message(msg);
- }
- }
-};
-
-/**
- * the packet in ts stream,
- * 2.4.3.2 Transport Stream packet layer, hls-mpeg-ts-iso13818-1.pdf, page 36
- * Transport Stream packets shall be 188 bytes long.
- */
-class SrsTsPacket
-{
- // 1B
- /**
- * The sync_byte is a fixed 8-bit field whose value is '0100 0111' (0x47) or '0111 0100' (0x74). Sync_byte emulation in the choice of
- * values for other regularly occurring fields, such as PID, should be avoided.
- */
- public var sync_byte:int; //8bits
-
- // 2B
- /**
- * The transport_error_indicator is a 1-bit flag. When set to '1' it indicates that at least
- * 1 uncorrectable bit error exists in the associated Transport Stream packet. This bit may be set to '1' by entities external to
- * the transport layer. When set to '1' this bit shall not be reset to '0' unless the bit value(s) in error have been corrected.
- */
- public var transport_error_indicator:int; //1bit
- /**
- * The payload_unit_start_indicator is a 1-bit flag which has normative meaning for
- * Transport Stream packets that carry PES packets (refer to 2.4.3.6) or PSI data (refer to 2.4.4).
- *
- * When the payload of the Transport Stream packet contains PES packet data, the payload_unit_start_indicator has the
- * following significance: a '1' indicates that the payload of this Transport Stream packet will commence(start) with the first byte
- * of a PES packet and a '0' indicates no PES packet shall start in this Transport Stream packet. If the
- * payload_unit_start_indicator is set to '1', then one and only one PES packet starts in this Transport Stream packet. This
- * also applies to private streams of stream_type 6 (refer to Table 2-29).
- *
- * When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following
- * significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value
- * shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the
- * Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0',
- * indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of
- * stream_type 5 (refer to Table 2-29).
- *
- * For null packets the payload_unit_start_indicator shall be set to '0'.
- *
- * The meaning of this bit for Transport Stream packets carrying only private data is not defined in this Specification.
- */
- public var payload_unit_start_indicator:int; //1bit
- /**
- * The transport_priority is a 1-bit indicator. When set to '1' it indicates that the associated packet is
- * of greater priority than other packets having the same PID which do not have the bit set to '1'. The transport mechanism
- * can use this to prioritize its data within an elementary stream. Depending on the application the transport_priority field
- * may be coded regardless of the PID or within one PID only. This field may be changed by channel specific encoders or
- * decoders.
- */
- public var transport_priority:int; //1bit
- /**
- * The PID is a 13-bit field, indicating the type of the data stored in the packet payload. PID value 0x0000 is
- * reserved for the Program Association Table (see Table 2-25). PID value 0x0001 is reserved for the Conditional Access
- * Table (see Table 2-27). PID values 0x0002 - 0x000F are reserved. PID value 0x1FFF is reserved for null packets (see
- * Table 2-3).
- */
- public var pid:int; //13bits
-
- // 1B
- /**
- * This 2-bit field indicates the scrambling mode of the Transport Stream packet payload.
- * The Transport Stream packet header, and the adaptation field when present, shall not be scrambled. In the case of a null
- * packet the value of the transport_scrambling_control field shall be set to '00' (see Table 2-4).
- */
- public var transport_scrambling_control:SrsTsScrambled; //2bits
- /**
- * This 2-bit field indicates whether this Transport Stream packet header is followed by an
- * adaptation field and/or payload (see Table 2-5).
- *
- * ITU-T Rec. H.222.0 | ISO/IEC 13818-1 decoders shall discard Transport Stream packets with the
- * adaptation_field_control field set to a value of '00'. In the case of a null packet the value of the adaptation_field_control
- * shall be set to '01'.
- */
- public var adaption_field_control:SrsTsAdaptationFieldType; //2bits
- /**
- * The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the
- * same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be
- * incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only).
- *
- * In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the
- * same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the
- * adaptation_field_control field shall be equal to '01'(payload only) or '11'(both). In duplicate packets each byte of the original packet shall be
- * duplicated, with the exception that in the program clock reference fields, if present, a valid value shall be encoded.
- *
- * The continuity_counter in a particular Transport Stream packet is continuous when it differs by a positive value of one
- * from the continuity_counter value in the previous Transport Stream packet of the same PID, or when either of the nonincrementing
- * conditions (adaptation_field_control set to '00' or '10', or duplicate packets as described above) are met.
- * The continuity counter may be discontinuous when the discontinuity_indicator is set to '1' (refer to 2.4.3.4). In the case of
- * a null packet the value of the continuity_counter is undefined.
- */
- public var continuity_counter:int; //4bits
-
- private var adaptation_field:SrsTsAdaptationField;
- private var payload:SrsTsPayload;
-
- public var context:SrsTsContext;
-
- public function SrsTsPacket(c:SrsTsContext)
- {
- context = c;
- }
-
- public function decode(stream:ByteArray):SrsTsMessage
- {
- var pos:uint = stream.position;
-
- // 4B ts packet header.
- if (stream.bytesAvailable < 4) {
- throw new Error("ts: demux header failed");
- }
-
- sync_byte = stream.readUnsignedByte();
- // drm algorithms for ts packet:
- // 1: "tiger", sync_byte is 0x74
- if (sync_byte != 0x47 && sync_byte != 0x74) {
- throw new Error("ts: sync_bytes must be 0x47 or 0x74, actual=" + sync_byte);
- }
-
- var pidv:int = stream.readUnsignedShort();
- transport_error_indicator = (pidv >> 15) & 0x01;
- payload_unit_start_indicator = (pidv >> 14) & 0x01;
- transport_priority = (pidv >> 13) & 0x01;
- pid = pidv & 0x1FFF;
-
- var ccv:int = stream.readUnsignedByte();
- transport_scrambling_control = SrsTsScrambled.parse((ccv >> 6) & 0x03);
- adaption_field_control = SrsTsAdaptationFieldType.parse((ccv >> 4) & 0x03);
- continuity_counter = ccv & 0x0F;
-
- // TODO: FIXME: create pids map when got new pid.
-
- // optional: adaptation field
- if (adaption_field_control == SrsTsAdaptationFieldType.AdaptionOnly
- || adaption_field_control == SrsTsAdaptationFieldType.Both
- ) {
- adaptation_field = new SrsTsAdaptationField(this);
- adaptation_field.decode(stream);
- }
-
- // calc the user defined data size for payload.
- var nb_payload:int = HlsCodec.SRS_TS_PACKET_SIZE - (stream.position - pos);
-
- // optional: payload.
- if (adaption_field_control == SrsTsAdaptationFieldType.PayloadOnly
- || adaption_field_control == SrsTsAdaptationFieldType.Both
- ) {
- if (SrsTsPid.PAT.equalsValue(pid)) {
- // 2.4.4.3 Program association Table
- payload = new SrsTsPayloadPAT(this);
- } else {
- var channel:SrsTsChannel = context.getChannel(pid);
- if (channel && channel.apply == SrsTsPidApply.PMT) {
- // 2.4.4.8 Program Map Table
- payload = new SrsTsPayloadPMT(this);
- } else if (channel && (channel.apply == SrsTsPidApply.Video || channel.apply == SrsTsPidApply.Audio)) {
- // 2.4.3.6 PES packet
- payload = new SrsTsPayloadPES(this);
- } else {
- // left bytes as reserved.
- stream.position += nb_payload;
- }
- }
-
- if (payload) {
- return payload.decode(stream);
- }
- }
-
- return null;
- }
- public function size():int
- {
- return 0;
- }
-
- public static function create_pat(context:SrsTsContext, pmt_number:int, pmt_pid:int):SrsTsPacket
- {
- return null;
- }
- public static function create_pmt(context:SrsTsContext,
- pmt_number:int, pmt_pid:int, vpid:int, vs:SrsTsStream, apid:int, ts:SrsTsStream):SrsTsPacket
- {
- return null;
- }
- public static function create_pes_first(context:SrsTsContext,
- pid:int, sid:SrsTsPESStreamId, continuity_counter:uint, discontinuity:Boolean,
- pcr:Number, dts:Number, pts:Number, size:int):SrsTsPacket
- {
- return null;
- }
- public static function create_pes_continue(context:SrsTsContext,
- pid:int, sid:SrsTsPESStreamId, continuity_counter:int
- ):SrsTsPacket
- {
- return null;
- }
-};
-
-/**
- * the adaption field of ts packet.
- * 2.4.3.5 Semantic definition of fields in adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 39
- * Table 2-6 - Transport Stream adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 40
- */
-class SrsTsAdaptationField
-{
- // 1B
- /**
- * The adaptation_field_length is an 8-bit field specifying the number of bytes in the
- * adaptation_field immediately following the adaptation_field_length. The value 0 is for inserting a single stuffing byte in
- * a Transport Stream packet. When the adaptation_field_control value is '11', the value of the adaptation_field_length shall
- * be in the range 0 to 182. When the adaptation_field_control value is '10', the value of the adaptation_field_length shall
- * be 183. For Transport Stream packets carrying PES packets, stuffing is needed when there is insufficient PES packet data
- * to completely fill the Transport Stream packet payload bytes. Stuffing is accomplished by defining an adaptation field
- * longer than the sum of the lengths of the data elements in it, so that the payload bytes remaining after the adaptation field
- * exactly accommodates the available PES packet data. The extra space in the adaptation field is filled with stuffing bytes.
- *
- * This is the only method of stuffing allowed for Transport Stream packets carrying PES packets. For Transport Stream
- * packets carrying PSI, an alternative stuffing method is described in 2.4.4.
- */
- public var adaption_field_length:int; //8bits
- // 1B
- /**
- * This is a 1-bit field which when set to '1' indicates that the discontinuity state is true for the
- * current Transport Stream packet. When the discontinuity_indicator is set to '0' or is not present, the discontinuity state is
- * false. The discontinuity indicator is used to indicate two types of discontinuities, system time-base discontinuities and
- * continuity_counter discontinuities.
- *
- * A system time-base discontinuity is indicated by the use of the discontinuity_indicator in Transport Stream packets of a
- * PID designated as a PCR_PID (refer to 2.4.4.9). When the discontinuity state is true for a Transport Stream packet of a
- * PID designated as a PCR_PID, the next PCR in a Transport Stream packet with that same PID represents a sample of a
- * new system time clock for the associated program. The system time-base discontinuity point is defined to be the instant
- * in time when the first byte of a packet containing a PCR of a new system time-base arrives at the input of the T-STD.
- * The discontinuity_indicator shall be set to '1' in the packet in which the system time-base discontinuity occurs. The
- * discontinuity_indicator bit may also be set to '1' in Transport Stream packets of the same PCR_PID prior to the packet
- * which contains the new system time-base PCR. In this case, once the discontinuity_indicator has been set to '1', it shall
- * continue to be set to '1' in all Transport Stream packets of the same PCR_PID up to and including the Transport Stream
- * packet which contains the first PCR of the new system time-base. After the occurrence of a system time-base
- * discontinuity, no fewer than two PCRs for the new system time-base shall be received before another system time-base
- * discontinuity can occur. Further, except when trick mode status is true, data from no more than two system time-bases
- * shall be present in the set of T-STD buffers for one program at any time.
- *
- * Prior to the occurrence of a system time-base discontinuity, the first byte of a Transport Stream packet which contains a
- * PTS or DTS which refers to the new system time-base shall not arrive at the input of the T-STD. After the occurrence of
- * a system time-base discontinuity, the first byte of a Transport Stream packet which contains a PTS or DTS which refers
- * to the previous system time-base shall not arrive at the input of the T-STD.
- *
- * A continuity_counter discontinuity is indicated by the use of the discontinuity_indicator in any Transport Stream packet.
- * When the discontinuity state is true in any Transport Stream packet of a PID not designated as a PCR_PID, the
- * continuity_counter in that packet may be discontinuous with respect to the previous Transport Stream packet of the same
- * PID. When the discontinuity state is true in a Transport Stream packet of a PID that is designated as a PCR_PID, the
- * continuity_counter may only be discontinuous in the packet in which a system time-base discontinuity occurs. A
- * continuity counter discontinuity point occurs when the discontinuity state is true in a Transport Stream packet and the
- * continuity_counter in the same packet is discontinuous with respect to the previous Transport Stream packet of the same
- * PID. A continuity counter discontinuity point shall occur at most one time from the initiation of the discontinuity state
- * until the conclusion of the discontinuity state. Furthermore, for all PIDs that are not designated as PCR_PIDs, when the
- * discontinuity_indicator is set to '1' in a packet of a specific PID, the discontinuity_indicator may be set to '1' in the next
- * Transport Stream packet of that same PID, but shall not be set to '1' in three consecutive Transport Stream packet of that
- * same PID.
- *
- * For the purpose of this clause, an elementary stream access point is defined as follows:
- * Video - The first byte of a video sequence header.
- * Audio - The first byte of an audio frame.
- *
- * After a continuity counter discontinuity in a Transport packet which is designated as containing elementary stream data,
- * the first byte of elementary stream data in a Transport Stream packet of the same PID shall be the first byte of an
- * elementary stream access point or in the case of video, the first byte of an elementary stream access point or a
- * sequence_end_code followed by an access point. Each Transport Stream packet which contains elementary stream data
- * with a PID not designated as a PCR_PID, and in which a continuity counter discontinuity point occurs, and in which a
- * PTS or DTS occurs, shall arrive at the input of the T-STD after the system time-base discontinuity for the associated
- * program occurs. In the case where the discontinuity state is true, if two consecutive Transport Stream packets of the same
- * PID occur which have the same continuity_counter value and have adaptation_field_control values set to '01' or '11', the
- * second packet may be discarded. A Transport Stream shall not be constructed in such a way that discarding such a packet
- * will cause the loss of PES packet payload data or PSI data.
- *
- * After the occurrence of a discontinuity_indicator set to '1' in a Transport Stream packet which contains PSI information,
- * a single discontinuity in the version_number of PSI sections may occur. At the occurrence of such a discontinuity, a
- * version of the TS_program_map_sections of the appropriate program shall be sent with section_length = = 13 and the
- * current_next_indicator = = 1, such that there are no program_descriptors and no elementary streams described. This shall
- * then be followed by a version of the TS_program_map_section for each affected program with the version_number
- * incremented by one and the current_next_indicator = = 1, containing a complete program definition. This indicates a
- * version change in PSI data.
- */
- public var discontinuity_indicator:int; //1bit
- /**
- * The random_access_indicator is a 1-bit field that indicates that the current Transport
- * Stream packet, and possibly subsequent Transport Stream packets with the same PID, contain some information to aid
- * random access at this point. Specifically, when the bit is set to '1', the next PES packet to start in the payload of Transport
- * Stream packets with the current PID shall contain the first byte of a video sequence header if the PES stream type (refer
- * to Table 2-29) is 1 or 2, or shall contain the first byte of an audio frame if the PES stream type is 3 or 4. In addition, in
- * the case of video, a presentation timestamp shall be present in the PES packet containing the first picture following the
- * sequence header. In the case of audio, the presentation timestamp shall be present in the PES packet containing the first
- * byte of the audio frame. In the PCR_PID the random_access_indicator may only be set to '1' in Transport Stream packet
- * containing the PCR fields.
- */
- public var random_access_indicator:int; //1bit
- /**
- * The elementary_stream_priority_indicator is a 1-bit field. It indicates, among
- * packets with the same PID, the priority of the elementary stream data carried within the payload of this Transport Stream
- * packet. A '1' indicates that the payload has a higher priority than the payloads of other Transport Stream packets. In the
- * case of video, this field may be set to '1' only if the payload contains one or more bytes from an intra-coded slice. A
- * value of '0' indicates that the payload has the same priority as all other packets which do not have this bit set to '1'.
- */
- public var elementary_stream_priority_indicator:int; //1bit
- /**
- * The PCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains a PCR field coded in
- * two parts. A value of '0' indicates that the adaptation field does not contain any PCR field.
- */
- public var PCR_flag:int; //1bit
- /**
- * The OPCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains an OPCR field
- * coded in two parts. A value of '0' indicates that the adaptation field does not contain any OPCR field.
- */
- public var OPCR_flag:int; //1bit
- /**
- * The splicing_point_flag is a 1-bit flag. When set to '1', it indicates that a splice_countdown field
- * shall be present in the associated adaptation field, specifying the occurrence of a splicing point. A value of '0' indicates
- * that a splice_countdown field is not present in the adaptation field.
- */
- public var splicing_point_flag:int; //1bit
- /**
- * The transport_private_data_flag is a 1-bit flag. A value of '1' indicates that the
- * adaptation field contains one or more private_data bytes. A value of '0' indicates the adaptation field does not contain any
- * private_data bytes.
- */
- public var transport_private_data_flag:int; //1bit
- /**
- * The adaptation_field_extension_flag is a 1-bit field which when set to '1' indicates
- * the presence of an adaptation field extension. A value of '0' indicates that an adaptation field extension is not present in
- * the adaptation field.
- */
- public var adaptation_field_extension_flag:int; //1bit
-
- // if PCR_flag, 6B
- /**
- * The program_clock_reference (PCR) is a
- * 42-bit field coded in two parts. The first part, program_clock_reference_base, is a 33-bit field whose value is given by
- * PCR_base(i), as given in equation 2-2. The second part, program_clock_reference_extension, is a 9-bit field whose value
- * is given by PCR_ext(i), as given in equation 2-3. The PCR indicates the intended time of arrival of the byte containing
- * the last bit of the program_clock_reference_base at the input of the system target decoder.
- */
- public var program_clock_reference_base:Number; //33bits
- /**
- * 6bits reserved, must be '1'
- */
- public var const1_value0:int; // 6bits
- public var program_clock_reference_extension:int; //9bits
-
- // if OPCR_flag, 6B
- /**
- * The optional original
- * program reference (OPCR) is a 42-bit field coded in two parts. These two parts, the base and the extension, are coded
- * identically to the two corresponding parts of the PCR field. The presence of the OPCR is indicated by the OPCR_flag.
- * The OPCR field shall be coded only in Transport Stream packets in which the PCR field is present. OPCRs are permitted
- * in both single program and multiple program Transport Streams.
- *
- * OPCR assists in the reconstruction of a single program Transport Stream from another Transport Stream. When
- * reconstructing the original single program Transport Stream, the OPCR may be copied to the PCR field. The resulting
- * PCR value is valid only if the original single program Transport Stream is reconstructed exactly in its entirety. This
- * would include at least any PSI and private data packets which were present in the original Transport Stream and would
- * possibly require other private arrangements. It also means that the OPCR must be an identical copy of its associated PCR
- * in the original single program Transport Stream.
- */
- public var original_program_clock_reference_base:Number; //33bits
- /**
- * 6bits reserved, must be '1'
- */
- public var const1_value2:int; // 6bits
- public var original_program_clock_reference_extension:int; //9bits
-
- // if splicing_point_flag, 1B
- /**
- * The splice_countdown is an 8-bit field, representing a value which may be positive or negative. A
- * positive value specifies the remaining number of Transport Stream packets, of the same PID, following the associated
- * Transport Stream packet until a splicing point is reached. Duplicate Transport Stream packets and Transport Stream
- * packets which only contain adaptation fields are excluded. The splicing point is located immediately after the last byte of
- * the Transport Stream packet in which the associated splice_countdown field reaches zero. In the Transport Stream packet
- * where the splice_countdown reaches zero, the last data byte of the Transport Stream packet payload shall be the last byte
- * of a coded audio frame or a coded picture. In the case of video, the corresponding access unit may or may not be
- * terminated by a sequence_end_code. Transport Stream packets with the same PID, which follow, may contain data from
- * a different elementary stream of the same type.
- *
- * The payload of the next Transport Stream packet of the same PID (duplicate packets and packets without payload being
- * excluded) shall commence with the first byte of a PES packet.In the case of audio, the PES packet payload shall
- * commence with an access point. In the case of video, the PES packet payload shall commence with an access point, or
- * with a sequence_end_code, followed by an access point. Thus, the previous coded audio frame or coded picture aligns
- * with the packet boundary, or is padded to make this so. Subsequent to the splicing point, the countdown field may also
- * be present. When the splice_countdown is a negative number whose value is minus n(-n), it indicates that the associated
- * Transport Stream packet is the n-th packet following the splicing point (duplicate packets and packets without payload
- * being excluded).
- *
- * For the purposes of this subclause, an access point is defined as follows:
- * Video - The first byte of a video_sequence_header.
- * Audio - The first byte of an audio frame.
- */
- public var splice_countdown:int; //8bits
-
- // if transport_private_data_flag, 1+p[0] B
- /**
- * The transport_private_data_length is an 8-bit field specifying the number of
- * private_data bytes immediately following the transport private_data_length field. The number of private_data bytes shall
- * not be such that private data extends beyond the adaptation field.
- */
- public var transport_private_data_length:int; //8bits
- public var transport_private_data:ByteArray; //[transport_private_data_length]bytes
-
- // if adaptation_field_extension_flag, 2+x B
- /**
- * The adaptation_field_extension_length is an 8-bit field. It indicates the number of
- * bytes of the extended adaptation field data immediately following this field, including reserved bytes if present.
- */
- public var adaptation_field_extension_length:int; //8bits
- /**
- * This is a 1-bit field which when set to '1' indicates the presence of the ltw_offset
- * field.
- */
- public var ltw_flag:int; //1bit
- /**
- * This is a 1-bit field which when set to '1' indicates the presence of the piecewise_rate field.
- */
- public var piecewise_rate_flag:int; //1bit
- /**
- * This is a 1-bit flag which when set to '1' indicates that the splice_type and DTS_next_AU fields
- * are present. A value of '0' indicates that neither splice_type nor DTS_next_AU fields are present. This field shall not be
- * set to '1' in Transport Stream packets in which the splicing_point_flag is not set to '1'. Once it is set to '1' in a Transport
- * Stream packet in which the splice_countdown is positive, it shall be set to '1' in all the subsequent Transport Stream
- * packets of the same PID that have the splicing_point_flag set to '1', until the packet in which the splice_countdown
- * reaches zero (including this packet). When this flag is set, if the elementary stream carried in this PID is an audio stream,
- * the splice_type field shall be set to '0000'. If the elementary stream carried in this PID is a video stream, it shall fulfil the
- * constraints indicated by the splice_type value.
- */
- public var seamless_splice_flag:int; //1bit
- /**
- * reserved 5bits, must be '1'
- */
- public var const1_value1:int; //5bits
- // if ltw_flag, 2B
- /**
- * (legal time window_valid_flag) - This is a 1-bit field which when set to '1' indicates that the value of the
- * ltw_offset shall be valid. A value of '0' indicates that the value in the ltw_offset field is undefined.
- */
- public var ltw_valid_flag:int; //1bit
- /**
- * (legal time window offset) - This is a 15-bit field, the value of which is defined only if the ltw_valid flag has
- * a value of '1'. When defined, the legal time window offset is in units of (300/fs) seconds, where fs is the system clock
- * frequency of the program that this PID belongs to, and fulfils:
- * offset = t1(i) - t(i)
- * ltw_offset = offset//1
- * where i is the index of the first byte of this Transport Stream packet, offset is the value encoded in this field, t(i) is the
- * arrival time of byte i in the T-STD, and t1(i) is the upper bound in time of a time interval called the Legal Time Window
- * which is associated with this Transport Stream packet.
- */
- public var ltw_offset:int; //15bits
- // if piecewise_rate_flag, 3B
- //2bits reserved
- /**
- * The meaning of this 22-bit field is only defined when both the ltw_flag and the ltw_valid_flag are set
- * to '1'. When defined, it is a positive integer specifying a hypothetical bitrate R which is used to define the end times of
- * the Legal Time Windows of Transport Stream packets of the same PID that follow this packet but do not include the
- * legal_time_window_offset field.
- */
- public var piecewise_rate:int; //22bits
- // if seamless_splice_flag, 5B
- /**
- * This is a 4-bit field. From the first occurrence of this field onwards, it shall have the same value in all the
- * subsequent Transport Stream packets of the same PID in which it is present, until the packet in which the
- * splice_countdown reaches zero (including this packet). If the elementary stream carried in that PID is an audio stream,
- * this field shall have the value '0000'. If the elementary stream carried in that PID is a video stream, this field indicates the
- * conditions that shall be respected by this elementary stream for splicing purposes. These conditions are defined as a
- * function of profile, level and splice_type in Table 2-7 through Table 2-16.
- */
- public var splice_type:int; //4bits
- /**
- * (decoding time stamp next access unit) - This is a 33-bit field, coded in three parts. In the case of
- * continuous and periodic decoding through this splicing point it indicates the decoding time of the first access unit
- * following the splicing point. This decoding time is expressed in the time base which is valid in the Transport Stream
- * packet in which the splice_countdown reaches zero. From the first occurrence of this field onwards, it shall have the
- * same value in all the subsequent Transport Stream packets of the same PID in which it is present, until the packet in
- * which the splice_countdown reaches zero (including this packet).
- */
- public var DTS_next_AU0:int; //3bits
- public var marker_bit0:int; //1bit
- public var DTS_next_AU1:int; //15bits
- public var marker_bit1:int; //1bit
- public var DTS_next_AU2:int; //15bits
- public var marker_bit2:int; //1bit
- // left bytes.
- /**
- * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the
- * decoder.
- */
- public var nb_af_ext_reserved:int;
-
- // left bytes.
- /**
- * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the
- * decoder.
- */
- public var nb_af_reserved:int;
-
- private var packet:SrsTsPacket;
-
- public function SrsTsAdaptationField(pkt:SrsTsPacket)
- {
- packet = pkt;
-
- adaption_field_length = 0;
- discontinuity_indicator = 0;
- random_access_indicator = 0;
- elementary_stream_priority_indicator = 0;
- PCR_flag = 0;
- OPCR_flag = 0;
- splicing_point_flag = 0;
- transport_private_data_flag = 0;
- adaptation_field_extension_flag = 0;
- program_clock_reference_base = 0;
- program_clock_reference_extension = 0;
- original_program_clock_reference_base = 0;
- original_program_clock_reference_extension = 0;
- splice_countdown = 0;
- transport_private_data_length = 0;
- transport_private_data = null;
- adaptation_field_extension_length = 0;
- ltw_flag = 0;
- piecewise_rate_flag = 0;
- seamless_splice_flag = 0;
- ltw_valid_flag = 0;
- ltw_offset = 0;
- piecewise_rate = 0;
- splice_type = 0;
- DTS_next_AU0 = 0;
- marker_bit0 = 0;
- DTS_next_AU1 = 0;
- marker_bit1 = 0;
- DTS_next_AU2 = 0;
- marker_bit2 = 0;
- nb_af_ext_reserved = 0;
- nb_af_reserved = 0;
-
- const1_value0 = 0x3F;
- const1_value1 = 0x1F;
- const1_value2 = 0x3F;
- }
-
- public function decode(stream:ByteArray):void
- {
- if (stream.bytesAvailable < 2) {
- throw new Error("ts: demux af failed.");
- }
- adaption_field_length = stream.readUnsignedByte();
-
- // When the adaptation_field_control value is '11', the value of the adaptation_field_length shall
- // be in the range 0 to 182.
- if (packet.adaption_field_control == SrsTsAdaptationFieldType.Both && adaption_field_length > 182) {
- throw new Error("ts: demux af length failed, must in [0, 182], actual=" + adaption_field_length);
- }
- // When the adaptation_field_control value is '10', the value of the adaptation_field_length shall
- // be 183.
- if (packet.adaption_field_control == SrsTsAdaptationFieldType.AdaptionOnly && adaption_field_length != 183) {
- throw new Error("ts: demux af length failed, must be 183, actual=" + adaption_field_length);
- }
-
- // no adaptation field.
- if (adaption_field_length == 0) {
- //info("ts: demux af empty.");
- return;
- }
-
- // the adaptation field start at here.
- var pos_af:uint = stream.position;
- var tmpv:int = stream.readUnsignedByte();
-
- discontinuity_indicator = (tmpv >> 7) & 0x01;
- random_access_indicator = (tmpv >> 6) & 0x01;
- elementary_stream_priority_indicator = (tmpv >> 5) & 0x01;
- PCR_flag = (tmpv >> 4) & 0x01;
- OPCR_flag = (tmpv >> 3) & 0x01;
- splicing_point_flag = (tmpv >> 2) & 0x01;
- transport_private_data_flag = (tmpv >> 1) & 0x01;
- adaptation_field_extension_flag = tmpv & 0x01;
-
- if (PCR_flag) {
- if (stream.bytesAvailable < 6) {
- throw new Error("ts: demux af PCR_flag failed.");
- }
-
- // @remark, for as, should never shift the Number object.
- // @remark, use pcr base and ignore the extension
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/250#issuecomment-71349370
- // first 33bits is pcr base.
- program_clock_reference_base = (stream.readUnsignedInt() << 1) & 0x1fffffe;
- var ch:uint = stream.readUnsignedByte();
- program_clock_reference_base += (ch >> 7) & 0x01;
- // next 6bits is the const values
- const1_value0 = (ch >> 1) & 0x3f;
- // last 9bits is the pcr ext.
- program_clock_reference_extension = (ch << 8) & 0x1ff;
- program_clock_reference_extension |= stream.readUnsignedByte();
- }
-
- if (OPCR_flag) {
- if (stream.bytesAvailable < 6) {
- throw new Error("ts: demux af OPCR_flag failed.");
- }
- // @remark, for as, should never shift the Number object.
- // @remark, use pcr base and ignore the extension
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/250#issuecomment-71349370
- // first 33bits is pcr base.
- original_program_clock_reference_base = (stream.readUnsignedInt() << 1) & 0x1fffffe;
- ch = stream.readUnsignedByte();
- original_program_clock_reference_base += (ch >> 7) & 0x01;
- // next 6bits is the const values
- const1_value2 = (ch >> 1) & 0x3f;
- // last 9bits is the pcr ext.
- original_program_clock_reference_extension = (ch << 8) & 0x1ff;
- original_program_clock_reference_extension |= stream.readUnsignedByte();
- }
-
- if (splicing_point_flag) {
- if (stream.bytesAvailable < 1) {
- throw new Error("ts: demux af splicing_point_flag failed.");
- }
- splice_countdown = stream.readUnsignedByte();
- }
-
- if (transport_private_data_flag) {
- if (stream.bytesAvailable < 1) {
- throw new Error("ts: demux af transport_private_data_flag failed.");
- }
- transport_private_data_length = stream.readUnsignedByte();
-
- if (transport_private_data_length> 0) {
- if (stream.bytesAvailable < transport_private_data_length) {
- throw new Error("ts: demux af transport_private_data_flag failed.");
- }
- transport_private_data = new ByteArray();
- stream.readBytes(transport_private_data, 0, transport_private_data_length);
- }
- }
-
- if (adaptation_field_extension_flag) {
- var pos_af_ext:uint = stream.position;
-
- if (stream.bytesAvailable < 2) {
- throw new Error("ts: demux af adaptation_field_extension_flag failed.");
- }
- adaptation_field_extension_length = stream.readUnsignedByte();
- var ltwfv:int = stream.readUnsignedByte();
-
- piecewise_rate_flag = (ltwfv >> 6) & 0x01;
- seamless_splice_flag = (ltwfv >> 5) & 0x01;
- ltw_flag = (ltwfv >> 7) & 0x01;
- const1_value1 = ltwfv & 0x1F;
-
- if (ltw_flag) {
- if (stream.bytesAvailable < 2) {
- throw new Error("ts: demux af ltw_flag failed.");
- }
- ltw_offset = stream.readUnsignedShort();
-
- ltw_valid_flag = (ltw_offset >> 15) &0x01;
- ltw_offset &= 0x7FFF;
- }
-
- if (piecewise_rate_flag) {
- if (stream.bytesAvailable < 3) {
- throw new Error("ts: demux af piecewise_rate_flag failed.");
- }
- // skip -1 to read 4B for 3B actually
- stream.position -= 1;
- piecewise_rate = (stream.readUnsignedInt() & 0x00ffffff);
-
- piecewise_rate &= 0x3FFFFF;
- }
-
- if (seamless_splice_flag) {
- if (stream.bytesAvailable < 5) {
- throw new Error("ts: demux af seamless_splice_flag failed");
- }
- marker_bit0 = stream.readUnsignedByte();
- DTS_next_AU1 = stream.readUnsignedShort();
- DTS_next_AU2 = stream.readUnsignedShort();
-
- splice_type = (marker_bit0 >> 4) & 0x0F;
- DTS_next_AU0 = (marker_bit0 >> 1) & 0x07;
- marker_bit0 &= 0x01;
-
- marker_bit1 = DTS_next_AU1 & 0x01;
- DTS_next_AU1 = (DTS_next_AU1 >> 1) & 0x7FFF;
-
- marker_bit2 = DTS_next_AU2 & 0x01;
- DTS_next_AU2 = (DTS_next_AU2 >> 1) & 0x7FFF;
- }
-
- nb_af_ext_reserved = adaptation_field_extension_length - (stream.position - pos_af_ext);
- stream.position += nb_af_ext_reserved;
- }
-
- nb_af_reserved = adaption_field_length - (stream.position - pos_af);
- stream.position += nb_af_reserved;
- }
-};
-
-/**
- * 2.4.4.4 Table_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 62
- * The table_id field identifies the contents of a Transport Stream PSI section as shown in Table 2-26.
- */
-class SrsTsPsiId extends SrsEnum
-{
- public function SrsTsPsiId(v:int)
- {
- super(v);
- }
- public static function parse(v:int):SrsTsPsiId
- {
- switch (v) {
- case 0x00: return SrsTsPsiId.Pas;
- case 0x01: return SrsTsPsiId.Cas;
- case 0x02: return SrsTsPsiId.Pms;
- case 0x03: return SrsTsPsiId.Ds;
- case 0x04: return SrsTsPsiId.Sds;
- case 0x05: return SrsTsPsiId.Ods;
- case 0x06: return SrsTsPsiId.Iso138181Start;
- case 0x37: return SrsTsPsiId.Iso138181End;
- case 0x38: return SrsTsPsiId.Iso138186Start;
- case 0x3F: return SrsTsPsiId.Iso138186End;
- case 0x40: return SrsTsPsiId.UserStart;
- case 0xFE: return SrsTsPsiId.UserEnd;
- case 0xFF: return SrsTsPsiId.Forbidden;
- default: case 0x00: return SrsTsPsiId.Forbidden;
- }
- }
-
- // program_association_section
- public static const Pas:SrsTsPsiId = new SrsTsPsiId(0x00);
- // conditional_access_section (CA_section)
- public static const Cas:SrsTsPsiId = new SrsTsPsiId(0x01);
- // TS_program_map_section
- public static const Pms:SrsTsPsiId = new SrsTsPsiId(0x02);
- // TS_description_section
- public static const Ds:SrsTsPsiId = new SrsTsPsiId(0x03);
- // ISO_IEC_14496_scene_description_section
- public static const Sds:SrsTsPsiId = new SrsTsPsiId(0x04);
- // ISO_IEC_14496_object_descriptor_section
- public static const Ods:SrsTsPsiId = new SrsTsPsiId(0x05);
- // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 reserved
- public static const Iso138181Start:SrsTsPsiId = new SrsTsPsiId(0x06);
- public static const Iso138181End:SrsTsPsiId = new SrsTsPsiId(0x37);
- // Defined in ISO/IEC 13818-6
- public static const Iso138186Start:SrsTsPsiId = new SrsTsPsiId(0x38);
- public static const Iso138186End:SrsTsPsiId = new SrsTsPsiId(0x3F);
- // User private
- public static const UserStart:SrsTsPsiId = new SrsTsPsiId(0x40);
- public static const UserEnd:SrsTsPsiId = new SrsTsPsiId(0xFE);
- // forbidden
- public static const Forbidden:SrsTsPsiId = new SrsTsPsiId(0xFF);
-};
-
-/**
- * the payload of ts packet, can be PES or PSI payload.
- */
-class SrsTsPayload
-{
- protected var packet:SrsTsPacket;
-
- public function SrsTsPayload(p:SrsTsPacket)
- {
- packet = p;
- }
-
- public function decode(stream:ByteArray):SrsTsMessage
- {
- throw new Error("not implements");
- }
-};
-
-/**
- * the PES payload of ts packet.
- * 2.4.3.6 PES packet, hls-mpeg-ts-iso13818-1.pdf, page 49
- */
-class SrsTsPayloadPES extends SrsTsPayload
-{
- // 3B
- /**
- * The packet_start_code_prefix is a 24-bit code. Together with the stream_id that follows it
- * constitutes a packet start code that identifies the beginning of a packet. The packet_start_code_prefix is the bit string
- * '0000 0000 0000 0000 0000 0001' (0x000001).
- */
- public var packet_start_code_prefix:int; //24bits
- // 1B
- /**
- * In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the
- * stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the
- * elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the
- * Program Specific Information as specified in 2.4.4.
- */
- // @see SrsTsPESStreamId, value can be SrsTsPESStreamIdAudioCommon or SrsTsPESStreamIdVideoCommon.
- public var stream_id:int; //8bits
- // 2B
- /**
- * A 16-bit field specifying the number of bytes in the PES packet following the last byte of the
- * field. A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in
- * PES packets whose payload consists of bytes from a video elementary stream contained in Transport Stream packets.
- */
- public var PES_packet_length:int; //16bits
-
- // 1B
- /**
- * 2bits const '10'
- */
- public var const2bits:int; //2bits
- /**
- * The 2-bit PES_scrambling_control field indicates the scrambling mode of the PES packet
- * payload. When scrambling is performed at the PES level, the PES packet header, including the optional fields when
- * present, shall not be scrambled (see Table 2-19).
- */
- public var PES_scrambling_control:int; //2bits
- /**
- * This is a 1-bit field indicating the priority of the payload in this PES packet. A '1' indicates a higher
- * priority of the payload of the PES packet payload than a PES packet payload with this field set to '0'. A multiplexor can
- * use the PES_priority bit to prioritize its data within an elementary stream. This field shall not be changed by the transport
- * mechanism.
- */
- public var PES_priority:int; //1bit
- /**
- * This is a 1-bit flag. When set to a value of '1' it indicates that the PES packet header is
- * immediately followed by the video start code or audio syncword indicated in the data_stream_alignment_descriptor
- * in 2.6.10 if this descriptor is present. If set to a value of '1' and the descriptor is not present, alignment as indicated in
- * alignment_type '01' in Table 2-47 and Table 2-48 is required. When set to a value of '0' it is not defined whether any such
- * alignment occurs or not.
- */
- public var data_alignment_indicator:int; //1bit
- /**
- * This is a 1-bit field. When set to '1' it indicates that the material of the associated PES packet payload is
- * protected by copyright. When set to '0' it is not defined whether the material is protected by copyright. A copyright
- * descriptor described in 2.6.24 is associated with the elementary stream which contains this PES packet and the copyright
- * flag is set to '1' if the descriptor applies to the material contained in this PES packet
- */
- public var copyright:int; //1bit
- /**
- * This is a 1-bit field. When set to '1' the contents of the associated PES packet payload is an original.
- * When set to '0' it indicates that the contents of the associated PES packet payload is a copy.
- */
- public var original_or_copy:int; //1bit
-
- // 1B
- /**
- * This is a 2-bit field. When the PTS_DTS_flags field is set to '10', the PTS fields shall be present in
- * the PES packet header. When the PTS_DTS_flags field is set to '11', both the PTS fields and DTS fields shall be present
- * in the PES packet header. When the PTS_DTS_flags field is set to '00' no PTS or DTS fields shall be present in the PES
- * packet header. The value '01' is forbidden.
- */
- public var PTS_DTS_flags:int; //2bits
- /**
- * A 1-bit flag, which when set to '1' indicates that ESCR base and extension fields are present in the PES
- * packet header. When set to '0' it indicates that no ESCR fields are present.
- */
- public var ESCR_flag:int; //1bit
- /**
- * A 1-bit flag, which when set to '1' indicates that the ES_rate field is present in the PES packet header.
- * When set to '0' it indicates that no ES_rate field is present.
- */
- public var ES_rate_flag:int; //1bit
- /**
- * A 1-bit flag, which when set to '1' it indicates the presence of an 8-bit trick mode field. When
- * set to '0' it indicates that this field is not present.
- */
- public var DSM_trick_mode_flag:int; //1bit
- /**
- * A 1-bit flag, which when set to '1' indicates the presence of the additional_copy_info field.
- * When set to '0' it indicates that this field is not present.
- */
- public var additional_copy_info_flag:int; //1bit
- /**
- * A 1-bit flag, which when set to '1' indicates that a CRC field is present in the PES packet. When set to
- * '0' it indicates that this field is not present.
- */
- public var PES_CRC_flag:int; //1bit
- /**
- * A 1-bit flag, which when set to '1' indicates that an extension field exists in this PES packet
- * header. When set to '0' it indicates that this field is not present.
- */
- public var PES_extension_flag:int; //1bit
-
- // 1B
- /**
- * An 8-bit field specifying the total number of bytes occupied by the optional fields and any
- * stuffing bytes contained in this PES packet header. The presence of optional fields is indicated in the byte that precedes
- * the PES_header_data_length field.
- */
- public var PES_header_data_length:int; //8bits
-
- // 5B
- /**
- * Presentation times shall be related to decoding times as follows: The PTS is a 33-bit
- * number coded in three separate fields. It indicates the time of presentation, tp n (k), in the system target decoder of a
- * presentation unit k of elementary stream n. The value of PTS is specified in units of the period of the system clock
- * frequency divided by 300 (yielding 90 kHz). The presentation time is derived from the PTS according to equation 2-11
- * below. Refer to 2.7.4 for constraints on the frequency of coding presentation timestamps.
- */
- // ===========1B
- // 4bits const
- // 3bits PTS [32..30]
- // 1bit const '1'
- // ===========2B
- // 15bits PTS [29..15]
- // 1bit const '1'
- // ===========2B
- // 15bits PTS [14..0]
- // 1bit const '1'
- public var pts:Number; // 33bits
-
- // 5B
- /**
- * The DTS is a 33-bit number coded in three separate fields. It indicates the decoding time,
- * td n (j), in the system target decoder of an access unit j of elementary stream n. The value of DTS is specified in units of
- * the period of the system clock frequency divided by 300 (yielding 90 kHz).
- */
- // ===========1B
- // 4bits const
- // 3bits DTS [32..30]
- // 1bit const '1'
- // ===========2B
- // 15bits DTS [29..15]
- // 1bit const '1'
- // ===========2B
- // 15bits DTS [14..0]
- // 1bit const '1'
- public var dts:Number; // 33bits
-
- // 6B
- /**
- * The elementary stream clock reference is a 42-bit field coded in two parts. The first
- * part, ESCR_base, is a 33-bit field whose value is given by ESCR_base(i), as given in equation 2-14. The second part,
- * ESCR_ext, is a 9-bit field whose value is given by ESCR_ext(i), as given in equation 2-15. The ESCR field indicates the
- * intended time of arrival of the byte containing the last bit of the ESCR_base at the input of the PES-STD for PES streams
- * (refer to 2.5.2.4).
- */
- // 2bits reserved
- // 3bits ESCR_base[32..30]
- // 1bit const '1'
- // 15bits ESCR_base[29..15]
- // 1bit const '1'
- // 15bits ESCR_base[14..0]
- // 1bit const '1'
- // 9bits ESCR_extension
- // 1bit const '1'
- public var ESCR_base:Number; //33bits
- public var ESCR_extension:int; //9bits
-
- // 3B
- /**
- * The ES_rate field is a 22-bit unsigned integer specifying the rate at which the
- * system target decoder receives bytes of the PES packet in the case of a PES stream. The ES_rate is valid in the PES
- * packet in which it is included and in subsequent PES packets of the same PES stream until a new ES_rate field is
- * encountered. The value of the ES_rate is measured in units of 50 bytes/second. The value 0 is forbidden. The value of the
- * ES_rate is used to define the time of arrival of bytes at the input of a P-STD for PES streams defined in 2.5.2.4. The
- * value encoded in the ES_rate field may vary from PES_packet to PES_packet.
- */
- // 1bit const '1'
- // 22bits ES_rate
- // 1bit const '1'
- public var ES_rate:int; //22bits
-
- // 1B
- /**
- * A 3-bit field that indicates which trick mode is applied to the associated video stream. In cases of
- * other types of elementary streams, the meanings of this field and those defined by the following five bits are undefined.
- * For the definition of trick_mode status, refer to the trick mode section of 2.4.2.3.
- */
- public var trick_mode_control:int; //3bits
- public var trick_mode_value:int; //5bits
-
- // 1B
- // 1bit const '1'
- /**
- * This 7-bit field contains private data relating to copyright information.
- */
- public var additional_copy_info:int; //7bits
-
- // 2B
- /**
- * The previous_PES_packet_CRC is a 16-bit field that contains the CRC value that yields
- * a zero output of the 16 registers in the decoder similar to the one defined in Annex A,
- */
- public var previous_PES_packet_CRC:int; //16bits
-
- // 1B
- /**
- * A 1-bit flag which when set to '1' indicates that the PES packet header contains private data.
- * When set to a value of '0' it indicates that private data is not present in the PES header.
- */
- public var PES_private_data_flag:int; //1bit
- /**
- * A 1-bit flag which when set to '1' indicates that an ISO/IEC 11172-1 pack header or a
- * Program Stream pack header is stored in this PES packet header. If this field is in a PES packet that is contained in a
- * Program Stream, then this field shall be set to '0'. In a Transport Stream, when set to the value '0' it indicates that no pack
- * header is present in the PES header.
- */
- public var pack_header_field_flag:int; //1bit
- /**
- * A 1-bit flag which when set to '1' indicates that the
- * program_packet_sequence_counter, MPEG1_MPEG2_identifier, and original_stuff_length fields are present in this
- * PES packet. When set to a value of '0' it indicates that these fields are not present in the PES header.
- */
- public var program_packet_sequence_counter_flag:int; //1bit
- /**
- * A 1-bit flag which when set to '1' indicates that the P-STD_buffer_scale and P-STD_buffer_size
- * are present in the PES packet header. When set to a value of '0' it indicates that these fields are not present in the
- * PES header.
- */
- public var P_STD_buffer_flag:int; //1bit
- /**
- * reverved value, must be '1'
- */
- public var const1_value0:int; //3bits
- /**
- * A 1-bit field which when set to '1' indicates the presence of the PES_extension_field_length
- * field and associated fields. When set to a value of '0' this indicates that the PES_extension_field_length field and any
- * associated fields are not present.
- */
- public var PES_extension_flag_2:int; //1bit
-
- // 16B
- /**
- * This is a 16-byte field which contains private data. This data, combined with the fields before and
- * after, shall not emulate the packet_start_code_prefix (0x000001).
- */
- public var PES_private_data:ByteArray; //128bits
-
- // (1+x)B
- /**
- * This is an 8-bit field which indicates the length, in bytes, of the pack_header_field().
- */
- public var pack_field_length:int; //8bits
- public var pack_field:ByteArray; //[pack_field_length] bytes
-
- // 2B
- // 1bit const '1'
- /**
- * The program_packet_sequence_counter field is a 7-bit field. It is an optional
- * counter that increments with each successive PES packet from a Program Stream or from an ISO/IEC 11172-1 Stream or
- * the PES packets associated with a single program definition in a Transport Stream, providing functionality similar to a
- * continuity counter (refer to 2.4.3.2). This allows an application to retrieve the original PES packet sequence of a Program
- * Stream or the original packet sequence of the original ISO/IEC 11172-1 stream. The counter will wrap around to 0 after
- * its maximum value. Repetition of PES packets shall not occur. Consequently, no two consecutive PES packets in the
- * program multiplex shall have identical program_packet_sequence_counter values.
- */
- public var program_packet_sequence_counter:int; //7bits
- // 1bit const '1'
- /**
- * A 1-bit flag which when set to '1' indicates that this PES packet carries information from
- * an ISO/IEC 11172-1 stream. When set to '0' it indicates that this PES packet carries information from a Program Stream.
- */
- public var MPEG1_MPEG2_identifier:int; //1bit
- /**
- * This 6-bit field specifies the number of stuffing bytes used in the original ITU-T
- * Rec. H.222.0 | ISO/IEC 13818-1 PES packet header or in the original ISO/IEC 11172-1 packet header.
- */
- public var original_stuff_length:int; //6bits
-
- // 2B
- // 2bits const '01'
- /**
- * The P-STD_buffer_scale is a 1-bit field, the meaning of which is only defined if this PES packet
- * is contained in a Program Stream. It indicates the scaling factor used to interpret the subsequent P-STD_buffer_size field.
- * If the preceding stream_id indicates an audio stream, P-STD_buffer_scale shall have the value '0'. If the preceding
- * stream_id indicates a video stream, P-STD_buffer_scale shall have the value '1'. For all other stream types, the value
- * may be either '1' or '0'.
- */
- public var P_STD_buffer_scale:int; //1bit
- /**
- * The P-STD_buffer_size is a 13-bit unsigned integer, the meaning of which is only defined if this
- * PES packet is contained in a Program Stream. It defines the size of the input buffer, BS n , in the P-STD. If
- * P-STD_buffer_scale has the value '0', then the P-STD_buffer_size measures the buffer size in units of 128 bytes. If
- * P-STD_buffer_scale has the value '1', then the P-STD_buffer_size measures the buffer size in units of 1024 bytes.
- */
- public var P_STD_buffer_size:int; //13bits
-
- // (1+x)B
- // 1bit const '1'
- /**
- * This is a 7-bit field which specifies the length, in bytes, of the data following this field in
- * the PES extension field up to and including any reserved bytes.
- */
- public var PES_extension_field_length:int; //7bits
- public var PES_extension_field:ByteArray; //[PES_extension_field_length] bytes
-
- // NB
- /**
- * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder, for example to meet
- * the requirements of the channel. It is discarded by the decoder. No more than 32 stuffing bytes shall be present in one
- * PES packet header.
- */
- public var nb_stuffings:int;
-
- // NB
- /**
- * PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream
- * indicated by the packet’s stream_id or PID. When the elementary stream data conforms to ITU-T
- * Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 13818-3, the PES_packet_data_bytes shall be byte aligned to the bytes of this
- * Recommendation | International Standard. The byte-order of the elementary stream shall be preserved. The number of
- * PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the
- * PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first
- * PES_packet_data_byte.
- *
- * In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the
- * PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future.
- */
- public var nb_bytes:int;
-
- // NB
- /**
- * This is a fixed 8-bit value equal to '1111 1111'. It is discarded by the decoder.
- */
- public var nb_paddings:int;
-
- private var _log:ILogger = new TraceLogger("HLS");
-
- public function SrsTsPayloadPES(p:SrsTsPacket)
- {
- super(p);
-
- PES_private_data = null;
- pack_field = null;
- PES_extension_field = null;
- nb_stuffings = 0;
- nb_bytes = 0;
- nb_paddings = 0;
- const2bits = 0x02;
- const1_value0 = 0x07;
- }
-
- override public function decode(stream:ByteArray):SrsTsMessage
- {
- // find the channel from chunk.
- var channel:SrsTsChannel = packet.context.getChannel(packet.pid);
- if (!channel) {
- throw new Error("ts: demux PES no channel, pid=" + packet.pid);
- }
-
- // init msg.
- var msg:SrsTsMessage = channel.msg;
- if (!msg) {
- msg = new SrsTsMessage(channel, packet);
- channel.msg = msg;
- }
-
- // we must cache the fresh state of msg,
- // for the PES_packet_length is 0, the first payload_unit_start_indicator always 1,
- // so should check for the fresh and not completed it.
- var is_fresh_msg:Boolean = msg.fresh();
-
- // check when fresh, the payload_unit_start_indicator
- // should be 1 for the fresh msg.
- if (is_fresh_msg && !packet.payload_unit_start_indicator) {
- _log.error("ts: PES fresh packet length={0}, us={1}, cc={2}",
- msg.PES_packet_length, packet.payload_unit_start_indicator, packet.continuity_counter);
- throw new Error("ts: PES fresh packet invalid.");
- }
-
- // check when not fresh and PES_packet_length>0,
- // the payload_unit_start_indicator should never be 1 when not completed.
- if (!is_fresh_msg && msg.PES_packet_length > 0
- && !msg.completed(packet.payload_unit_start_indicator)
- && packet.payload_unit_start_indicator
- ) {
- _log.error("ts: PES packet length={0}, us={1}, cc={2}",
- msg.PES_packet_length, packet.payload_unit_start_indicator, packet.continuity_counter);
- throw new Error("ts: PES packet length invalid.");
-
- // reparse current msg.
- stream.position = 0;
- channel.msg = null;
- return null;
- }
-
- // check the continuity counter
- if (!is_fresh_msg) {
- // late-incoming or duplicated continuity, drop message.
- // @remark check overflow, the counter plus 1 should greater when invalid.
- if (msg.continuity_counter >= packet.continuity_counter
- && ((msg.continuity_counter + 1) & 0x0f) > packet.continuity_counter
- ) {
- _log.warn("ts: drop PES {0}B for duplicated cc={1}",
- stream.length, msg.continuity_counter);
- stream.position = 0;
- return null;
- }
-
- // when got partially message, the continous count must be continuous, or drop it.
- if (((msg.continuity_counter + 1) & 0x0f) != packet.continuity_counter) {
- _log.error("ts: continuity must be continous, msg={0}, packet={1}",
- msg.continuity_counter, packet.continuity_counter);
- throw new Error("ts: continuity must be continous.");
-
- // reparse current msg.
- stream.position = 0;
- channel.msg = null;
- return null;
- }
- }
- msg.continuity_counter = packet.continuity_counter;
-
- // for the PES_packet_length(0), reap when completed.
- if (!is_fresh_msg && msg.completed(packet.payload_unit_start_indicator)) {
- // reap previous PES packet.
- channel.msg = null;
-
- // reparse current msg.
- stream.position = 0;
- return msg;
- }
-
- // contious packet, append bytes for unit start is 0
- if (!packet.payload_unit_start_indicator) {
- nb_bytes = msg.dump(stream);
- }
-
- // when unit start, parse the fresh msg.
- if (packet.payload_unit_start_indicator) {
- // 6B fixed header.
- if (stream.bytesAvailable < 6) {
- throw new Error("ts: demux PSE failed.");
- }
- // 3B
- stream.position -= 1;
- packet_start_code_prefix = (stream.readUnsignedInt()) & 0x00ffffff;
- // 1B
- stream_id = stream.readUnsignedByte();
- // 2B
- PES_packet_length = stream.readUnsignedShort();
-
- // check the packet start prefix.
- packet_start_code_prefix &= 0xFFFFFF;
- if (packet_start_code_prefix != 0x01) {
- _log.error("ts: demux PES start code failed, expect=0x01, actual={0}",
- packet_start_code_prefix);
- throw new Error("ts: demux PES start code failed.");
- }
- var pos_packet:uint = stream.position;
-
- // @remark the sid indicates the elementary stream format.
- // the SrsTsPESStreamIdAudio and SrsTsPESStreamIdVideo is start by 0b110 or 0b1110
- var sid:SrsTsPESStreamId = SrsTsPESStreamId.parse(stream_id);
- msg.sid = sid;
-
- if (sid.notEquals(SrsTsPESStreamId.ProgramStreamMap)
- && sid.notEquals(SrsTsPESStreamId.PaddingStream)
- && sid.notEquals(SrsTsPESStreamId.PrivateStream2)
- && sid.notEquals(SrsTsPESStreamId.EcmStream)
- && sid.notEquals(SrsTsPESStreamId.EmmStream)
- && sid.notEquals(SrsTsPESStreamId.ProgramStreamDirectory)
- && sid.notEquals(SrsTsPESStreamId.DsmccStream)
- && sid.notEquals(SrsTsPESStreamId.H2221TypeE)
- ) {
- // 3B flags.
- if (stream.bytesAvailable < 3) {
- throw new Error("ts: demux PSE flags failed.");
- }
- // 1B
- var oocv:int = stream.readUnsignedByte();
- // 1B
- var pefv:int = stream.readUnsignedByte();
- // 1B
- PES_header_data_length = stream.readUnsignedByte();
- // position of header start.
- var pos_header:uint = stream.position;
-
- const2bits = (oocv >> 6) & 0x03;
- PES_scrambling_control = (oocv >> 4) & 0x03;
- PES_priority = (oocv >> 3) & 0x01;
- data_alignment_indicator = (oocv >> 2) & 0x01;
- copyright = (oocv >> 1) & 0x01;
- original_or_copy = oocv & 0x01;
-
- PTS_DTS_flags = (pefv >> 6) & 0x03;
- ESCR_flag = (pefv >> 5) & 0x01;
- ES_rate_flag = (pefv >> 4) & 0x01;
- DSM_trick_mode_flag = (pefv >> 3) & 0x01;
- additional_copy_info_flag = (pefv >> 2) & 0x01;
- PES_CRC_flag = (pefv >> 1) & 0x01;
- PES_extension_flag = pefv & 0x01;
-
- // check required together.
- var nb_required:int = 0;
- nb_required += (PTS_DTS_flags == 0x2)? 5:0;
- nb_required += (PTS_DTS_flags == 0x3)? 10:0;
- nb_required += ESCR_flag? 6:0;
- nb_required += ES_rate_flag? 3:0;
- nb_required += DSM_trick_mode_flag? 1:0;
- nb_required += additional_copy_info_flag? 1:0;
- nb_required += PES_CRC_flag? 2:0;
- nb_required += PES_extension_flag? 1:0;
- if (stream.bytesAvailable < nb_required) {
- throw new Error("ts: demux PSE payload failed.");
- }
-
- // 5B
- if (PTS_DTS_flags == 0x2) {
- pts = decode_33bits_dts_pts(stream);
- dts = pts;
-
- // update the dts and pts of message.
- msg.dts = dts;
- msg.pts = pts;
- }
-
- // 10B
- if (PTS_DTS_flags == 0x3) {
- pts = decode_33bits_dts_pts(stream);
- dts = decode_33bits_dts_pts(stream);
-
- // check sync, the diff of dts and pts should never greater than 1s.
- if (dts - pts > 90000 || pts - dts > 90000) {
- _log.warn("ts: sync dts={0}, pts={1}", dts, pts);
- }
-
- // update the dts and pts of message.
- msg.dts = dts;
- msg.pts = pts;
- }
-
- // 6B
- if (ESCR_flag) {
- ESCR_extension = 0;
- ESCR_base = 0;
-
- stream.position += 6;
- _log.warn("ts: demux PES, ignore the escr.");
- }
-
- // 3B
- if (ES_rate_flag) {
- // skip -1 to read 4bytes for the ES_rate is 3B.
- stream.position -= 1;
- ES_rate = (stream.readUnsignedInt() & 0x00ffffff);
-
- ES_rate = ES_rate >> 1;
- ES_rate &= 0x3FFFFF;
- }
-
- // 1B
- if (DSM_trick_mode_flag) {
- trick_mode_control = stream.readUnsignedByte();
-
- trick_mode_value = trick_mode_control & 0x1f;
- trick_mode_control = (trick_mode_control >> 5) & 0x03;
- }
-
- // 1B
- if (additional_copy_info_flag) {
- additional_copy_info = stream.readUnsignedByte();
-
- additional_copy_info &= 0x7f;
- }
-
- // 2B
- if (PES_CRC_flag) {
- previous_PES_packet_CRC = stream.readUnsignedShort();
- }
-
- // 1B
- if (PES_extension_flag) {
- var efv:int = stream.readUnsignedByte();
-
- PES_private_data_flag = (efv >> 7) & 0x01;
- pack_header_field_flag = (efv >> 6) & 0x01;
- program_packet_sequence_counter_flag = (efv >> 5) & 0x01;
- P_STD_buffer_flag = (efv >> 4) & 0x01;
- const1_value0 = (efv >> 1) & 0x07;
- PES_extension_flag_2 = efv & 0x01;
-
- nb_required = 0;
- nb_required += PES_private_data_flag? 16:0;
- nb_required += pack_header_field_flag? 1:0; // 1+x bytes.
- nb_required += program_packet_sequence_counter_flag? 2:0;
- nb_required += P_STD_buffer_flag? 2:0;
- nb_required += PES_extension_flag_2? 1:0; // 1+x bytes.
- if (stream.bytesAvailable < nb_required) {
- throw new Error("ts: demux PSE ext payload failed.");
- }
-
- // 16B
- if (PES_private_data_flag) {
- PES_private_data = new ByteArray();
- stream.readBytes(PES_private_data, 0, 16);
- }
-
- // (1+x)B
- if (pack_header_field_flag) {
- pack_field_length = stream.readUnsignedByte();
- if (pack_field_length > 0) {
- // the adjust required bytes.
- nb_required = nb_required - 16 - 1 + pack_field_length;
- if (stream.bytesAvailable < nb_required) {
- throw new Error("ts: demux PSE ext pack failed.");
- }
- pack_field = new ByteArray();
- stream.readBytes(pack_field, 0, pack_field_length);
- }
- }
-
- // 2B
- if (program_packet_sequence_counter_flag) {
- program_packet_sequence_counter = stream.readUnsignedByte();
- program_packet_sequence_counter &= 0x7f;
-
- original_stuff_length = stream.readUnsignedByte();
- MPEG1_MPEG2_identifier = (original_stuff_length >> 6) & 0x01;
- original_stuff_length &= 0x3f;
- }
-
- // 2B
- if (P_STD_buffer_flag) {
- P_STD_buffer_size = stream.readUnsignedShort();
-
- // '01'
- //int8_t const2bits = (P_STD_buffer_scale >>14) & 0x03;
-
- P_STD_buffer_scale = (P_STD_buffer_scale >>13) & 0x01;
- P_STD_buffer_size &= 0x1FFF;
- }
-
- // (1+x)B
- if (PES_extension_flag_2) {
- PES_extension_field_length = stream.readUnsignedByte();
- PES_extension_field_length &= 0x07;
-
- if (PES_extension_field_length > 0) {
- if (stream.bytesAvailable < PES_extension_field_length) {
- throw new Error("ts: demux PSE ext field failed.");
- }
- PES_extension_field = new ByteArray();
- stream.readBytes(PES_extension_field, 0, PES_extension_field_length);
- }
- }
- }
-
- // stuffing_byte
- nb_stuffings = PES_header_data_length - (stream.position - pos_header);
- if (nb_stuffings > 0) {
- if (stream.bytesAvailable < nb_stuffings) {
- throw new Error("ts: demux PSE stuffings failed.");
- }
- stream.position += nb_stuffings;
- }
-
- // PES_packet_data_byte, page58.
- // the packet size contains the header size.
- // The number of PES_packet_data_bytes, N, is specified by the
- // PES_packet_length field. N shall be equal to the value
- // indicated in the PES_packet_length minus the number of bytes
- // between the last byte of the PES_packet_length field and the
- // first PES_packet_data_byte.
- /**
- * when actual packet length > 0xffff(65535),
- * which exceed the max u_int16_t packet length,
- * use 0 packet length, the next unit start indicates the end of packet.
- */
- if (PES_packet_length > 0) {
- var nb_packet:uint = PES_packet_length - (stream.position - pos_packet);
- msg.PES_packet_length = (uint)(Math.max(0, nb_packet));
- }
-
- // xB
- nb_bytes = msg.dump(stream);
- } else if (sid.equals(SrsTsPESStreamId.ProgramStreamMap)
- || sid.equals(SrsTsPESStreamId.PrivateStream2)
- || sid.equals(SrsTsPESStreamId.EcmStream)
- || sid.equals(SrsTsPESStreamId.EmmStream)
- || sid.equals(SrsTsPESStreamId.ProgramStreamDirectory)
- || sid.equals(SrsTsPESStreamId.DsmccStream)
- || sid.equals(SrsTsPESStreamId.H2221TypeE)
- ) {
- // for (i = 0; i < PES_packet_length; i++) {
- // PES_packet_data_byte
- // }
-
- // xB
- nb_bytes = msg.dump(stream);
- } else if (sid.equals(SrsTsPESStreamId.PaddingStream)) {
- // for (i = 0; i < PES_packet_length; i++) {
- // padding_byte
- // }
- nb_paddings = stream.length - stream.position;
- stream.position = stream.length;
- //info("ts: drop %dB padding bytes", nb_paddings);
- } else {
- var nb_drop:int = stream.length - stream.position;
- stream.position = stream.length;
- _log.warn("ts: drop the pes packet {0}B for stream_id={1}", nb_drop, stream_id);
- }
- }
-
- // when fresh and the PES_packet_length is 0,
- // the payload_unit_start_indicator always be 1,
- // the message should never EOF for the first packet.
- if (is_fresh_msg && msg.PES_packet_length == 0) {
- return null;
- }
-
- // check msg, reap when completed.
- if (msg.completed(packet.payload_unit_start_indicator)) {
- channel.msg = null;
- //info("ts: reap msg for completed.");
- return msg;
- }
-
- return null;
- }
-
- private function decode_33bits_dts_pts(stream:ByteArray):Number
- {
- if (stream.bytesAvailable < 5) {
- throw new Error("ts: demux PSE dts/pts failed");
- }
-
- // decode the 33bits schema.
- // ===========1B
- // 4bits const maybe '0001', '0010' or '0011'.
- // 3bits DTS/PTS [32..30]
- // 1bit const '1'
- var dts_pts_30_32:uint = stream.readUnsignedByte();
- if ((dts_pts_30_32 & 0x01) != 0x01) {
- throw new Error("ts: demux PSE dts/pts 30-32 failed.");
- }
- // @remark, we donot check the high 4bits, maybe '0001', '0010' or '0011'.
- // so we just ensure the high 4bits is not 0x00.
- if (((dts_pts_30_32 >> 4) & 0x0f) == 0x00) {
- throw new Error("ts: demux PSE dts/pts 30-32 failed.");
- }
- dts_pts_30_32 = (dts_pts_30_32 >> 1) & 0x07;
-
- // ===========2B
- // 15bits DTS/PTS [29..15]
- // 1bit const '1'
- var dts_pts_15_29:uint = stream.readUnsignedShort();
- if ((dts_pts_15_29 & 0x01) != 0x01) {
- throw new Error("ts: demux PSE dts/pts 15-29 failed.");
- }
- dts_pts_15_29 = (dts_pts_15_29 >> 1) & 0x7fff;
-
- // ===========2B
- // 15bits DTS/PTS [14..0]
- // 1bit const '1'
- var dts_pts_0_14:uint = stream.readUnsignedShort();
- if ((dts_pts_0_14 & 0x01) != 0x01) {
- throw new Error("ts: demux PSE dts/pts 0-14 failed.");
- }
- dts_pts_0_14 = (dts_pts_0_14 >> 1) & 0x7fff;
-
- var v:uint = 0x00;
- v += (dts_pts_30_32 << 30) & 0x1c0000000;
- v += (dts_pts_15_29 << 15) & 0x3fff8000;
- v += dts_pts_0_14 & 0x7fff;
- return v;
- }
-};
-
-/**
- * the PSI payload of ts packet.
- * 2.4.4 Program specific information, hls-mpeg-ts-iso13818-1.pdf, page 59
- */
-class SrsTsPayloadPSI extends SrsTsPayload
-{
- // 1B
- /**
- * This is an 8-bit field whose value shall be the number of bytes, immediately following the pointer_field
- * until the first byte of the first section that is present in the payload of the Transport Stream packet (so a value of 0x00 in
- * the pointer_field indicates that the section starts immediately after the pointer_field). When at least one section begins in
- * a given Transport Stream packet, then the payload_unit_start_indicator (refer to 2.4.3.2) shall be set to 1 and the first
- * byte of the payload of that Transport Stream packet shall contain the pointer. When no section begins in a given
- * Transport Stream packet, then the payload_unit_start_indicator shall be set to 0 and no pointer shall be sent in the
- * payload of that packet.
- */
- public var pointer_field:int;
- // 1B
- /**
- * This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26.
- */
- public var table_id:SrsTsPsiId; //8bits
-
- // 2B
- /**
- * The section_syntax_indicator is a 1-bit field which shall be set to '1'.
- */
- public var section_syntax_indicator:int; //1bit
- /**
- * const value, must be '0'
- */
- public var const0_value:int; //1bit
- /**
- * reverved value, must be '1'
- */
- public var const1_value:int; //2bits
- /**
- * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number
- * of bytes of the section, starting immediately following the section_length field, and including the CRC. The value in this
- * field shall not exceed 1021 (0x3FD).
- */
- public var section_length:int; //12bits
-
- // the specified psi info, for example, PAT fields.
- // 4B
- /**
- * This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder
- * defined in Annex A after processing the entire section.
- * @remark crc32(bytes without pointer field, before crc32 field)
- */
- public var CRC_32:int; //32bits
-
- public function SrsTsPayloadPSI(p:SrsTsPacket)
- {
- super(p);
-
- pointer_field = 0;
- const0_value = 0;
- const1_value = 3;
- CRC_32 = 0;
- }
-
- override public function decode(stream:ByteArray):SrsTsMessage
- {
- /**
- * When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following
- * significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value
- * shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the
- * Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0',
- * indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of
- * stream_type 5 (refer to Table 2-29).
- */
- if (packet.payload_unit_start_indicator) {
- if (stream.bytesAvailable < 1) {
- throw new Error("ts: demux PSI failed.");
- }
- pointer_field = stream.readUnsignedByte();
- }
-
- // to calc the crc32
- var pat_pos:uint = stream.position;
-
- // atleast 3B for all psi.
- if (stream.bytesAvailable < 3) {
- throw new Error("ts: demux PSI failed.");
- }
- // 1B
- table_id = SrsTsPsiId.parse(stream.readUnsignedByte());
-
- // 2B
- var slv:int = stream.readUnsignedShort();
-
- section_syntax_indicator = (slv >> 15) & 0x01;
- const0_value = (slv >> 14) & 0x01;
- const1_value = (slv >> 12) & 0x03;
- section_length = slv & 0x0FFF;
-
- // no section, ignore.
- if (section_length == 0) {
- // "ts: demux PAT ignore empty section"
- return null;
- }
-
- if (stream.bytesAvailable < section_length) {
- throw new Error("ts: demux PAT section failed.");
- }
-
- // call the virtual method of actual PSI.
- psi_decode(stream);
-
- // 4B
- if (stream.bytesAvailable < 4) {
- throw new Error("ts: demux PSI crc32 failed.");
- }
- CRC_32 = stream.readUnsignedInt();
-
- // verify crc32.
- var pos:uint = stream.position;
-
- var crc32Bytes:ByteArray = new ByteArray();
- stream.position = pat_pos;
- stream.readBytes(crc32Bytes, 0, pos - pat_pos - 4);
- stream.position = pos;
-
- var expetCrc32:int = (int)(SrsUtils.srs_crc32(crc32Bytes));
- if (expetCrc32 != CRC_32) {
- throw new Error("ts: verify PSI crc32 failed.");
- }
- stream.position = pos;
-
- // consume left stuffings
- // TODO: FIXME: all stuffing must be 0xff.
- stream.position = stream.length;
-
- return null;
- }
-
- protected function psi_decode(stream:ByteArray):void
- {
- throw new Error("not implements");
- }
-};
-
-/**
- * the program of PAT of PSI ts packet.
- */
-class SrsTsPayloadPATProgram
-{
- // 4B
- /**
- * Program_number is a 16-bit field. It specifies the program to which the program_map_PID is
- * applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value
- * of this field is user defined. This field shall not take any single value more than once within one version of the Program
- * Association Table.
- */
- public var number:int; // 16bits
- /**
- * reverved value, must be '1'
- */
- public var const1_value:int; //3bits
- /**
- * program_map_PID/network_PID 13bits
- * network_PID - The network_PID is a 13-bit field, which is used only in conjunction with the value of the
- * program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network
- * Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in
- * Table 2-3. The presence of the network_PID is optional.
- */
- public var pid:int; //13bits
-
- public function SrsTsPayloadPATProgram(n:int, p:int)
- {
- number = n;
- pid = p;
- const1_value = 0x07;
- }
-
- public function decode(stream:ByteArray):void
- {
- // atleast 4B for PAT program specified
- if (stream.bytesAvailable < 4) {
- throw new Error("ts: demux PAT failed.");
- }
-
- var tmpv:int = stream.readUnsignedInt();
- number = ((tmpv >> 16) & 0xFFFF);
- const1_value = ((tmpv >> 13) & 0x07);
- pid = (tmpv & 0x1FFF);
-
- return;
- }
-};
-
-/**
- * the PAT payload of PSI ts packet.
- * 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61
- * The Program Association Table provides the correspondence between a program_number and the PID value of the
- * Transport Stream packets which carry the program definition. The program_number is the numeric label associated with
- * a program.
- */
-class SrsTsPayloadPAT extends SrsTsPayloadPSI
-{
- // 2B
- /**
- * This is a 16-bit field which serves as a label to identify this Transport Stream from any other
- * multiplex within a network. Its value is defined by the user.
- */
- public var transport_stream_id:int; //16bits
-
- // 1B
- /**
- * reverved value, must be '1'
- */
- public var const3_value:int; //2bits
- /**
- * This 5-bit field is the version number of the whole Program Association Table. The version number
- * shall be incremented by 1 modulo 32 whenever the definition of the Program Association Table changes. When the
- * current_next_indicator is set to '1', then the version_number shall be that of the currently applicable Program Association
- * Table. When the current_next_indicator is set to '0', then the version_number shall be that of the next applicable Program
- * Association Table.
- */
- public var version_number:int; //5bits
- /**
- * A 1-bit indicator, which when set to '1' indicates that the Program Association Table sent is
- * currently applicable. When the bit is set to '0', it indicates that the table sent is not yet applicable and shall be the next
- * table to become valid.
- */
- public var current_next_indicator:int; //1bit
-
- // 1B
- /**
- * This 8-bit field gives the number of this section. The section_number of the first section in the
- * Program Association Table shall be 0x00. It shall be incremented by 1 with each additional section in the Program
- * Association Table.
- */
- public var section_number:int; //8bits
-
- // 1B
- /**
- * This 8-bit field specifies the number of the last section (that is, the section with the highest
- * section_number) of the complete Program Association Table.
- */
- public var last_section_number:int; //8bits
-
- // multiple 4B program data, elem is SrsTsPayloadPATProgram
- public var programs:Array;
-
- public function SrsTsPayloadPAT(p:SrsTsPacket)
- {
- super(p);
-
- const3_value = 3;
- programs = new Array();
- }
-
- override protected function psi_decode(stream:ByteArray):void
- {
- // atleast 5B for PAT specified
- if (stream.bytesAvailable < 5) {
- throw new Error("ts: demux PAT failed.");
- }
-
- var pos:uint = stream.position;
-
- // 2B
- transport_stream_id = stream.readUnsignedShort();
-
- // 1B
- var cniv:int = stream.readUnsignedByte();
-
- const3_value = (cniv >> 6) & 0x03;
- version_number = (cniv >> 1) & 0x1F;
- current_next_indicator = cniv & 0x01;
-
- // TODO: FIXME: check the indicator.
-
- // 1B
- section_number = stream.readUnsignedByte();
- // 1B
- last_section_number = stream.readUnsignedByte();
-
- // multiple 4B program data.
- var program_bytes:int = section_length - 4 - (stream.position - pos);
- for (var i:int = 0; i < program_bytes; i += 4) {
- var program:SrsTsPayloadPATProgram = new SrsTsPayloadPATProgram(0, 0);
- program.decode(stream);
-
- // update the apply pid table.
- packet.context.setChannel(program.pid, SrsTsPidApply.PMT, SrsTsStream.Reserved);
-
- programs.push(program);
- }
-
- // update the apply pid table.
- packet.context.setChannel(packet.pid, SrsTsPidApply.PAT, SrsTsStream.Reserved);
-
- return;
- }
-};
-
-/**
- * the esinfo for PMT program.
- */
-class SrsTsPayloadPMTESInfo
-{
- // 1B
- /**
- * This is an 8-bit field specifying the type of program element carried within the packets with the PID
- * whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29.
- */
- public var stream_type:SrsTsStream; //8bits
-
- // 2B
- /**
- * reverved value, must be '1'
- */
- public var const1_value0:int; //3bits
- /**
- * This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated
- * program element.
- */
- public var elementary_PID:int; //13bits
-
- // (2+x)B
- /**
- * reverved value, must be '1'
- */
- public var const1_value1:int; //4bits
- /**
- * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number
- * of bytes of the descriptors of the associated program element immediately following the ES_info_length field.
- */
- public var ES_info_length:int; //12bits
- public var ES_info:ByteArray; //[ES_info_length] bytes.
-
- public function SrsTsPayloadPMTESInfo(st:SrsTsStream, epid:int)
- {
- stream_type = st;
- elementary_PID = epid;
-
- const1_value0 = 7;
- const1_value1 = 0x0f;
- ES_info_length = 0;
- ES_info = null;
- }
-
- public function decode(stream:ByteArray):void
- {
- // 5B
- if (stream.bytesAvailable < 5) {
- throw new Error("ts: demux PMT es info failed.");
- }
-
- stream_type = SrsTsStream.parse(stream.readUnsignedByte());
-
- var epv:int = stream.readUnsignedShort();
- const1_value0 = (epv >> 13) & 0x07;
- elementary_PID = epv & 0x1FFF;
-
- var eilv:int = stream.readUnsignedShort();
- const1_value1 = (epv >> 12) & 0x0f;
- ES_info_length = eilv & 0x0FFF;
-
- if (ES_info_length > 0) {
- if (stream.bytesAvailable < ES_info_length) {
- throw new Error("ts: demux PMT es info data failed.");
- }
- ES_info = new ByteArray();
- stream.readBytes(ES_info, 0, ES_info_length);
- }
- }
-};
-
-/**
- * the PMT payload of PSI ts packet.
- * 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64
- * The Program Map Table provides the mappings between program numbers and the program elements that comprise
- * them. A single instance of such a mapping is referred to as a "program definition". The program map table is the
- * complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID
- * values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in
- * one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the
- * section number field shall be set to zero. Sections are identified by the program_number field.
- */
-class SrsTsPayloadPMT extends SrsTsPayloadPSI
-{
- // 2B
- /**
- * program_number is a 16-bit field. It specifies the program to which the program_map_PID is
- * applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a
- * program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when
- * that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By
- * describing the different program elements belonging to a program, data from different sources (e.g. sequential events)
- * can be concatenated together to form a continuous set of streams using a program_number. For examples of applications
- * refer to Annex C.
- */
- public var program_number:int; //16bits
-
- // 1B
- /**
- * reverved value, must be '1'
- */
- public var const1_value0:int; //2bits
- /**
- * This 5-bit field is the version number of the TS_program_map_section. The version number shall be
- * incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers
- * to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then
- * the version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator
- * is set to '0', then the version_number shall be that of the next applicable TS_program_map_section.
- */
- public var version_number:int; //5bits
- /**
- * A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is
- * currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable
- * and shall be the next TS_program_map_section to become valid.
- */
- public var current_next_indicator:int; //1bit
-
- // 1B
- /**
- * The value of this 8-bit field shall be 0x00.
- */
- public var section_number:int; //8bits
-
- // 1B
- /**
- * The value of this 8-bit field shall be 0x00.
- */
- public var last_section_number:int; //8bits
-
- // 2B
- /**
- * reverved value, must be '1'
- */
- public var const1_value1:int; //3bits
- /**
- * This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields
- * valid for the program specified by program_number. If no PCR is associated with a program definition for private
- * streams, then this field shall take the value of 0x1FFF. Refer to the semantic definition of PCR in 2.4.3.5 and Table 2-3
- * for restrictions on the choice of PCR_PID value.
- */
- public var PCR_PID:int; //13bits
-
- // 2B
- public var const1_value2:int; //4bits
- /**
- * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the
- * number of bytes of the descriptors immediately following the program_info_length field.
- */
- public var program_info_length:int; //12bits
- public var program_info_desc:ByteArray; //[program_info_length]bytes
-
- // array of TSPMTESInfo, elem is SrsTsPayloadPMTESInfo object.
- public var infos:Array;
-
- public function SrsTsPayloadPMT(p:SrsTsPacket)
- {
- super(p);
-
- const1_value0 = 3;
- const1_value1 = 7;
- const1_value2 = 0x0f;
- program_info_length = 0;
- program_info_desc = null;
- infos = new Array();
- }
-
- override protected function psi_decode(stream:ByteArray):void
- {
- // atleast 9B for PMT specified
- if (stream.bytesAvailable < 9) {
- throw new Error("ts: demux PMT failed.");
- }
-
- // 2B
- program_number = stream.readUnsignedShort();
-
- // 1B
- var cniv:int = stream.readUnsignedByte();
-
- const1_value0 = (cniv >> 6) & 0x03;
- version_number = (cniv >> 1) & 0x1F;
- current_next_indicator = cniv & 0x01;
-
- // 1B
- section_number = stream.readUnsignedByte();
-
- // 1B
- last_section_number = stream.readUnsignedByte();
-
- // 2B
- var ppv:int = stream.readUnsignedShort();
- const1_value1 = (ppv >> 13) & 0x07;
- PCR_PID = ppv & 0x1FFF;
-
- // 2B
- var pilv:int = stream.readUnsignedShort();
- const1_value2 = (pilv >> 12) & 0x0F;
- program_info_length = pilv & 0xFFF;
-
- if (program_info_length > 0) {
- if (stream.bytesAvailable < program_info_length) {
- throw new Error("ts: demux PMT program info failed.");
- }
-
- program_info_desc = new ByteArray();
- stream.readBytes(program_info_desc, 0, program_info_length);
- }
-
- // [section_length] - 4(CRC) - 9B - [program_info_length]
- var ES_EOF_pos:uint = stream.position + section_length - 4 - 9 - program_info_length;
- while (stream.position < ES_EOF_pos) {
- var info:SrsTsPayloadPMTESInfo = new SrsTsPayloadPMTESInfo(SrsTsStream.Reserved, 0);
- infos.push(info);
-
- info.decode(stream);
-
- // update the apply pid table
- switch (info.stream_type) {
- case SrsTsStream.VideoH264:
- case SrsTsStream.VideoMpeg4:
- packet.context.setChannel(info.elementary_PID, SrsTsPidApply.Video, info.stream_type);
- break;
- case SrsTsStream.AudioAAC:
- case SrsTsStream.AudioAC3:
- case SrsTsStream.AudioDTS:
- case SrsTsStream.AudioMp3:
- packet.context.setChannel(info.elementary_PID, SrsTsPidApply.Audio, info.stream_type);
- break;
- default:
- // warn("ts: drop pid=%#x, stream=%#x", info->elementary_PID, info->stream_type);
- break;
- }
- }
-
- // update the apply pid table.
- packet.context.setChannel(packet.pid, SrsTsPidApply.PMT, SrsTsStream.Reserved);
- packet.context.on_pmt_parsed();
- }
-};
-
-/**
- * the m3u8 parser.
- */
-class M3u8
-{
- private var _hls:HlsCodec;
- private var _log:ILogger = new TraceLogger("HLS");
-
- private var _tses:Array;
- private var _duration:Number;
- private var _seq_no:Number;
- private var _url:String;
- // when variant, all ts url is sub m3u8 url.
- private var _variant:Boolean;
-
- public function M3u8(hls:HlsCodec)
- {
- _hls = hls;
- _tses = new Array();
- _duration = 0;
- _seq_no = 0;
- _variant = false;
- }
-
- public function getTsUrl(index:Number):String
- {
- if (index >= _tses.length) {
- throw new Error("ts index overflow, index=" + index + ", max=" + _tses.length);
- }
-
- var url:String = _tses[index].url;
-
- // if absolute url, return.
- if (Utility.stringStartswith(url, "http://")) {
- return url;
- }
-
- // add prefix of m3u8.
- if (_url.lastIndexOf("/") >= 0) {
- url = _url.substr(0, _url.lastIndexOf("/") + 1) + url;
- }
- return url;
- }
-
- public function parse(url:String, v:String):void
- {
- // TODO: FIXME: reset the m3u8 when parse.
- _tses = new Array();
- _duration = 0;
- _url = url;
- _variant = false;
-
- var ptl:String = null;
- var td:Number = 0;
- var seq_no:Number = 0;
-
- var lines:Array = v.split("\n");
- for (var i:int = 0; i < lines.length; i++) {
- var line:String = String(lines[i]).replace("\r", "").replace(" ", "");
-
- // #EXT-X-VERSION:3
- // the version must be 3.0
- if (Utility.stringStartswith(line, "#EXT-X-VERSION:")) {
- if (!Utility.stringEndswith(line, ":3")) {
- _log.warn("m3u8 3.0 required, actual is {0}", line);
- }
- continue;
- }
-
- // #EXT-X-STREAM-INF:BANDWIDTH=3000000
- if (Utility.stringStartswith(line, "#EXT-X-STREAM-INF:")) {
- _variant = true;
- var sub_m3u8_url:String = lines[++i];
- _tses.push({
- duration: 0,
- url: sub_m3u8_url
- });
- continue;
- }
-
- // #EXT-X-PLAYLIST-TYPE:VOD
- // the playlist type, vod or nothing.
- if (Utility.stringStartswith(line, "#EXT-X-PLAYLIST-TYPE:")) {
- ptl = line;
- continue;
- }
-
- // #EXT-X-MEDIA-SEQUENCE:55
- // the seq no of first ts.
- if (Utility.stringStartswith(line, "#EXT-X-MEDIA-SEQUENCE:")) {
- seq_no = Number(line.substr("#EXT-X-MEDIA-SEQUENCE:".length));
- continue;
- }
-
- // #EXT-X-TARGETDURATION:12
- // the target duration is required.
- if (Utility.stringStartswith(line, "#EXT-X-TARGETDURATION:")) {
- td = Number(line.substr("#EXT-X-TARGETDURATION:".length));
- continue;
- }
-
- // #EXT-X-ENDLIST
- // parse completed.
- if (line == "#EXT-X-ENDLIST") {
- break;
- }
-
- // #EXTINF:11.401,
- // livestream-5.ts
- // parse each ts entry, expect current line is inf.
- if (!Utility.stringStartswith(line, "#EXTINF:")) {
- continue;
- }
- // expect next line is url.
- if (i >= lines.length - 1) {
- _log.warn("ts entry unexpected eof, inf={0}", line);
- break;
- }
- if (line.indexOf(",") >= 0) {
- line = line.split(",")[0];
- }
- var ts_duration:Number = Number(line.substr("#EXTINF:".length).replace(",", ""));
- var ts_url:String = lines[++i];
-
- _duration += ts_duration;
- _tses.push({
- duration: ts_duration,
- url: ts_url
- });
- }
- _seq_no = seq_no;
-
- // for vod, must specifies the playlist type to vod.
- if (false) {
- _log.warn("vod required the playlist type, actual is {0}", ptl);
- }
-
- if (false) {
- _log.info("hls got {0}B {1}L m3u8, td={2}, ts={3}", v.length, lines.length, td, _tses.length);
- } else {
- _log.debug("hls got {0}B {1}L m3u8, td={2}, ts={3}", v.length, lines.length, td, _tses.length);
- }
- }
-
- public function get tsCount():Number
- {
- return _tses.length;
- }
-
- public function get duration():Number
- {
- return _duration;
- }
-
- public function get seq_no():Number
- {
- return _seq_no;
- }
-
- public function get variant():Boolean
- {
- return _variant;
- }
-}
diff --git a/trunk/research/players/srs_player/src/Player.as b/trunk/research/players/srs_player/src/Player.as
deleted file mode 100644
index e085b683e..000000000
--- a/trunk/research/players/srs_player/src/Player.as
+++ /dev/null
@@ -1,210 +0,0 @@
-package
-{
- import flash.display.Sprite;
- import flash.display.StageAlign;
- import flash.display.StageDisplayState;
- import flash.display.StageScaleMode;
- import flash.events.Event;
- import flash.events.FullScreenEvent;
- import flash.events.MouseEvent;
- import flash.events.NetStatusEvent;
- import flash.events.TimerEvent;
- import flash.external.ExternalInterface;
- import flash.media.SoundTransform;
- import flash.media.Video;
- import flash.net.NetConnection;
- import flash.net.NetStream;
- import flash.net.URLVariables;
- import flash.system.Security;
- import flash.ui.ContextMenu;
- import flash.ui.ContextMenuItem;
- import flash.utils.Timer;
- import flash.utils.getTimer;
- import flash.utils.setTimeout;
-
- import flashx.textLayout.formats.Float;
-
- /**
- * common player to play rtmp/flv stream,
- * use system NetStream.
- */
- public class Player
- {
- // refresh every ts_fragment_seconds*M3u8RefreshRatio
- public static var M3u8RefreshRatio:Number = 0.3;
-
- // parse ts every this ms.
- public static var TsParseAsyncInterval:Number = 80;
-
- private var js_id:String = null;
-
- // play param url.
- private var user_url:String = null;
-
- private var media_stream:NetStream = null;
- private var media_conn:NetConnection = null;
-
- private var owner:srs_player = null;
-
- public function Player(o:srs_player) {
- owner = o;
- }
-
- public function init(flashvars:Object):void {
- this.js_id = flashvars.id;
- }
-
- public function stream():NetStream {
- return this.media_stream;
- }
-
- private function dumps_object(obj:Object):String {
- var smr:String = "";
- for (var k:String in obj) {
- smr += k + "=" + obj[k] + ", ";
- }
-
- return smr;
- }
-
- public function play(url:String):void {
- owner.on_player_status("init", "Ready to play");
-
- var streamName:String;
- this.user_url = url;
-
- this.media_conn = new NetConnection();
- this.media_conn.client = {};
- this.media_conn.client.onBWDone = function():void {};
- this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
- log("NetConnection: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
- + ", info is " + dumps_object(evt.info));
-
- if (evt.info.hasOwnProperty("data") && evt.info.data) {
- owner.on_player_metadata(evt.info.data);
- }
-
- // reject by server, maybe redirect.
- if (evt.info.code == "NetConnection.Connect.Rejected") {
- // RTMP 302 redirect.
- if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) {
- streamName = url.substr(url.lastIndexOf("/") + 1);
- url = evt.info.ex.redirect + "/" + streamName;
- log("Async RTMP 302 Redirect to: " + url);
-
- // notify server.
- media_conn.call("Redirected", null, evt.info.ex.redirect);
-
- // do 302.
- owner.on_player_302(url);
- return;
- }
-
- owner.on_player_status("rejected", "Server reject play");
- close();
- }
-
- if (evt.info.code == "NetConnection.Connect.Success") {
- owner.on_player_status("connected", "Connected at server");
- }
- if (evt.info.code == "NetConnection.Connect.Closed") {
- close();
- }
- if (evt.info.code == "NetConnection.Connect.Failed") {
- owner.on_player_status("failed", "Connect to server failed.");
- close();
- }
-
- // TODO: FIXME: failed event.
- if (evt.info.code != "NetConnection.Connect.Success") {
- return;
- }
-
- if (url.indexOf(".m3u8") > 0) {
- media_stream = new HlsNetStream(M3u8RefreshRatio, TsParseAsyncInterval, media_conn);
- } else {
- media_stream = new NetStream(media_conn);
- }
- media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
- log("NetStream: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
- + ", info is " + dumps_object(evt.info));
-
- if (evt.info.code == "NetStream.Play.Start") {
- owner.on_player_status("play", "Start to play stream");
- }
- if (evt.info.code == "NetStream.Play.StreamNotFound") {
- owner.on_player_status("rejected", "Stream not found");
- close();
- }
-
- if (evt.info.code == "NetStream.Video.DimensionChange") {
- owner.on_player_dimension_change();
- } else if (evt.info.code == "NetStream.Buffer.Empty") {
- owner.on_player_buffer_empty();
- } else if (evt.info.code == "NetStream.Buffer.Full") {
- owner.on_player_buffer_full();
- }
-
- // TODO: FIXME: failed event.
- });
-
- // setup stream before play.
- owner.on_player_before_play();
-
- if (url.indexOf("http") == 0) {
- media_stream.play(url);
- } else {
- streamName = url.substr(url.lastIndexOf("/") + 1);
- media_stream.play(streamName);
- }
-
- owner.on_player_play();
- });
-
- if (url.indexOf("http") == 0) {
- this.media_conn.connect(null);
- } else {
- var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/"));
- streamName = url.substr(url.lastIndexOf("/") + 1);
-
- // parse vhost from stream query.
- if (streamName.indexOf("?") >= 0) {
- var uv:URLVariables = new URLVariables(user_url.substr(user_url.indexOf("?") + 1));
- var domain:String = uv["domain"];
- if (!domain) {
- domain = uv["vhost"];
- }
- if (domain) {
- tcUrl += "?vhost=" + domain;
- }
- }
-
- this.media_conn.connect(tcUrl);
- }
- }
-
- public function close():void {
- var notify:Boolean = false;
-
- if (this.media_stream) {
- this.media_stream.close();
- this.media_stream = null;
- notify = true;
- }
-
- if (this.media_conn) {
- this.media_conn.close();
- this.media_conn = null;
- notify = true;
- }
-
- if (notify) {
- owner.on_player_status("closed", "Server closed.");
- }
- }
-
- private function log(msg:String):void {
- Utility.log(js_id, msg);
- }
- }
-}
\ No newline at end of file
diff --git a/trunk/research/players/srs_player/src/Utility.as b/trunk/research/players/srs_player/src/Utility.as
deleted file mode 100644
index 7707954c2..000000000
--- a/trunk/research/players/srs_player/src/Utility.as
+++ /dev/null
@@ -1,51 +0,0 @@
-package
-{
- import flash.external.ExternalInterface;
- import flash.utils.setTimeout;
-
- /**
- * the utility functions.
- */
- public class Utility
- {
- /**
- * total log.
- */
- public static var logData:String = "";
-
- /**
- * whether string s endswith f.
- */
- public static function stringEndswith(s:String, f:String):Boolean {
- return s && f && s.indexOf(f) == s.length - f.length;
- }
-
- /**
- * whether string s startswith f.
- */
- public static function stringStartswith(s:String, f:String):Boolean {
- return s && f && s.indexOf(f) == 0;
- }
-
- /**
- * write log to trace and console.log.
- * @param msg the log message.
- */
- public static function log(js_id:String, msg:String):void {
- if (js_id) {
- msg = "[" + new Date() +"][srs-player][" + js_id + "] " + msg;
- }
-
- logData += msg + "\n";
-
- trace(msg);
-
- if (!flash.external.ExternalInterface.available) {
- flash.utils.setTimeout(log, 300, null, msg);
- return;
- }
-
- ExternalInterface.call("console.log", msg);
- }
- }
-}
\ No newline at end of file
diff --git a/trunk/research/players/srs_player/src/srs_player.as b/trunk/research/players/srs_player/src/srs_player.as
deleted file mode 100755
index 9f0e424b8..000000000
--- a/trunk/research/players/srs_player/src/srs_player.as
+++ /dev/null
@@ -1,668 +0,0 @@
-package
-{
- import flash.display.Sprite;
- import flash.display.StageAlign;
- import flash.display.StageDisplayState;
- import flash.display.StageScaleMode;
- import flash.events.Event;
- import flash.events.FullScreenEvent;
- import flash.events.MouseEvent;
- import flash.events.NetStatusEvent;
- import flash.events.TimerEvent;
- import flash.external.ExternalInterface;
- import flash.media.SoundTransform;
- import flash.media.Video;
- import flash.net.NetConnection;
- import flash.net.NetStream;
- import flash.system.Security;
- import flash.ui.ContextMenu;
- import flash.ui.ContextMenuItem;
- import flash.utils.Timer;
- import flash.utils.getTimer;
- import flash.utils.setTimeout;
-
- import flashx.textLayout.formats.Float;
-
- public class srs_player extends Sprite
- {
- // user set id.
- private var js_id:String = null;
- // user set callback
- private var js_on_player_ready:String = null;
- private var js_on_player_metadata:String = null;
- private var js_on_player_timer:String = null;
- private var js_on_player_empty:String = null;
- private var js_on_player_full:String = null;
- private var js_on_player_status:String = null;
-
- // play param, user set width and height
- private var user_w:int = 0;
- private var user_h:int = 0;
- private var user_buffer_time:Number = 0;
- private var user_max_buffer_time:Number = 0;
- private var user_volume:Number = 0;
- // user set dar den:num
- private var user_dar_den:int = 0;
- private var user_dar_num:int = 0;
- // user set fs(fullscreen) refer and percent.
- private var user_fs_refer:String = null;
- private var user_fs_percent:int = 0;
-
- // media specified.
- private var media_video:Video = null;
- private var media_metadata:Object = {};
- private var media_timer:Timer = new Timer(300);
-
- // controls.
- // flash donot allow js to set to fullscreen,
- // only allow user click to enter fullscreen.
- private var control_fs_mask:Sprite = new Sprite();
-
- // the common player to play stream.
- private var player:Player = null;
- // the flashvars config.
- private var config:Object = null;
-
- public function srs_player()
- {
- if (!this.stage) {
- this.addEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage);
- } else {
- this.system_on_add_to_stage(null);
- }
- }
-
- /**
- * system event callback, when this control added to stage.
- * the main function.
- */
- private function system_on_add_to_stage(evt:Event):void {
- this.removeEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage);
-
- this.stage.align = StageAlign.TOP_LEFT;
- this.stage.scaleMode = StageScaleMode.NO_SCALE;
-
- this.stage.addEventListener(FullScreenEvent.FULL_SCREEN, this.user_on_stage_fullscreen);
-
- Security.allowDomain("*");
-
- this.addChild(this.control_fs_mask);
- this.control_fs_mask.buttonMode = true;
- this.control_fs_mask.addEventListener(MouseEvent.CLICK, user_on_click_video);
-
- this.contextMenu = new ContextMenu();
- this.contextMenu.hideBuiltInItems();
-
- var flashvars:Object = this.root.loaderInfo.parameters;
-
- if (!flashvars.hasOwnProperty("id")) {
- throw new Error("must specifies the id");
- }
-
- this.config = flashvars;
- this.js_id = flashvars.id;
- this.js_on_player_ready = flashvars.on_player_ready;
- this.js_on_player_metadata = flashvars.on_player_metadata;
- this.js_on_player_timer = flashvars.on_player_timer;
- this.js_on_player_empty = flashvars.on_player_empty;
- this.js_on_player_full = flashvars.on_player_full;
- this.js_on_player_status = flashvars.on_player_status;
-
- this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer);
- this.media_timer.start();
-
- flash.utils.setTimeout(this.system_on_js_ready, 0);
- }
-
- /**
- * system callack event, when js ready, register callback for js.
- * the actual main function.
- */
- private function system_on_js_ready():void {
- if (!flash.external.ExternalInterface.available) {
- log("js not ready, try later.");
- flash.utils.setTimeout(this.system_on_js_ready, 100);
- return;
- }
-
- flash.external.ExternalInterface.addCallback("__play", this.js_call_play);
- flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop);
- flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause);
- flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume);
- flash.external.ExternalInterface.addCallback("__set_dar", this.js_call_set_dar);
- flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size);
- flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt);
- flash.external.ExternalInterface.addCallback("__set_mbt", this.js_call_set_mbt);
- flash.external.ExternalInterface.addCallback("__dump_log", this.js_call_dump_log);
-
- flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id);
- }
-
- /**
- * system callack event, timer to do some regular tasks.
- */
- private function system_on_timer(evt:TimerEvent):void {
- if (!player) {
- return;
- }
-
- var ms:NetStream = player.stream();
-
- if (!ms) {
- //log("stream is null, ignore timer event.");
- return;
- }
-
- var rtime:Number = flash.utils.getTimer();
- var bitrate:Number = Number((ms.info.videoBytesPerSecond + ms.info.audioBytesPerSecond) * 8 / 1000);
- log("on timer, time=" + ms.time.toFixed(2) + "s, buffer=" + ms.bufferLength.toFixed(2) + "s"
- + ", bitrate=" + bitrate.toFixed(1) + "kbps"
- + ", fps=" + ms.currentFPS.toFixed(1)
- + ", rtime=" + rtime.toFixed(0)
- );
- flash.external.ExternalInterface.call(
- this.js_on_player_timer, this.js_id, ms.time, ms.bufferLength,
- bitrate, ms.currentFPS, rtime
- );
- }
-
- /**
- * system callback event, when stream is empty.
- */
- private function system_on_buffer_empty():void {
- var time:Number = flash.utils.getTimer();
- log("stream is empty at " + time + "ms");
- flash.external.ExternalInterface.call(this.js_on_player_empty, this.js_id, time);
- }
- private function system_on_buffer_full():void {
- var time:Number = flash.utils.getTimer();
- log("stream is full at " + time + "ms");
- flash.external.ExternalInterface.call(this.js_on_player_full, this.js_id, time);
- }
-
- /**
- * system callack event, when got metadata from stream.
- * or got video dimension change event(the DAR notification), to update the metadata manually.
- */
- private function system_on_metadata(metadata:Object):void {
- if (!media_metadata) {
- media_metadata = {};
- }
- for (var k:String in metadata) {
- media_metadata[k] = metadata[k];
- }
-
- // update the debug info.
- on_debug_info(media_metadata);
- update_context_items();
-
- // for js.
- var obj:Object = __get_video_size_object();
-
- obj.server = 'srs';
- obj.contributor = 'winlin';
-
- if (srs_server != null) {
- obj.server = srs_server;
- }
- if (srs_primary != null) {
- obj.contributor = srs_primary;
- }
- if (srs_authors != null) {
- obj.contributor = srs_authors;
- }
- if (srs_id != null) {
- obj.cid = srs_id;
- }
- if (srs_pid != null) {
- obj.pid = srs_pid;
- }
- if (srs_server_ip != null) {
- obj.ip = srs_server_ip;
- }
-
- var s:String = "";
- for (var key:String in obj) {
- s += key + "=" + obj[key] + " ";
- }
- log("metadata is " + s);
-
- var code:int = flash.external.ExternalInterface.call(js_on_player_metadata, js_id, obj);
- if (code != 0) {
- throw new Error("callback on_player_metadata failed. code=" + code);
- }
- }
-
- /**
- * player callack event, when user click video to enter or leave fullscreen.
- */
- private function user_on_stage_fullscreen(evt:FullScreenEvent):void {
- if (!evt.fullScreen) {
- __execute_user_set_dar();
- } else {
- __execute_user_enter_fullscreen();
- }
- }
-
- /**
- * user event callback, js cannot enter the fullscreen mode, user must click to.
- */
- private function user_on_click_video(evt:MouseEvent):void {
- if (!this.stage.allowsFullScreen) {
- log("donot allow fullscreen.");
- return;
- }
-
- // enter fullscreen to get the fullscreen size correctly.
- if (this.stage.displayState == StageDisplayState.FULL_SCREEN) {
- this.stage.displayState = StageDisplayState.NORMAL;
- } else {
- this.stage.displayState = StageDisplayState.FULL_SCREEN;
- }
- }
-
- /**
- * function for js to call: to pause the stream. ignore if not play.
- */
- private function js_call_pause():void {
- if (player && player.stream()) {
- player.stream().pause();
- log("user pause play");
- }
- }
-
- /**
- * function for js to call: to resume the stream. ignore if not play.
- */
- private function js_call_resume():void {
- if (player && player.stream()) {
- player.stream().resume();
- log("user resume play");
- }
- }
-
- /**
- * dumps all log data.
- */
- private function js_call_dump_log():String {
- return Utility.logData;
- }
-
- /**
- * to set the DAR, for example, DAR=16:9 where num=16,den=9.
- * @param num, for example, 16.
- * use metadata width if 0.
- * use user specified width if -1.
- * @param den, for example, 9.
- * use metadata height if 0.
- * use user specified height if -1.
- */
- private function js_call_set_dar(num:int, den:int):void {
- user_dar_num = num;
- user_dar_den = den;
-
- flash.utils.setTimeout(__execute_user_set_dar, 0);
- log("user set dar to " + num + "/" + den);
- }
-
- /**
- * set the fullscreen size data.
- * @refer the refer fullscreen mode. it can be:
- * video: use video orignal size.
- * screen: use screen size to rescale video.
- * @param percent, the rescale percent, where
- * 100 means 100%.
- */
- private function js_call_set_fs_size(refer:String, percent:int):void {
- user_fs_refer = refer;
- user_fs_percent = percent;
- log("user set refer to " + refer + ", percent to" + percent);
- }
-
- /**
- * set the stream buffer time in seconds.
- * @buffer_time the buffer time in seconds.
- */
- private function js_call_set_bt(buffer_time:Number):void {
- if (player && player.stream()) {
- player.stream().bufferTime = buffer_time;
- log("user set bufferTime to " + buffer_time.toFixed(2) + "s");
- }
- }
-
- /**
- * set the max stream buffer time in seconds.
- * @max_buffer_time the max buffer time in seconds.
- * @remark this is the key feature for realtime communication by flash.
- */
- private function js_call_set_mbt(max_buffer_time:Number):void {
- if (player && player.stream()) {
- player.stream().bufferTimeMax = max_buffer_time;
- log("user set bufferTimeMax to " + max_buffer_time.toFixed(2) + "s");
- }
- }
-
- /**
- * function for js to call: to stop the stream. ignore if not play.
- */
- private function js_call_stop():void {
- if (this.media_video) {
- this.removeChild(this.media_video);
- this.media_video = null;
- }
-
- if (player) {
- player.close();
- player = null;
- }
- log("player stopped");
- }
-
- // srs infos
- private var srs_server:String = null;
- private var srs_primary:String = null;
- private var srs_authors:String = null;
- private var srs_id:String = null;
- private var srs_pid:String = null;
- private var srs_server_ip:String = null;
- private function update_context_items():void {
- // for context menu
- var customItems:Array = [new ContextMenuItem("SrsPlayer")];
- if (srs_server != null) {
- customItems.push(new ContextMenuItem("Server: " + srs_server));
- }
- if (srs_primary != null) {
- customItems.push(new ContextMenuItem("Primary: " + srs_primary));
- }
- if (srs_authors != null) {
- customItems.push(new ContextMenuItem("Authors: " + srs_authors));
- }
- if (srs_server_ip != null) {
- customItems.push(new ContextMenuItem("SrsIp: " + srs_server_ip));
- }
- if (srs_pid != null) {
- customItems.push(new ContextMenuItem("SrsPid: " + srs_pid));
- }
- if (srs_id != null) {
- customItems.push(new ContextMenuItem("SrsId: " + srs_id));
- }
- contextMenu.customItems = customItems;
- }
-
- /**
- * server can set the debug info in _result of RTMP connect, or metadata.
- */
- private function on_debug_info(data:*):void {
- if (data.hasOwnProperty("srs_server")) {
- srs_server = data.srs_server;
- }
- if (data.hasOwnProperty("srs_primary")) {
- srs_primary = data.srs_primary;
- }
- if (data.hasOwnProperty("srs_authors")) {
- srs_authors = data.srs_authors;
- }
- if (data.hasOwnProperty("srs_id")) {
- srs_id = data.srs_id;
- }
- if (data.hasOwnProperty("srs_pid")) {
- srs_pid = data.srs_pid;
- }
- if (data.hasOwnProperty("srs_server_ip")) {
- srs_server_ip = data.srs_server_ip;
- }
- }
-
- /**
- * function for js to call: to play the stream. stop then play.
- * @param url, the rtmp/http url to play.
- * @param _width, the player width.
- * @param _height, the player height.
- * @param buffer_time, the buffer time in seconds. recommend to >=0.5
- * @param max_buffer_time, the max buffer time in seconds. recommend to 3 x buffer_time.
- * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%.
- */
- private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, max_buffer_time:Number, volume:Number):void {
- this.user_w = _width;
- this.user_h = _height;
- this.user_buffer_time = buffer_time;
- this.user_max_buffer_time = max_buffer_time;
- this.user_volume = volume;
- log("start to play url: " + url + ", w=" + this.user_w + ", h=" + this.user_h
- + ", buffer=" + buffer_time.toFixed(2) + "s, max_buffer=" + max_buffer_time.toFixed(2) + "s, volume=" + volume.toFixed(2)
- );
-
- js_call_stop();
-
- // trim last ?
- while (Utility.stringEndswith(url, "?")) {
- url = url.substr(0, url.length - 1);
- }
-
- // create player.
- player = new Player(this);
-
- // init player by config.
- player.init(config);
-
- // play the url.
- player.play(url);
- }
- public function on_player_before_play():void {
- if (!player) {
- return;
- }
-
- var ms:NetStream = player.stream();
- if (!ms) {
- return;
- }
-
- ms.soundTransform = new SoundTransform(user_volume);
- ms.bufferTime = user_buffer_time;
- ms.bufferTimeMax = user_max_buffer_time;
- ms.client = {};
- ms.client.onMetaData = system_on_metadata;
- }
- public function on_player_play():void {
- if (!player) {
- return;
- }
-
- media_video = new Video();
- media_video.width = user_w;
- media_video.height = user_h;
- media_video.attachNetStream(player.stream());
- media_video.smoothing = true;
- addChild(media_video);
-
- __draw_black_background(user_w, user_h);
-
- // lowest layer, for mask to cover it.
- setChildIndex(media_video, 0);
- }
- public function on_player_metadata(data:Object):void {
- system_on_metadata(data);
- }
- public function on_player_302(url:String):void {
- setTimeout(function():void{
- log("Async RTMP 302 Redirected.");
- js_call_play(url, user_w, user_h, user_buffer_time, user_max_buffer_time, user_volume);
- }, 1000);
- }
- public function on_player_dimension_change():void {
- system_on_metadata(media_metadata);
- }
- public function on_player_buffer_empty():void {
- system_on_buffer_empty();
- }
- public function on_player_buffer_full():void {
- system_on_buffer_full();
- }
-
- public function on_player_status(code:String, desc:String):void {
- log("[STATUS] code=" + code + ", desc=" + desc);
- flash.external.ExternalInterface.call(this.js_on_player_status, this.js_id, code, desc);
- }
-
- /**
- * get the "right" size of video,
- * 1. initialize with the original video object size.
- * 2. override with metadata size if specified.
- * 3. override with codec size if specified.
- */
- private function __get_video_size_object():Object {
- if (!media_video) {
- return {};
- }
- var obj:Object = {
- width: media_video.width,
- height: media_video.height
- };
-
- // override with metadata size.
- if (this.media_metadata.hasOwnProperty("width")) {
- obj.width = this.media_metadata.width;
- }
- if (this.media_metadata.hasOwnProperty("height")) {
- obj.height = this.media_metadata.height;
- }
-
- // override with codec size.
- if (media_video.videoWidth > 0) {
- obj.width = media_video.videoWidth;
- }
- if (media_video.videoHeight > 0) {
- obj.height = media_video.videoHeight;
- }
-
- return obj;
- }
-
- /**
- * execute the enter fullscreen action.
- */
- private function __execute_user_enter_fullscreen():void {
- if (!user_fs_refer || user_fs_percent <= 0) {
- return;
- }
-
- // change to video size if refer to video.
- var obj:Object = __get_video_size_object();
-
- // get the DAR
- var den:int = user_dar_den;
- var num:int = user_dar_num;
-
- if (den == 0) {
- den = obj.height;
- }
- if (den == -1) {
- den = this.stage.fullScreenHeight;
- }
-
- if (num == 0) {
- num = obj.width;
- }
- if (num == -1) {
- num = this.stage.fullScreenWidth;
- }
-
- // for refer is screen.
- if (user_fs_refer == "screen") {
- obj = {
- width: this.stage.fullScreenWidth,
- height: this.stage.fullScreenHeight
- };
- }
-
- // rescale to fs
- __update_video_size(num, den,
- obj.width * user_fs_percent / 100,
- obj.height * user_fs_percent / 100,
- this.stage.fullScreenWidth, this.stage.fullScreenHeight
- );
- }
-
- /**
- * for user set dar, or leave fullscreen to recover the dar.
- */
- private function __execute_user_set_dar():void {
- // get the DAR
- var den:int = user_dar_den;
- var num:int = user_dar_num;
-
- var obj:Object = __get_video_size_object();
-
- if (den == 0) {
- den = obj.height;
- }
- if (den == -1) {
- den = this.user_h;
- }
-
- if (num == 0) {
- num = obj.width;
- }
- if (num == -1) {
- num = this.user_w;
- }
-
- __update_video_size(num, den, this.user_w, this.user_h, this.user_w, this.user_h);
- }
-
- /**
- * update the video width and height,
- * according to the specifies DAR(den:num) and max size(w:h).
- * set the position of video(x,y) specifies by size(sw:sh),
- * and update the bg to size(sw:sh).
- * @param _num/_den the DAR. use to rescale the player together with paper size.
- * @param _w/_h the video draw paper size. used to rescale the player together with DAR.
- * @param _sw/_wh the stage size, >= paper size. used to center the player.
- */
- private function __update_video_size(_num:int, _den:int, _w:int, _h:int, _sw:int, _sh:int):void {
- if (!this.media_video || _den <= 0 || _num <= 0) {
- return;
- }
-
- // set DAR.
- // calc the height by DAR
- var _height:int = _w * _den / _num;
- if (_height <= _h) {
- this.media_video.width = _w;
- this.media_video.height = _height;
- } else {
- // height overflow, calc the width by DAR
- var _width:int = _h * _num / _den;
-
- this.media_video.width = _width;
- this.media_video.height = _h;
- }
-
- // align center.
- this.media_video.x = (_sw - this.media_video.width) / 2;
- this.media_video.y = (_sh - this.media_video.height) / 2;
-
- __draw_black_background(_sw, _sh);
- }
-
- /**
- * draw black background and draw the fullscreen mask.
- */
- private function __draw_black_background(_width:int, _height:int):void {
- // draw black bg.
- this.graphics.beginFill(0x00, 1.0);
- this.graphics.drawRect(0, 0, _width, _height);
- this.graphics.endFill();
-
- // draw the fs mask.
- this.control_fs_mask.graphics.beginFill(0xff0000, 0);
- this.control_fs_mask.graphics.drawRect(0, 0, _width, _height);
- this.control_fs_mask.graphics.endFill();
- }
-
- private function log(msg:String):void {
- Utility.log(js_id, msg);
- }
- }
-}
diff --git a/trunk/research/players/srs_publisher.html b/trunk/research/players/srs_publisher.html
deleted file mode 100644
index e113b50f8..000000000
--- a/trunk/research/players/srs_publisher.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
- SRS
-
-
-
-
-
-
-