m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();
\ No newline at end of file
diff --git a/js/msp.js b/js/msp.js
index e45ac87c..1cdc18c0 100644
--- a/js/msp.js
+++ b/js/msp.js
@@ -51,7 +51,7 @@ var MSP_codes = {
MSP_PIDNAMES: 117,
MSP_WP: 118,
MSP_BOXIDS: 119,
- MSP_SERVO_CONF: 120,
+ MSP_SERVO_CONFIGURATIONS: 120,
MSP_SET_RAW_RC: 200,
MSP_SET_RAW_GPS: 201,
@@ -65,10 +65,13 @@ var MSP_codes = {
MSP_SET_WP: 209,
MSP_SELECT_SETTING: 210,
MSP_SET_HEAD: 211,
- MSP_SET_SERVO_CONF: 212,
+ MSP_SET_SERVO_CONFIGURATION: 212,
MSP_SET_MOTOR: 214,
// MSP_BIND: 240,
+
+ MSP_SERVO_MIX_RULES: 241,
+ MSP_SET_SERVO_MIX_RULE: 242,
MSP_EEPROM_WRITE: 250,
@@ -80,7 +83,7 @@ var MSP_codes = {
MSP_ACC_TRIM: 240, // get acc angle trim values
MSP_SET_ACC_TRIM: 239, // set acc angle trim values
MSP_GPS_SV_INFO: 164, // get Signal Strength
-
+
// Additional private MSP for baseflight configurator (yes thats us \o/)
MSP_RX_MAP: 64, // get channel map (also returns number of channels total)
MSP_SET_RX_MAP: 65, // set rc map, numchannels to set comes from MSP_RX_MAP
@@ -102,6 +105,7 @@ var MSP = {
callbacks: [],
packet_error: 0,
+ unsupported: 0,
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
ledFunctionLetters: ['i', 'w', 'f', 'a', 't', 'r', 'c'], // in LSB bit order
@@ -138,10 +142,14 @@ var MSP = {
}
break;
case 2: // direction (should be >)
+ this.unsupported = 0;
if (data[i] == 62) { // >
this.message_direction = 1;
- } else { // <
+ } else if (data[i] == 60) { // <
this.message_direction = 0;
+ } else if (data[i] == 33) { // !
+ // FC reports unsupported message error
+ this.unsupported = 1;
}
this.state++;
@@ -202,7 +210,7 @@ var MSP = {
process_data: function (code, message_buffer, message_length) {
var data = new DataView(message_buffer, 0); // DataView (allowing us to view arrayBuffer as struct/union)
- switch (code) {
+ if (!this.unsupported) switch (code) {
case MSP_codes.MSP_IDENT:
console.log('Using deprecated msp command: MSP_IDENT');
// Deprecated
@@ -377,7 +385,6 @@ var MSP = {
}
break;
case MSP_codes.MSP_MISC: // 22 bytes
-<<<<<<< HEAD
var offset = 0;
MISC.midrc = data.getInt16(offset, 1);
offset += 2;
@@ -401,24 +408,6 @@ var MSP = {
MISC.vbatmincellvoltage = data.getUint8(offset++, 1) / 10; // 10-50
MISC.vbatmaxcellvoltage = data.getUint8(offset++, 1) / 10; // 10-50
MISC.vbatwarningcellvoltage = data.getUint8(offset++, 1) / 10; // 10-50
-=======
- MISC.midrc = data.getInt16(0, 1);
- MISC.minthrottle = data.getUint16(2, 1); // 0-2000
- MISC.maxthrottle = data.getUint16(4, 1); // 0-2000
- MISC.mincommand = data.getUint16(6, 1); // 0-2000
- MISC.failsafe_throttle = data.getUint16(8, 1); // 1000-2000
- MISC.gps_type = data.getUint8(10);
- MISC.gps_baudrate = data.getUint8(11);
- MISC.gps_ubx_sbas = data.getInt8(12);
- MISC.multiwiicurrentoutput = data.getUint8(13);
- MISC.rssi_aux_channel = data.getUint8(14);
- MISC.placeholder2 = data.getUint8(15);
- MISC.mag_declination = data.getInt16(16, 1) / 10; // -18000-18000
- MISC.vbatscale = data.getUint8(18, 1); // 10-200
- MISC.vbatmincellvoltage = data.getUint8(19, 1) / 10; // 10-50
- MISC.vbatmaxcellvoltage = data.getUint8(20, 1) / 10; // 10-50
- MISC.vbatwarningcellvoltage = data.getUint8(21, 1) / 10; // 10-50
->>>>>>> origin/baseflight-configurator-development
break;
case MSP_codes.MSP_MOTOR_PINS:
console.log(data);
@@ -463,19 +452,52 @@ var MSP = {
AUX_CONFIG_IDS.push(data.getUint8(i));
}
break;
- case MSP_codes.MSP_SERVO_CONF:
+ case MSP_codes.MSP_SERVO_MIX_RULES:
+ break;
+
+ case MSP_codes.MSP_SERVO_CONFIGURATIONS:
SERVO_CONFIG = []; // empty the array as new data is coming in
- if (data.byteLength % 7 == 0) {
- for (var i = 0; i < data.byteLength; i += 7) {
- var arr = {
- 'min': data.getInt16(i, 1),
- 'max': data.getInt16(i + 2, 1),
- 'middle': data.getInt16(i + 4, 1),
- 'rate': data.getInt8(i + 6)
- };
-
- SERVO_CONFIG.push(arr);
+ if (semver.gte(CONFIG.apiVersion, "1.12.0")) {
+ if (data.byteLength % 14 == 0) {
+ for (var i = 0; i < data.byteLength; i += 14) {
+ var arr = {
+ 'min': data.getInt16(i + 0, 1),
+ 'max': data.getInt16(i + 2, 1),
+ 'middle': data.getInt16(i + 4, 1),
+ 'rate': data.getInt8(i + 6),
+ 'angleAtMin': data.getInt8(i + 7),
+ 'angleAtMax': data.getInt8(i + 8),
+ 'indexOfChannelToForward': data.getInt8(i + 9),
+ 'reversedInputSources': data.getUint32(i + 10)
+ };
+
+ SERVO_CONFIG.push(arr);
+ }
+ }
+ } else {
+ if (data.byteLength % 7 == 0) {
+ for (var i = 0; i < data.byteLength; i += 7) {
+ var arr = {
+ 'min': data.getInt16(i + 0, 1),
+ 'max': data.getInt16(i + 2, 1),
+ 'middle': data.getInt16(i + 4, 1),
+ 'rate': data.getInt8(i + 6),
+ 'angleAtMin': 90,
+ 'angleAtMax': 90,
+ 'indexOfChannelToForward': undefined,
+ 'reversedInputSources': 0
+ };
+
+ SERVO_CONFIG.push(arr);
+ }
+ }
+
+ if (semver.eq(CONFIG.apiVersion, '1.10.0')) {
+ // drop two unused servo configurations due to MSP rx buffer to small)
+ while (SERVO_CONFIG.length > 8) {
+ SERVO_CONFIG.pop();
+ }
}
}
break;
@@ -509,7 +531,7 @@ var MSP = {
case MSP_codes.MSP_SELECT_SETTING:
console.log('Profile selected');
break;
- case MSP_codes.MSP_SET_SERVO_CONF:
+ case MSP_codes.MSP_SET_SERVO_CONFIGURATION:
console.log('Servo Configuration saved');
break;
case MSP_codes.MSP_EEPROM_WRITE:
@@ -817,6 +839,8 @@ var MSP = {
default:
console.log('Unknown code detected: ' + code);
+ } else {
+ console.log('FC reports unsupported message error: ' + code);
}
// trigger callbacks, cleanup/remove callback after trigger
@@ -963,43 +987,43 @@ MSP.crunch = function (code) {
case 7:
case 8:
case 9:
- buffer.push(parseInt(PIDs[i][0] * 10));
- buffer.push(parseInt(PIDs[i][1] * 1000));
+ buffer.push(Math.round(PIDs[i][0] * 10));
+ buffer.push(Math.round(PIDs[i][1] * 1000));
buffer.push(parseInt(PIDs[i][2]));
break;
case 4:
- buffer.push(parseInt(PIDs[i][0] * 100));
- buffer.push(parseInt(PIDs[i][1] * 100));
+ buffer.push(Math.round(PIDs[i][0] * 100));
+ buffer.push(Math.round(PIDs[i][1] * 100));
buffer.push(parseInt(PIDs[i][2]));
break;
case 5:
case 6:
- buffer.push(parseInt(PIDs[i][0] * 10));
- buffer.push(parseInt(PIDs[i][1] * 100));
- buffer.push(parseInt(PIDs[i][2] * 1000));
+ buffer.push(Math.round(PIDs[i][0] * 10));
+ buffer.push(Math.round(PIDs[i][1] * 100));
+ buffer.push(Math.round(PIDs[i][2] * 1000));
break;
}
}
break;
case MSP_codes.MSP_SET_RC_TUNING:
- buffer.push(parseInt(RC_tuning.RC_RATE * 100));
- buffer.push(parseInt(RC_tuning.RC_EXPO * 100));
+ buffer.push(Math.round(RC_tuning.RC_RATE * 100));
+ buffer.push(Math.round(RC_tuning.RC_EXPO * 100));
if (semver.lt(CONFIG.apiVersion, "1.7.0")) {
- buffer.push(parseInt(RC_tuning.roll_pitch_rate * 100));
+ buffer.push(Math.round(RC_tuning.roll_pitch_rate * 100));
} else {
- buffer.push(parseInt(RC_tuning.roll_rate * 100));
- buffer.push(parseInt(RC_tuning.pitch_rate * 100));
+ buffer.push(Math.round(RC_tuning.roll_rate * 100));
+ buffer.push(Math.round(RC_tuning.pitch_rate * 100));
}
- buffer.push(parseInt(RC_tuning.yaw_rate * 100));
- buffer.push(parseInt(RC_tuning.dynamic_THR_PID * 100));
- buffer.push(parseInt(RC_tuning.throttle_MID * 100));
- buffer.push(parseInt(RC_tuning.throttle_EXPO * 100));
+ buffer.push(Math.round(RC_tuning.yaw_rate * 100));
+ buffer.push(Math.round(RC_tuning.dynamic_THR_PID * 100));
+ buffer.push(Math.round(RC_tuning.throttle_MID * 100));
+ buffer.push(Math.round(RC_tuning.throttle_EXPO * 100));
if (semver.gte(CONFIG.apiVersion, "1.7.0")) {
buffer.push(lowByte(RC_tuning.dynamic_THR_breakpoint));
buffer.push(highByte(RC_tuning.dynamic_THR_breakpoint));
}
if (semver.gte(CONFIG.apiVersion, "1.10.0")) {
- buffer.push(parseInt(RC_tuning.RC_YAW_EXPO * 100));
+ buffer.push(Math.round(RC_tuning.RC_YAW_EXPO * 100));
}
break;
// Disabled, cleanflight does not use MSP_SET_BOX.
@@ -1047,26 +1071,12 @@ MSP.crunch = function (code) {
buffer.push(MISC.multiwiicurrentoutput);
buffer.push(MISC.rssi_channel);
buffer.push(MISC.placeholder2);
- buffer.push(lowByte(MISC.mag_declination * 10));
- buffer.push(highByte(MISC.mag_declination * 10));
+ buffer.push(lowByte(Math.round(MISC.mag_declination * 10)));
+ buffer.push(highByte(Math.round(MISC.mag_declination * 10)));
buffer.push(MISC.vbatscale);
- buffer.push(MISC.vbatmincellvoltage * 10);
- buffer.push(MISC.vbatmaxcellvoltage * 10);
- buffer.push(MISC.vbatwarningcellvoltage * 10);
- break;
- case MSP_codes.MSP_SET_SERVO_CONF:
- for (var i = 0; i < SERVO_CONFIG.length; i++) {
- buffer.push(lowByte(SERVO_CONFIG[i].min));
- buffer.push(highByte(SERVO_CONFIG[i].min));
-
- buffer.push(lowByte(SERVO_CONFIG[i].max));
- buffer.push(highByte(SERVO_CONFIG[i].max));
-
- buffer.push(lowByte(SERVO_CONFIG[i].middle));
- buffer.push(highByte(SERVO_CONFIG[i].middle));
-
- buffer.push(lowByte(SERVO_CONFIG[i].rate));
- }
+ buffer.push(Math.round(MISC.vbatmincellvoltage * 10));
+ buffer.push(Math.round(MISC.vbatmaxcellvoltage * 10));
+ buffer.push(Math.round(MISC.vbatwarningcellvoltage * 10));
break;
case MSP_codes.MSP_SET_CHANNEL_FORWARDING:
for (var i = 0; i < SERVO_CONFIG.length; i++) {
@@ -1127,6 +1137,22 @@ MSP.crunch = function (code) {
return buffer;
};
+/**
+ * Set raw Rx values over MSP protocol.
+ *
+ * Channels is an array of 16-bit unsigned integer channel values to be sent. 8 channels is probably the maximum.
+ */
+MSP.setRawRx = function(channels) {
+ var buffer = [];
+
+ for (var i = 0; i < channels.length; i++) {
+ buffer.push(specificByte(channels[i], 0));
+ buffer.push(specificByte(channels[i], 1));
+ }
+
+ MSP.send_message(MSP_codes.MSP_SET_RAW_RC, buffer, false);
+}
+
/**
* Send a request to read a block of data from the dataflash at the given address and pass that address and a dataview
* of the returned data to the given callback (or null for the data if an error occured).
@@ -1147,7 +1173,102 @@ MSP.dataflashRead = function(address, onDataCallback) {
onDataCallback(address, null);
}
});
-} ;
+};
+
+MSP.sendServoMixRules = function(onCompleteCallback) {
+ // TODO implement
+ onCompleteCallback();
+};
+
+MSP.sendServoConfigurations = function(onCompleteCallback) {
+ var nextFunction = send_next_servo_configuration;
+
+ var servoIndex = 0;
+
+ if (SERVO_CONFIG.length == 0) {
+ onCompleteCallback();
+ }
+
+ nextFunction();
+
+ function send_next_servo_configuration() {
+
+ var buffer = [];
+
+ if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
+ // send all in one go
+ // 1.9.0 had a bug where the MSP input buffer was too small, limit to 8.
+ for (var i = 0; i < SERVO_CONFIG.length && i < 8; i++) {
+ buffer.push(lowByte(SERVO_CONFIG[i].min));
+ buffer.push(highByte(SERVO_CONFIG[i].min));
+
+ buffer.push(lowByte(SERVO_CONFIG[i].max));
+ buffer.push(highByte(SERVO_CONFIG[i].max));
+
+ buffer.push(lowByte(SERVO_CONFIG[i].middle));
+ buffer.push(highByte(SERVO_CONFIG[i].middle));
+
+ buffer.push(lowByte(SERVO_CONFIG[i].rate));
+ }
+
+ nextFunction = send_channel_forwarding;
+ } else {
+ // send one at a time, with index
+
+ var servoConfiguration = SERVO_CONFIG[servoIndex];
+
+ buffer.push(servoIndex);
+
+ buffer.push(lowByte(servoConfiguration.min));
+ buffer.push(highByte(servoConfiguration.min));
+
+ buffer.push(lowByte(servoConfiguration.max));
+ buffer.push(highByte(servoConfiguration.max));
+
+ buffer.push(lowByte(servoConfiguration.middle));
+ buffer.push(highByte(servoConfiguration.middle));
+
+ buffer.push(lowByte(servoConfiguration.rate));
+
+ buffer.push(servoConfiguration.angleAtMin);
+ buffer.push(servoConfiguration.angleAtMax);
+
+ var out = servoConfiguration.indexOfChannelToForward;
+ if (out == undefined) {
+ out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF"
+ }
+ buffer.push(out);
+
+ buffer.push(specificByte(servoConfiguration.reversedInputSources, 0));
+ buffer.push(specificByte(servoConfiguration.reversedInputSources, 1));
+ buffer.push(specificByte(servoConfiguration.reversedInputSources, 2));
+ buffer.push(specificByte(servoConfiguration.reversedInputSources, 3));
+
+ // prepare for next iteration
+ servoIndex++;
+ if (servoIndex == SERVO_CONFIG.length) {
+ nextFunction = onCompleteCallback;
+ }
+ }
+ MSP.send_message(MSP_codes.MSP_SET_SERVO_CONFIGURATION, buffer, false, nextFunction);
+ }
+
+ function send_channel_forwarding() {
+ var buffer = [];
+
+ for (var i = 0; i < SERVO_CONFIG.length; i++) {
+ var out = SERVO_CONFIG[i].indexOfChannelToForward;
+ if (out == undefined) {
+ out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF"
+ }
+ buffer.push(out);
+ }
+
+ nextFunction = onCompleteCallback;
+
+ MSP.send_message(MSP_codes.MSP_SET_CHANNEL_FORWARDING, buffer, false, nextFunction);
+ }
+};
MSP.sendModeRanges = function(onCompleteCallback) {
var nextFunction = send_next_mode_range;
@@ -1165,12 +1286,12 @@ MSP.sendModeRanges = function(onCompleteCallback) {
var modeRange = MODE_RANGES[modeRangeIndex];
- var AUX_val_buffer_out = [];
- AUX_val_buffer_out.push(modeRangeIndex);
- AUX_val_buffer_out.push(modeRange.id);
- AUX_val_buffer_out.push(modeRange.auxChannelIndex);
- AUX_val_buffer_out.push((modeRange.range.start - 900) / 25);
- AUX_val_buffer_out.push((modeRange.range.end - 900) / 25);
+ var buffer = [];
+ buffer.push(modeRangeIndex);
+ buffer.push(modeRange.id);
+ buffer.push(modeRange.auxChannelIndex);
+ buffer.push((modeRange.range.start - 900) / 25);
+ buffer.push((modeRange.range.end - 900) / 25);
// prepare for next iteration
modeRangeIndex++;
@@ -1178,7 +1299,7 @@ MSP.sendModeRanges = function(onCompleteCallback) {
nextFunction = onCompleteCallback;
}
- MSP.send_message(MSP_codes.MSP_SET_MODE_RANGE, AUX_val_buffer_out, false, nextFunction);
+ MSP.send_message(MSP_codes.MSP_SET_MODE_RANGE, buffer, false, nextFunction);
}
};
@@ -1198,14 +1319,14 @@ MSP.sendAdjustmentRanges = function(onCompleteCallback) {
var adjustmentRange = ADJUSTMENT_RANGES[adjustmentRangeIndex];
- var ADJUSTMENT_val_buffer_out = [];
- ADJUSTMENT_val_buffer_out.push(adjustmentRangeIndex);
- ADJUSTMENT_val_buffer_out.push(adjustmentRange.slotIndex);
- ADJUSTMENT_val_buffer_out.push(adjustmentRange.auxChannelIndex);
- ADJUSTMENT_val_buffer_out.push((adjustmentRange.range.start - 900) / 25);
- ADJUSTMENT_val_buffer_out.push((adjustmentRange.range.end - 900) / 25);
- ADJUSTMENT_val_buffer_out.push(adjustmentRange.adjustmentFunction);
- ADJUSTMENT_val_buffer_out.push(adjustmentRange.auxSwitchChannelIndex);
+ var buffer = [];
+ buffer.push(adjustmentRangeIndex);
+ buffer.push(adjustmentRange.slotIndex);
+ buffer.push(adjustmentRange.auxChannelIndex);
+ buffer.push((adjustmentRange.range.start - 900) / 25);
+ buffer.push((adjustmentRange.range.end - 900) / 25);
+ buffer.push(adjustmentRange.adjustmentFunction);
+ buffer.push(adjustmentRange.auxSwitchChannelIndex);
// prepare for next iteration
adjustmentRangeIndex++;
@@ -1213,7 +1334,7 @@ MSP.sendAdjustmentRanges = function(onCompleteCallback) {
nextFunction = onCompleteCallback;
}
- MSP.send_message(MSP_codes.MSP_SET_ADJUSTMENT_RANGE, ADJUSTMENT_val_buffer_out, false, nextFunction);
+ MSP.send_message(MSP_codes.MSP_SET_ADJUSTMENT_RANGE, buffer, false, nextFunction);
}
};
diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js
index 3d4baf98..e9bdfb5b 100644
--- a/js/protocols/stm32.js
+++ b/js/protocols/stm32.js
@@ -4,8 +4,6 @@
Official "specs" are from 115200 to 1200
popular choices - 921600, 460800, 256000, 230400, 153600, 128000, 115200, 57600, 38400, 28800, 19200
-
- Documentation reference: http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf
*/
'use strict';
@@ -386,7 +384,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
break;
case 2:
// get version of the bootloader and supported commands
- self.send([self.command.get, self.command.get ^ 0xFF], 2, function (data) {
+ self.send([self.command.get, 0xFF], 2, function (data) { // 0x00 ^ 0xFF
if (self.verify_response(self.status.ACK, data)) {
self.retrieve(data[1] + 1 + 1, function (data) { // data[1] = number of bytes that will follow [– 1 except current and ACKs]
console.log('STM32 - Bootloader version: ' + (parseInt(data[0].toString(16)) / 10).toFixed(1)); // convert dec to hex, hex to dec and add floating point
@@ -401,7 +399,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
break;
case 3:
// get ID (device signature)
- self.send([self.command.get_ID, self.command.get_ID ^ 0xFF], 2, function (data) {
+ self.send([self.command.get_ID, 0xFD], 2, function (data) { // 0x01 ^ 0xFF
if (self.verify_response(self.status.ACK, data)) {
self.retrieve(data[1] + 1 + 1, function (data) { // data[1] = number of bytes that will follow [– 1 (N = 1 for STM32), except for current byte and ACKs]
var signature = (data[0] << 8) | data[1];
@@ -496,7 +494,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
console.log(message);
$('span.progressLabel').text(message + ' ...');
- self.send([self.command.erase, self.command.erase ^ 0xFF], 1, function (reply) {
+ self.send([self.command.erase, 0xBC], 1, function (reply) { // 0x43 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
self.send([0xFF, 0x00], 1, function (reply) {
if (self.verify_response(self.status.ACK, reply)) {
@@ -512,7 +510,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
console.log(message);
$('span.progressLabel').text(message + ' ...');
- self.send([self.command.erase, self.command.erase ^ 0xFF], 1, function (reply) {
+ self.send([self.command.erase, 0xBC], 1, function (reply) { // 0x43 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
// the bootloader receives one byte that contains N, the number of pages to be erased – 1
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
@@ -557,7 +555,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// console.log('STM32 - Writing to: 0x' + address.toString(16) + ', ' + bytes_to_write + ' bytes');
- self.send([self.command.write_memory, self.command.write_memory ^ 0xFF], 1, function (reply) {
+ self.send([self.command.write_memory, 0xCE], 1, function (reply) { // 0x31 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
// address needs to be transmitted as 32 bit integer, we need to bit shift each byte out and then calculate address checksum
var address_arr = [(address >> 24), (address >> 16), (address >> 8), address];
@@ -637,7 +635,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// console.log('STM32 - Reading from: 0x' + address.toString(16) + ', ' + bytes_to_read + ' bytes');
- self.send([self.command.read_memory, self.command.read_memory ^ 0xFF], 1, function (reply) {
+ self.send([self.command.read_memory, 0xEE], 1, function (reply) { // 0x11 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
var address_arr = [(address >> 24), (address >> 16), (address >> 8), address];
var address_checksum = address_arr[0] ^ address_arr[1] ^ address_arr[2] ^ address_arr[3];
@@ -721,7 +719,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// memory address = 4 bytes, 1st high byte, 4th low byte, 5th byte = checksum XOR(byte 1, byte 2, byte 3, byte 4)
console.log('Sending GO command: 0x8000000');
- self.send([self.command.go, self.command.go ^ 0xFF], 1, function (reply) {
+ self.send([self.command.go, 0xDE], 1, function (reply) { // 0x21 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
var gt_address = 0x8000000,
address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address],
diff --git a/main.html b/main.html
index 724d180c..fb9bc4b4 100755
--- a/main.html
+++ b/main.html
@@ -14,8 +14,7 @@
-
-
+
@@ -27,21 +26,14 @@
+
-
-
-
-
-
-
-<<<<<<< HEAD
-
-=======
->>>>>>> origin/baseflight-configurator-development
+
+
@@ -85,27 +77,20 @@
-
-
-
-