From 187d732a26c9ecf22f3805267443466fbee5f7c1 Mon Sep 17 00:00:00 2001 From: matthewcornell Date: Wed, 9 Sep 2026 11:32:18 -0400 Subject: [PATCH 1/4] fixes [Score tables use fixed decimal places (round) instead of significant figures (signif) #88] Score columns took their decimal count from the smallest value in the column and applied it to every value via toFixed(), so a column's significant figures tracked its minimum rather than its variation. On the flusight dashboard the wis__log column spans [0.19, 1.27]; one decimal cleared the old rule's "nothing rounds to zero" bar, so 21 of 58 models rendered as the same "0.3" while wis in the next column carried four digits nobody could act on. Replace min_decimals_for_values() with score_decimals(), which picks the decimals that resolve the column's variation -- two effective digits in Ehrenberg's sense (1977, JRSS A 140(3), 277-297) -- and caps how many significant figures the column may carry. get_round_decimals() keeps its name, signature, and its relative-skill and coverage special cases, and delegates the rest. Both magnitude anchors are quantiles rather than extremes. The spread is the IQR, since the range is set by the worst model but the comparison that matters is among the contenders at the top. The cap is anchored on Q3 rather than on the maximum, which is the one deviation from the code in the issue thread: a max-anchored cap lets one blown-up submission set the digit count for everyone, flattening a column of values near 1.0 to "0", "1", "1" the moment a 52000 appears -- the same failure the IQR anchoring exists to prevent, reintroduced one line later. Per the discussion on #88 there is no minSigFigs floor: WIS and MAE land at 0 decimals ("184", "393"), which is what both reviewers preferred over "183.7". The rule stays decimals-based rather than significant-figure-based on purpose. The issue suggested d3's .3~r / .3g, i.e. R's signif(), but that rounds left of the decimal point -- a national-scale MAE of 12345.6 would render as 12300. toFixed() never does, and the cap only ever removes decimals, bottoming out at 0, so every integer digit survives at national scale. Add render_score() for the per-cell string. Values too small to survive the column's rounding render as "<0.01" (or ">-0.01") rather than as a bare "0", which is what keeps a column-wide rule from claiming a real non-zero score is zero. That string is also why the table's render callback now guards on the DataTables type: render() runs for every type including sort, and "<0.01" in a sort key would silently switch the column to lexicographic ordering. Display and filter get the string, everything else gets the number. Both hovertemplates now consume pre-formatted customdata instead of interpolating a .Nf spec, so a hover value and its table cell can never disagree about rounding. The colorbar tickformat is unchanged. One judgment call worth flagging for review: zeros are filtered out of the magnitude anchors but still count toward the IQR, so [0, 1.5, 2.3, 47.7] gives 1 decimal where [1.5, 2.3, 47.7] gives 2. A zero is a real score and belongs in the column's distribution. It is pinned by a test either way. Tests replace the min_decimals_for_values module wholesale, since it asserted the min-anchored contract directly. The new modules cover the 58-value flusight wis__log fixture (7 distinct rendered strings before, 34 after), the national-scale case, and both outlier directions. test/ui.js gains a cell-rendering module covering column values -> decimals -> cell string end to end plus the sort-key regression; its DataTables stub is now a shared stubDataTable() helper that captures the handed-over config. Bundles rebuilt. Co-Authored-By: Claude Opus 5 (1M context) --- dev-example/predevals.bundle.js | 2 +- dist/predevals.bundle.js | 2 +- src/predevals.js | 24 ++++-- src/utils.js | 88 +++++++++++++++----- test/ui.js | 105 +++++++++++++++++++---- test/utils.js | 143 ++++++++++++++++++++++++-------- 6 files changed, 286 insertions(+), 78 deletions(-) diff --git a/dev-example/predevals.bundle.js b/dev-example/predevals.bundle.js index 88d1e43..7d7e383 100644 --- a/dev-example/predevals.bundle.js +++ b/dev-example/predevals.bundle.js @@ -1 +1 @@ -class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function B(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Be=[];function Ve(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Fe(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Bt(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Ft.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ye:Fe;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Fe(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Vn:Bn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Fn()(Rn,Rn);return e.copy=function(){return Yn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Fn()).domain([1,10]);return e.copy=()=>Yn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Vt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Pr(e)?2:Tr(e)||null===t?1:function(e){const t=e.filter(e=>null!=e&&isFinite(e)&&0!==e).map(e=>Math.abs(e));if(0===t.length)return 1;const n=Math.min(...t);return Math.max(1,Math.ceil(-Math.log10(n)-1e-10))}(t)}function Ar(e){return parseFloat(e.slice(18))}function Sr(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Er(e){const t=Sr(e);return t?t.base:e}function Dr(e){return"n"===e||e.startsWith("n_")}function Tr(e){return/^interval_coverage_/.test(e)}function Pr(e){return/_scaled_relative_skill$/.test(Er(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const Cr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function zr(e){if(Dr(e))return"N";if(Tr(e))return`${Ar(e)}% Cov.`;const t=Sr(e),n=t?t.base:e,r=Cr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Ir(e){return null==e?[]:Array.isArray(e)?e:[e]}function Or(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const Ur={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},jr="Number of predictions scored for the associated metric(s).",qr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Ir(e.metrics),relative_metrics:Ir(e.relative_metrics),disaggregate_by:Ir(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(zr(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Dr)}const n=[...new Set(e.map(Er))].map(function(e){const[t,n]=Ur[e]||["No definition available.",null],r=n?` `:"";return{term:zr(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${jr} Each N count refers to the metric column(s) to its left.`:jr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){qr.state.selected_target=this.value,qr.initializeDisaggregateByUI(),qr.initializeMetricUI(),qr.updateTransformPanel(),qr.updateGlossary(),qr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){qr.state.selected_eval_set=this.value,qr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){qr.state.selected_plot_type=this.value,qr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){qr.state.selected_disaggregate_by=this.value,qr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){qr.state.selected_metric=this.value,qr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(qr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),qr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>qr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Dr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(zr(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Dr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n);return{data:t,name:t,render:e=>e.toFixed(r)}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Or(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Or(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=zr(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${zr(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Tr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Tr(n=this.state.selected_metric)?Ar(n):Pr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l={x:s.map(e=>e[0]),y:s.map(e=>e[1]),mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${zr(this.state.selected_metric)}: %{y:.${i}f}`,opacity:.7};t.push(l)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Tr(e.selected_metric),n=Pr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Ar(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M,type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${zr(this.state.selected_metric)}: %{customdata:.${s}f}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Hr=qr;export{Hr as default}; \ No newline at end of file +class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=l(c,.75)-l(c,.25)||c[c.length-1]-c[0],u=l([...o].sort((e,t)=>e-t),.75),d=f>0?t-1-s(f):n-1-s(u),h=r-1-s(u);return Math.min(Math.max(d,0),Math.max(h,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file diff --git a/dist/predevals.bundle.js b/dist/predevals.bundle.js index 88d1e43..7d7e383 100644 --- a/dist/predevals.bundle.js +++ b/dist/predevals.bundle.js @@ -1 +1 @@ -class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function B(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Be=[];function Ve(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Fe(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Bt(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Ft.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ye:Fe;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Fe(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Vn:Bn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Fn()(Rn,Rn);return e.copy=function(){return Yn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Fn()).domain([1,10]);return e.copy=()=>Yn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Vt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Pr(e)?2:Tr(e)||null===t?1:function(e){const t=e.filter(e=>null!=e&&isFinite(e)&&0!==e).map(e=>Math.abs(e));if(0===t.length)return 1;const n=Math.min(...t);return Math.max(1,Math.ceil(-Math.log10(n)-1e-10))}(t)}function Ar(e){return parseFloat(e.slice(18))}function Sr(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Er(e){const t=Sr(e);return t?t.base:e}function Dr(e){return"n"===e||e.startsWith("n_")}function Tr(e){return/^interval_coverage_/.test(e)}function Pr(e){return/_scaled_relative_skill$/.test(Er(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const Cr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function zr(e){if(Dr(e))return"N";if(Tr(e))return`${Ar(e)}% Cov.`;const t=Sr(e),n=t?t.base:e,r=Cr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Ir(e){return null==e?[]:Array.isArray(e)?e:[e]}function Or(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const Ur={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},jr="Number of predictions scored for the associated metric(s).",qr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Ir(e.metrics),relative_metrics:Ir(e.relative_metrics),disaggregate_by:Ir(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(zr(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Dr)}const n=[...new Set(e.map(Er))].map(function(e){const[t,n]=Ur[e]||["No definition available.",null],r=n?` `:"";return{term:zr(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${jr} Each N count refers to the metric column(s) to its left.`:jr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){qr.state.selected_target=this.value,qr.initializeDisaggregateByUI(),qr.initializeMetricUI(),qr.updateTransformPanel(),qr.updateGlossary(),qr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){qr.state.selected_eval_set=this.value,qr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){qr.state.selected_plot_type=this.value,qr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){qr.state.selected_disaggregate_by=this.value,qr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){qr.state.selected_metric=this.value,qr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(qr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),qr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>qr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Dr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(zr(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Dr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n);return{data:t,name:t,render:e=>e.toFixed(r)}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Or(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Or(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=zr(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${zr(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Tr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Tr(n=this.state.selected_metric)?Ar(n):Pr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l={x:s.map(e=>e[0]),y:s.map(e=>e[1]),mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${zr(this.state.selected_metric)}: %{y:.${i}f}`,opacity:.7};t.push(l)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Tr(e.selected_metric),n=Pr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Ar(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M,type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${zr(this.state.selected_metric)}: %{customdata:.${s}f}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Hr=qr;export{Hr as default}; \ No newline at end of file +class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=l(c,.75)-l(c,.25)||c[c.length-1]-c[0],u=l([...o].sort((e,t)=>e-t),.75),d=f>0?t-1-s(f):n-1-s(u),h=r-1-s(u);return Math.min(Math.max(d,0),Math.max(h,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file diff --git a/src/predevals.js b/src/predevals.js index 46db9c6..d2c8c0a 100644 --- a/src/predevals.js +++ b/src/predevals.js @@ -3,7 +3,7 @@ */ import * as d3 from "d3"; -import {axis_kind, base_col_name, convertDataColumnTypes, get_round_decimals, hexToRGB, is_coverage_col, is_n_col, is_relative_skill_col, parse_coverage_rate, reference_line_value, score_col_name_to_text, toArray} from "./utils.js"; +import {axis_kind, base_col_name, convertDataColumnTypes, get_round_decimals, hexToRGB, is_coverage_col, is_n_col, is_relative_skill_col, parse_coverage_rate, reference_line_value, render_score, score_col_name_to_text, toArray} from "./utils.js"; import {nDefinition, metricDefinitions} from "./metric-definitions.js"; @@ -652,12 +652,17 @@ const App = { return {data: columnName, name: columnName}; } else { // format score columns: relative_skill → 2 dp, interval_coverage → 1 dp, - // all others → auto-detected minimum decimals needed (see get_round_decimals). + // all others → the decimals that resolve the column's variation (see get_round_decimals). // Note: we only build tables if disaggregate_by is '(None)', so we can assume that all // columns other than model_id and the `n` column(s) are scores const colValues = thisState.scores_table.map(row => row[columnName]); const decimals = get_round_decimals(columnName, colValues); - return {data: columnName, name: columnName, render: (d) => d.toFixed(decimals)}; + + // only format for display: render_score() can emit '<0.01', which DataTables would + // then type-detect as a string and sort lexicographically. Sorting gets the number. + const render = (d, type) => (type === 'display' || type === 'filter') + ? render_score(columnName, d, decimals) : d; + return {data: columnName, name: columnName, render: render}; } }); const targetObj = this.getSelectedTargetObj(); @@ -903,7 +908,11 @@ const App = { // their extremes, so nothing sits on the edge for them and this is a no-op. cliponaxis: false, hovermode: false, - hovertemplate: `model: %{data.name}
${thisState.selected_disaggregate_by}: %{x}
${score_col_name_to_text(this.state.selected_metric)}: %{y:.${metricDecimals}f}`, + + // pre-format rather than let Plotly round, so a hover value and its table cell + // always read the same + customdata: y.map(v => render_score(thisState.selected_metric, v, metricDecimals)), + hovertemplate: `model: %{data.name}
${thisState.selected_disaggregate_by}: %{x}
${score_col_name_to_text(this.state.selected_metric)}: %{customdata}`, opacity: 0.7, }; pd.push(line_data); @@ -1068,9 +1077,12 @@ const App = { x: x, y: y, z: z, - customdata: z_orig, + + // pre-format rather than let Plotly round, so a hover value and its table cell always + // read the same + customdata: z_orig.map(row => row.map(v => v === null ? null : render_score(thisState.selected_metric, v, metricDecimals))), type: 'heatmap', - hovertemplate: `${thisState.selected_disaggregate_by}: %{x}
model: %{y}
${score_col_name_to_text(this.state.selected_metric)}: %{customdata:.${metricDecimals}f}`, + hovertemplate: `${thisState.selected_disaggregate_by}: %{x}
model: %{y}
${score_col_name_to_text(this.state.selected_metric)}: %{customdata}`, hoverongaps: false }; diff --git a/src/utils.js b/src/utils.js index 39a3a16..476cd44 100644 --- a/src/utils.js +++ b/src/utils.js @@ -13,10 +13,9 @@ function hexToRGB(hex) { * Return the number of decimal places to use when rendering a score column. * * - `*_scaled_relative_skill` columns always use 2 decimal places. - * - `interval_coverage_*` columns always use 1 (values are 0–100 percentages). - * - All other columns: when `values` is supplied, returns the minimum decimals - * needed so that no non-zero value rounds to zero (see `min_decimals_for_values`); - * otherwise falls back to 1. + * - `interval_coverage_*` columns always use 1 (values are 0-100 percentages). + * - All other columns: when `values` is supplied, returns the decimals that resolve the column's + * variation (see `score_decimals`); otherwise falls back to 1. * * @param {string} col_name * @param {Array|null} [values=null] @@ -27,30 +26,79 @@ function get_round_decimals(col_name, values = null) { return 2; } if (!is_coverage_col(col_name) && values !== null) { - return min_decimals_for_values(values); + return score_decimals(values); } return 1; } /** - * Return the minimum number of decimal places needed so that every non-zero - * value in `values` renders as non-zero (i.e., doesn't round to "0.000…0"). - * Null, undefined, non-finite, and zero entries are ignored. - * Returns 1 when the array is empty or contains only zeros/non-finite values. + * Decimals for a score column, chosen so the displayed digits resolve the column's variation + * ("two effective digits", Ehrenberg 1977, JRSS A 140(3), 277-297), capped so the column never + * carries more than `maxSigFigs`. Display only: never applied to sort keys or downloaded data. + * + * Both anchors are quantiles rather than extremes: the range is set by the worst model, but the + * comparison that matters is among the contenders at the top, so neither one blown-up submission + * (which would flatten the leaderboard through the cap) nor one near-zero score (which would pad + * every other row with spurious decimals) gets to set the whole column's precision. + * + * Because the rule is decimals-based (`toFixed`) rather than significant-figure-based (R's + * `signif`), it never rounds digits left of the decimal point: a national-scale MAE of 12345.6 + * renders as `12346`, never `12300`. `maxSigFigs` only ever removes decimals, and it bottoms out + * at 0. + * + * Note: depends on the rows currently in `scores_table`, so precision can shift under filtering. + * That is inherent to any column-wide rule, and is the price of keeping decimal points aligned. * * @param {Array} values + * @param {Object} [options] * @returns {number} */ -function min_decimals_for_values(values) { - const nonZeroAbs = values - .filter(v => v !== null && v !== undefined && isFinite(v) && v !== 0) - .map(v => Math.abs(v)); - if (nonZeroAbs.length === 0) return 1; - const minVal = Math.min(...nonZeroAbs); - // ceil(-log10(minVal)) = decimal places needed to show 1 significant figure for the smallest value. - // Subtract a tiny epsilon before ceil to guard against floating-point overshoot - // (e.g. -log10(0.001) can return 2.9999... instead of 3 exactly). - return Math.max(1, Math.ceil(-Math.log10(minVal) - 1e-10)); +function score_decimals(values, {effDigits = 2, fallbackSigFigs = 3, maxSigFigs = 5, maxDecimals = 6} = {}) { + const vals = values.filter(v => v !== null && v !== undefined && isFinite(v)); + const nonZeroAbs = vals.filter(v => v !== 0).map(Math.abs); + if (nonZeroAbs.length === 0) return 0; + + // epsilon guards floating-point overshoot, e.g. log10(0.001) === -3.0000000000000004 + const mag = (x) => Math.floor(Math.log10(x) + 1e-10); + const quantile = (sorted, p) => sorted[Math.min(sorted.length - 1, Math.floor(p * (sorted.length - 1)))]; + const sorted = [...vals].sort((a, b) => a - b); + + // fall back to the full range when the IQR is degenerate (few rows, or many ties) + const spread = (quantile(sorted, 0.75) - quantile(sorted, 0.25)) || (sorted[sorted.length - 1] - sorted[0]); + const large = quantile([...nonZeroAbs].sort((a, b) => a - b), 0.75); + const d_spread = spread > 0 ? effDigits - 1 - mag(spread) + : fallbackSigFigs - 1 - mag(large); + const d_cap = maxSigFigs - 1 - mag(large); + return Math.min(Math.max(d_spread, 0), Math.max(d_cap, 0), maxDecimals); +} + +/** + * Render one score cell as a string. `decimals` comes from `get_round_decimals()`, computed once + * per column so that decimal points line up down the column. + * + * Values too small to survive the column's rounding render as `<0.01` (or `>-0.01`) rather than as + * a bare `0`, which is what keeps a column-wide rule from claiming a real non-zero score is zero. + * + * @param {string} col_name + * @param {number|null|undefined} value + * @param {number} decimals + * @returns {string} + */ +function render_score(col_name, value, decimals) { + if (value === null || value === undefined || !isFinite(value)) { + return ''; + } + if (is_relative_skill_col(col_name)) { + return value.toFixed(2); + } + if (is_coverage_col(col_name)) { + return value.toFixed(1); + } + const smallest = Math.pow(10, -decimals); + if (value !== 0 && Math.abs(value) < smallest / 2) { + return (value < 0 ? '>-' : '<') + smallest.toFixed(decimals); + } + return value.toFixed(decimals); } @@ -238,4 +286,4 @@ function axis_kind(values) { return 'category'; } -export {titleCase, hexToRGB, min_decimals_for_values, get_round_decimals, parse_coverage_rate, split_transformed_col_name, base_col_name, is_n_col, is_coverage_col, is_relative_skill_col, reference_line_value, score_col_name_to_text, convertDataColumnTypes, toArray, axis_kind} +export {titleCase, hexToRGB, score_decimals, render_score, get_round_decimals, parse_coverage_rate, split_transformed_col_name, base_col_name, is_n_col, is_coverage_col, is_relative_skill_col, reference_line_value, score_col_name_to_text, convertDataColumnTypes, toArray, axis_kind} diff --git a/test/ui.js b/test/ui.js index 9e8e602..efe910c 100644 --- a/test/ui.js +++ b/test/ui.js @@ -65,6 +65,30 @@ function useStubbedApp(hooks) { }); } +// DataTables isn't loaded in the jsdom test env; stub the pieces updateTable() touches so the +// is still assembled (that DOM is built before the DataTable() hand-off). Returns a getter +// for the config updateTable() handed over, which is where the column render functions live. +function stubDataTable(hooks) { + let originalDataTable; + let capturedConfig; + hooks.beforeEach(() => { + originalDataTable = $.fn.DataTable; + capturedConfig = null; + const DataTableStub = function (config) { + capturedConfig = config; + return {destroy() {}}; + }; + DataTableStub.isDataTable = function () { + return false; + }; + $.fn.DataTable = DataTableStub; + }); + hooks.afterEach(() => { + $.fn.DataTable = originalDataTable; + }); + return () => capturedConfig; +} + // A scores_table stand-in carrying only the `.columns` property the render paths read. function scoresWithColumns(columns) { const scores = []; @@ -215,23 +239,7 @@ QUnit.module('metric definitions glossary', (hooks) => { QUnit.module('scores table headers', (hooks) => { useStubbedApp(hooks); - - // DataTables isn't loaded in the jsdom test env; stub the pieces updateTable() touches so the - // is still assembled (that DOM is built before the DataTable() hand-off). - let originalDataTable; - hooks.beforeEach(() => { - originalDataTable = $.fn.DataTable; - const DataTableStub = function () { - return {destroy() {}}; - }; - DataTableStub.isDataTable = function () { - return false; - }; - $.fn.DataTable = DataTableStub; - }); - hooks.afterEach(() => { - $.fn.DataTable = originalDataTable; - }); + stubDataTable(hooks); const headerTexts = () => textsOf('#predeval_table thead th'); @@ -262,6 +270,69 @@ QUnit.module('scores table headers', (hooks) => { }); +// +// scores table cell rendering tests +// + +QUnit.module('scores table cell rendering', (hooks) => { + useStubbedApp(hooks); + const dtConfig = stubDataTable(hooks); + + // the flusight `wis__log` column from issue #88, trimmed to the rows that make the point: under + // the old min-anchored rule every one of these rendered as "0.3" + const WIS_LOG_ROWS = [0.265444756757736, 0.305843546429542, 0.296765334110182, 0.194580477360387, + 0.42445635328479, 0.690585048746816, 1.27387287336059, 0.343356886197072]; + + // Build a scores_table of real rows (not the header-only `scoresWithColumns` stand-in) so the + // column-values → decimals → cell-string path runs for real. + function tableWith(columnValues) { + const columns = ['model_id', ...Object.keys(columnValues)]; + const nRows = Object.values(columnValues)[0].length; + const scores = Array.from({length: nRows}, (_, i) => { + const row = {model_id: `model-${i}`}; + for (const [col, values] of Object.entries(columnValues)) { + row[col] = values[i]; + } + return row; + }); + scores.columns = columns; + return scores; + } + + const renderFor = (columnName) => dtConfig().columns.find((c) => c.name === columnName).render; + + test('renders score cells at the decimals that resolve the column (issue #88)', assert => { + App.state.scores_table = tableWith({wis__log: WIS_LOG_ROWS}); + App.updateTable(); + + const render = renderFor('wis__log'); + assert.equal(render(0.265444756757736, 'display'), '0.27'); + assert.equal(render(0.305843546429542, 'display'), '0.31'); + assert.equal(render(0.296765334110182, 'display'), '0.30'); + }); + + test('hands DataTables the raw number for sorting', assert => { + // render() runs for every DataTables type, and '<0.01' in a sort key would silently switch + // the column to lexicographic ordering + App.state.scores_table = tableWith({wis__log: WIS_LOG_ROWS}); + App.updateTable(); + + const render = renderFor('wis__log'); + assert.strictEqual(render(0.305843546429542, 'sort'), 0.305843546429542); + assert.strictEqual(render(0.305843546429542, 'type'), 0.305843546429542); + assert.equal(render(0.305843546429542, 'filter'), '0.31', 'search matches what is displayed'); + }); + + test('renders whole-number-scale columns without a decimal place', assert => { + App.state.scores_table = tableWith({ae_median: [290.690197703552, 101.287927350427, 76.9, 498.2, 11.3]}); + App.updateTable(); + + const render = renderFor('ae_median'); + assert.equal(render(290.690197703552, 'display'), '291'); + assert.equal(render(11.3, 'display'), '11'); + }); +}); + // // plot x-axis tests // diff --git a/test/utils.js b/test/utils.js index 7f4897b..b4668e3 100644 --- a/test/utils.js +++ b/test/utils.js @@ -7,10 +7,11 @@ import { is_coverage_col, is_n_col, is_relative_skill_col, - min_decimals_for_values, + render_score, parse_coverage_rate, reference_line_value, score_col_name_to_text, + score_decimals, split_transformed_col_name, titleCase, toArray, @@ -58,10 +59,10 @@ test('returns 2 for scaled_relative_skill columns', assert => { assert.equal(get_round_decimals('mae_scaled_relative_skill__log'), 2); }); -test('with values: returns min decimals needed for non-coverage, non-skill columns', assert => { - assert.equal(get_round_decimals('wis', [0.000925, 0.000759, 0.000805]), 4); - assert.equal(get_round_decimals('ae_median', [0.001, 0.002, 0.009]), 3); - assert.equal(get_round_decimals('wis', [1.5, 2.3, 47.7]), 1); +test('with values: defers to score_decimals() for non-coverage, non-skill columns', assert => { + assert.equal(get_round_decimals('wis', [0.000925, 0.000759, 0.000805]), 6); + assert.equal(get_round_decimals('ae_median', [0.001, 0.002, 0.009]), 4); + assert.equal(get_round_decimals('wis', [1.5, 2.3, 47.7]), 2); }); test('with values: still returns 2 for scaled_relative_skill regardless of values', assert => { @@ -75,49 +76,125 @@ test('with values: still returns 1 for interval_coverage columns (values are 0-1 }); -QUnit.module('min_decimals_for_values'); +QUnit.module('score_decimals'); -test('returns 1 for empty, all-zero, or all-non-finite values', assert => { - assert.equal(min_decimals_for_values([]), 1); - assert.equal(min_decimals_for_values([0, 0, 0]), 1); - assert.equal(min_decimals_for_values([null, undefined]), 1); - assert.equal(min_decimals_for_values([Infinity, -Infinity]), 1); +// The issue-88 regression case: flusight-dashboard `wis__log`, all 58 models. Every value sits in +// [0.19, 1.27], so the old min-anchored rule cleared its "nothing rounds to zero" bar at one +// decimal and rendered 21 of these 58 rows as the same "0.3". +const WIS_LOG_VALUES = [ + 0.194580477360387, 0.42445635328479, 0.264657716265282, 0.343356886197072, + 0.305843546429542, 0.361738462099056, 0.460338093431164, 0.440443041113521, + 0.450465100085903, 0.565428319467, 0.265444756757736, 0.309846277585966, + 0.530184444278452, 0.327864650476597, 0.333704559479011, 0.311450841561445, + 0.322866070572885, 0.405768484358752, 0.431702079297883, 0.296765334110182, + 0.305707952027994, 0.690585048746816, 0.486658116642048, 0.575326737297091, + 0.581587036665746, 0.645718348925459, 0.704006487669316, 0.312369466300412, + 0.344182455268459, 0.415489242163702, 0.422157834149336, 0.381696816546922, + 0.404151084284733, 0.322012575547464, 0.345297308828633, 0.428431249029247, + 0.472023154530456, 0.311225672203621, 0.305893179663906, 0.392204368133479, + 0.384833937936552, 0.530086715037455, 0.643205272486554, 0.398985751470517, + 0.393277225697538, 0.30886209898577, 0.33910087296964, 1.27387287336059, + 0.482863143449645, 0.563085931347079, 0.465941529854746, 0.314563493121172, + 0.52361022830072, 0.459469976679847, 0.597800361636446, 0.408775489527314, + 0.296166723330344, 0.500871388446773, +]; + +test('returns 0 when there is nothing non-zero to resolve', assert => { + assert.equal(score_decimals([]), 0); + assert.equal(score_decimals([0, 0, 0]), 0); + assert.equal(score_decimals([null, undefined]), 0); + assert.equal(score_decimals([Infinity, -Infinity]), 0); +}); + +test('resolves the flusight `wis__log` column past one decimal (issue #88)', assert => { + assert.equal(score_decimals(WIS_LOG_VALUES), 2, 'IQR of 0.161 resolves at 2 decimals'); +}); + +test('whole-number-scale columns drop to 0 decimals', assert => { + // national-scale MAE: every integer digit is kept, only the decimal place goes. A + // significant-figure rule (R's signif) would render these as 1250, 12300 - this one does not + const national = [1247.3, 1583.9, 2104.6, 2890.2, 3312.8, 4501.7, 5120.4, 8842.1, 12345.6, 15678.9]; + assert.equal(score_decimals(national), 0); + assert.equal(render_score('ae_median', 12345.6, 0), '12346'); +}); + +test('falls back to the range, then to sig figs, as the IQR degenerates', assert => { + assert.equal(score_decimals([42.7]), 1, 'single value: 3 sig figs'); + assert.equal(score_decimals([5, 5, 5]), 2, 'all identical: IQR and range both zero'); +}); + +test('one high outlier does not flatten the column', assert => { + // the cap is anchored on Q3, not the max: anchoring on the max would give d_cap = 0 here and + // render the nine rows that matter as "0", "1", "1", ... + const withOutlier = [0.42, 0.55, 0.61, 0.73, 0.88, 1.02, 1.19, 1.41, 2.05, 52000]; + assert.equal(score_decimals(withOutlier), 2); + assert.equal(render_score('wis', 0.42, 2), '0.42'); }); -test('returns 1 for values >= 0.1', assert => { - assert.equal(min_decimals_for_values([1.5, 2.3, 47.7]), 1); - assert.equal(min_decimals_for_values([0.1, 0.5, 0.9]), 1); +test('one low outlier does not pad the column with decimals', assert => { + // min-anchoring - the old rule, and the `minSigFigs` floor considered on #88 - would force + // decimals here to keep 0.05 visible, giving "183.70" and "392.80" + const withOutlier = [0.05, 183.7, 220.4, 250.9, 290.7, 312.5, 392.8]; + assert.equal(score_decimals(withOutlier), 0); + assert.equal(render_score('wis', 183.7, 0), '184'); }); -test('returns 2 for values in [0.01, 0.1)', assert => { - assert.equal(min_decimals_for_values([0.05, 0.08]), 2); - assert.equal(min_decimals_for_values([0.01, 0.09]), 2); +test('guards floating-point overshoot at exact powers of ten', assert => { + // log10(0.001) is -3.0000000000000004, which would floor to -4 without the epsilon + assert.equal(score_decimals([0.001, 0.002, 0.009]), 4); }); -test('returns 3 for values in [0.001, 0.01)', assert => { - assert.equal(min_decimals_for_values([0.005, 0.008]), 3); - assert.equal(min_decimals_for_values([0.001, 0.009]), 3); +test('respects maxDecimals', assert => { + assert.equal(score_decimals([0.000925, 0.000759, 0.000805]), 6, 'jointly binding with the spread'); + assert.equal(score_decimals([0.000925, 0.000759, 0.000805], {maxDecimals: 4}), 4); }); -test('returns 4 for covidhub-style WIS values (~0.0005-0.0014)', assert => { - // real data: document.predevals.state.scores_table wis column - const wisValues = [0.000925048661683814, 0.00075907107176393, 0.000804968609706757, - 0.00138310730984419, 0.00143697666395866, 0.00055223613252158, 0.000892415568463205]; - assert.equal(min_decimals_for_values(wisValues), 4); +test('ignores null, undefined, and non-finite entries', assert => { + assert.equal(score_decimals([null, undefined, Infinity, -Infinity, 1.5, 2.3, 47.7]), + score_decimals([1.5, 2.3, 47.7])); +}); + +test('counts zeros as observations when measuring the spread', assert => { + // a zero is a real score, so it belongs in the column's distribution even though it can't + // anchor a magnitude. Only the magnitude anchors skip it + assert.equal(score_decimals([0, 1.5, 2.3, 47.7]), 1, 'the zero widens the IQR'); + assert.equal(score_decimals([1.5, 2.3, 47.7]), 2); +}); + + +QUnit.module('render_score'); + +test('distinguishes `wis__log` values that all rendered as "0.3" (issue #88)', assert => { + const decimals = score_decimals(WIS_LOG_VALUES); + + // the three rows visible in the issue screenshot + assert.equal(render_score('wis__log', 0.265444756757736, decimals), '0.27'); + assert.equal(render_score('wis__log', 0.305843546429542, decimals), '0.31'); + assert.equal(render_score('wis__log', 0.296765334110182, decimals), '0.30'); + + const rendered = WIS_LOG_VALUES.map(v => render_score('wis__log', v, decimals)); + assert.equal(WIS_LOG_VALUES.filter(v => v.toFixed(1) === '0.3').length, 21, 'rows the old rule flattened'); + assert.equal(new Set(rendered).size, 34, 'distinct strings, up from 7 under the old rule'); }); -test('is driven by the smallest non-zero absolute value in the array', assert => { - assert.equal(min_decimals_for_values([100, 1.5, 0.001]), 3); +test('overrides the column decimals for skill and coverage columns', assert => { + assert.equal(render_score('wis_scaled_relative_skill', 0.798407240258868, 0), '0.80'); + assert.equal(render_score('interval_coverage_50', 52.884615384615394, 0), '52.9'); }); -test('handles negative values by taking absolute value', assert => { - assert.equal(min_decimals_for_values([-0.005, -0.008]), 3); - assert.equal(min_decimals_for_values([-1.5, 0.5]), 1); +test('flags values too small to survive the column rounding', assert => { + assert.equal(render_score('wis', 0.0001, 2), '<0.01'); + assert.equal(render_score('wis', -0.0001, 2), '>-0.01'); + assert.equal(render_score('wis', 0.05, 0), '<1'); + assert.equal(render_score('wis', 0.005, 2), '0.01', 'rounds up rather than flagging'); + assert.equal(render_score('wis', 0, 2), '0.00', 'a true zero is not flagged'); }); -test('filters out null, undefined, and non-finite values', assert => { - assert.equal(min_decimals_for_values([null, undefined, Infinity, -Infinity, 0, 0.5]), 1); - assert.equal(min_decimals_for_values([null, 0.005]), 3); +test('renders missing and non-finite values as empty', assert => { + assert.equal(render_score('wis', null, 2), ''); + assert.equal(render_score('wis', undefined, 2), ''); + assert.equal(render_score('wis', Infinity, 2), ''); + assert.equal(render_score('wis', NaN, 2), ''); }); From 762d77f3619c97047d6e04fe1ca418643af841ff Mon Sep 17 00:00:00 2001 From: matthewcornell Date: Tue, 15 Sep 2026 10:37:17 -0400 Subject: [PATCH 2/4] Anchor the degenerate-IQR fallback on quantiles too (follow-up to #88) score_decimals() fell back to the full range whenever the IQR came out zero. The comment justified that as covering "few rows, or many ties", but many ties is exactly the case where the fallback hands the column back to the outliers the IQR anchoring exists to keep out: [0.5 x8, 0.52, 52000] has a zero IQR, so the range set the precision at 0 decimals and rendered the nine rows that matter as "1" nine times over. That is the issue-88 failure, reintroduced one fallback later -- the same shape as the max-anchored cap the parent commit declined to take. Widen the window in rungs instead: IQR, then P10-P90, then the full range. The tied column above now resolves at 3 decimals ("0.500", "0.520"). The range is still the last rung, but reaching it now means the column is tied from P10 to P90, where there is nothing left to measure and the range is all that is left. No-op on all four real flusight columns and on every existing test. Document the one case the parent commit left implicit: maxSigFigs is applied as a hard minimum against the spread, so it wins where the two disagree. Above ~1e4 that flattens neighbors the spread would have resolved ([12345.1, 12345.2] wants 1 decimal and gets 0). That is the trade the cap exists to make -- the loss is the sixth significant figure, not the first -- but it is worth naming next to the maxSigFigs knob rather than leaving a reader to find it. Narrow both hovertemplate comments. "A hover value and its table cell always read the same" is not quite true: the table's decimals come from scores_table (never disaggregated) and the plot's from scores_plot, so while disaggregation is on the two panes can differ. State what the change actually buys instead -- hover now goes through the same rule as every other score display, including render_score()'s '<0.01' floor and its '' for a missing score, where %{y:.Nf} rendered a bare "NaN" (parseFloat() turns an absent score into NaN, not null). Restore the covidhub tiny-WIS fixture dropped when the min_decimals_for_values tests were replaced. It is the second real-data column on record, it lands at 5 decimals under the new rule, and all seven rows now render distinctly where the old rule collapsed 0.000805 and 0.000759 onto "0.0008". Add a test pinning the tie-heavy column in both directions. Bundles rebuilt. Co-Authored-By: Claude Opus 5 (1M context) --- dev-example/predevals.bundle.js | 2 +- dist/predevals.bundle.js | 2 +- src/predevals.js | 11 +++++++---- src/utils.js | 15 +++++++++++++-- test/utils.js | 30 ++++++++++++++++++++++++++++-- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/dev-example/predevals.bundle.js b/dev-example/predevals.bundle.js index 7d7e383..690db90 100644 --- a/dev-example/predevals.bundle.js +++ b/dev-example/predevals.bundle.js @@ -1 +1 @@ -class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=l(c,.75)-l(c,.25)||c[c.length-1]-c[0],u=l([...o].sort((e,t)=>e-t),.75),d=f>0?t-1-s(f):n-1-s(u),h=r-1-s(u);return Math.min(Math.max(d,0),Math.max(h,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file +class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=(e,t)=>l(c,t)-l(c,e),u=f(.25,.75)||f(.1,.9)||f(0,1),d=l([...o].sort((e,t)=>e-t),.75),h=u>0?t-1-s(u):n-1-s(d),p=r-1-s(d);return Math.min(Math.max(h,0),Math.max(p,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file diff --git a/dist/predevals.bundle.js b/dist/predevals.bundle.js index 7d7e383..690db90 100644 --- a/dist/predevals.bundle.js +++ b/dist/predevals.bundle.js @@ -1 +1 @@ -class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=l(c,.75)-l(c,.25)||c[c.length-1]-c[0],u=l([...o].sort((e,t)=>e-t),.75),d=f>0?t-1-s(f):n-1-s(u),h=r-1-s(u);return Math.min(Math.max(d,0),Math.max(h,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file +class e extends Map{constructor(e,t=n){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[t,n]of e)this.set(t,n)}get(e){return super.get(t(this,e))}has(e){return super.has(t(this,e))}set(e,t){return super.set(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}(this,e),t)}delete(e){return super.delete(function({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}(this,e))}}function t({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function n(e){return null!==e&&"object"==typeof e?e.valueOf():e}function r(e){return e}function a(t,...n){return function(t,n,r,a){return function t(i,o){if(o>=a.length)return r(i);const s=new e,l=a[o++];let c=-1;for(const e of i){const t=l(e,++c,i),n=s.get(t);n?n.push(e):s.set(t,[e])}for(const[e,n]of s)s.set(e,t(n,o));return n(s)}(t,0)}(t,r,r,n)}function i(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n>t||void 0===n&&t>=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r,e))&&(n>a||void 0===n&&a>=a)&&(n=a)}return n}function o(){}function s(e){return null==e?o:function(){return this.querySelector(e)}}function l(){return[]}function c(e){return null==e?l:function(){return this.querySelectorAll(e)}}function f(e){return function(){return this.matches(e)}}function u(e){return function(t){return t.matches(e)}}Set;var d=Array.prototype.find;function h(){return this.firstElementChild}var p=Array.prototype.filter;function g(){return Array.from(this.children)}function b(e){return new Array(e.length)}function m(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}function _(e,t,n,r,a,i){for(var o,s=0,l=t.length,c=i.length;st?1:e>=t?0:NaN}m.prototype={constructor:m,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var M="http://www.w3.org/1999/xhtml";const k={svg:"http://www.w3.org/2000/svg",xhtml:M,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(e){var t=e+="",n=t.indexOf(":");return n>=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),k.hasOwnProperty(t)?{space:k[t],local:e}:e}function A(e){return function(){this.removeAttribute(e)}}function S(e){return function(){this.removeAttributeNS(e.space,e.local)}}function E(e,t){return function(){this.setAttribute(e,t)}}function D(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function T(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function P(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function C(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function z(e){return function(){this.style.removeProperty(e)}}function I(e,t,n){return function(){this.style.setProperty(e,t,n)}}function O(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function U(e,t){return e.style.getPropertyValue(t)||C(e).getComputedStyle(e,null).getPropertyValue(t)}function j(e){return function(){delete this[e]}}function q(e,t){return function(){this[e]=t}}function H(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function R(e){return e.classList||new X(e)}function X(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function F(e,t){for(var n=R(e),r=-1,a=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];function be(e,t){this._groups=e,this._parents=t}function me(){return new be([[document.documentElement]],ge)}be.prototype=me.prototype={constructor:be,select:function(e){"function"!=typeof e&&(e=s(e));for(var t=this._groups,n=t.length,r=new Array(n),a=0;a=k&&(k=$+1);!(M=m[k])&&++k=0;)(r=a[i])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=x);for(var n=this._groups,r=n.length,a=new Array(r),i=0;i1?this.each((null==t?z:"function"==typeof t?O:I)(e,t,n??"")):U(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?j:"function"==typeof t?H:q)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=R(this.node()),a=-1,i=n.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=i.length;if(!(arguments.length<2)){for(s=t?ue:fe,r=0;r{}};function ye(){for(var e,t=0,n=arguments.length,r={};t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=i.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,a=new Array(n),i=0;i=0&&t._call.call(void 0,e),t=t._next;--Ae}()}finally{Ae=0,function(){for(var e,t,n=ke,r=1/0;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:ke=t);Ne=e,Le(r)}(),Te=0}}function He(){var e=Ce.now(),t=e-De;t>1e3&&(Pe-=t,De=e)}function Le(e){Ae||(Se&&(Se=clearTimeout(Se)),e-Te>24?(e<1/0&&(Se=setTimeout(qe,e-Ce.now()-Pe)),Ee&&(Ee=clearInterval(Ee))):(Ee||(De=Ce.now(),Ee=setInterval(He,1e3)),Ae=1,ze(qe)))}function Re(e,t,n){var r=new Ue;return t=null==t?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}Ue.prototype=je.prototype={constructor:Ue,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?Ie():+n)+(null==t?0:+t),this._next||Ne===this||(Ne?Ne._next=this:ke=this,Ne=this),this._call=e,this._time=n,Le()},stop:function(){this._call&&(this._call=null,this._time=1/0,Le())}};var Xe=$e("start","end","cancel","interrupt"),Fe=[];function Be(e,t,n,r,a,i){var o=e.__transition;if(o){if(n in o)return}else e.__transition={};!function(e,t,n){var r,a=e.__transition;function i(l){var c,f,u,d;if(1!==n.state)return s();for(c in a)if((d=a[c]).name===n.name){if(3===d.state)return Re(i);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",e,e.__data__,d.index,d.group),delete a[c]):+c0)throw new Error("too late; already scheduled");return n}function Ye(e,t){var n=Ge(e,t);if(n.state>3)throw new Error("too late; already running");return n}function Ge(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var Ke,Ze=180/Math.PI,Je={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Qe(e,t,n,r,a,i){var o,s,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*n+t*r)&&(n-=e*l,r-=t*l),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,l/=s),e*r180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(a(n)+"rotate(",null,r)-2,x:We(e,t)})):t&&n.push(a(n)+"rotate("+t+r)}(i.rotate,o.rotate,s,l),function(e,t,n,i){e!==t?i.push({i:n.push(a(n)+"skewX(",null,r)-2,x:We(e,t)}):t&&n.push(a(n)+"skewX("+t+r)}(i.skewX,o.skewX,s,l),function(e,t,n,r,i,o){if(e!==n||t!==r){var s=i.push(a(i)+"scale(",null,",",null,")");o.push({i:s-4,x:We(e,n)},{i:s-2,x:We(t,r)})}else 1===n&&1===r||i.push(a(i)+"scale("+n+","+r+")")}(i.scaleX,i.scaleY,o.scaleX,o.scaleY,s,l),i=o=null,function(e){for(var t,n=-1,r=l.length;++n>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Nt(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Nt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=gt.exec(e))?new St(t[1],t[2],t[3],1):(t=bt.exec(e))?new St(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mt.exec(e))?Nt(t[1],t[2],t[3],t[4]):(t=_t.exec(e))?Nt(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=vt.exec(e))?zt(t[1],t[2]/100,t[3]/100,1):(t=yt.exec(e))?zt(t[1],t[2]/100,t[3]/100,t[4]):wt.hasOwnProperty(e)?kt(wt[e]):"transparent"===e?new St(NaN,NaN,NaN,0):null}function kt(e){return new St(e>>16&255,e>>8&255,255&e,1)}function Nt(e,t,n,r){return r<=0&&(e=t=n=NaN),new St(e,t,n,r)}function At(e,t,n,r){return 1===arguments.length?((a=e)instanceof lt||(a=$t(a)),a?new St((a=a.rgb()).r,a.g,a.b,a.opacity):new St):new St(e,t,n,r??1);var a}function St(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Et(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}`}function Dt(){const e=Tt(this.opacity);return`${1===e?"rgb(":"rgba("}${Pt(this.r)}, ${Pt(this.g)}, ${Pt(this.b)}${1===e?")":`, ${e})`}`}function Tt(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Pt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Ct(e){return((e=Pt(e))<16?"0":"")+e.toString(16)}function zt(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ot(e,t,n,r)}function It(e){if(e instanceof Ot)return new Ot(e.h,e.s,e.l,e.opacity);if(e instanceof lt||(e=$t(e)),!e)return new Ot;if(e instanceof Ot)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,a=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,s=i-a,l=(i+a)/2;return s?(o=t===i?(n-r)/s+6*(n0&&l<1?0:o,new Ot(o,s,l,e.opacity)}function Ot(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Ut(e){return(e=(e||0)%360)<0?e+360:e}function jt(e){return Math.max(0,Math.min(1,e||0))}function qt(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}function Ht(e,t,n,r,a){var i=e*e,o=i*e;return((1-3*e+3*i-o)*t+(4-6*i+3*o)*n+(1+3*e+3*i-3*o)*r+o*a)/6}ot(lt,$t,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:xt,formatHex:xt,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return It(this).formatHsl()},formatRgb:Mt,toString:Mt}),ot(St,At,st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new St(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new St(Pt(this.r),Pt(this.g),Pt(this.b),Tt(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Et,formatHex:Et,formatHex8:function(){return`#${Ct(this.r)}${Ct(this.g)}${Ct(this.b)}${Ct(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Dt,toString:Dt})),ot(Ot,function(e,t,n,r){return 1===arguments.length?It(e):new Ot(e,t,n,r??1)},st(lt,{brighter(e){return e=null==e?ft:Math.pow(ft,e),new Ot(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?ct:Math.pow(ct,e),new Ot(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,a=2*n-r;return new St(qt(e>=240?e-240:e+120,a,r),qt(e,a,r),qt(e<120?e+240:e-120,a,r),this.opacity)},clamp(){return new Ot(Ut(this.h),jt(this.s),jt(this.l),Tt(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Tt(this.opacity);return`${1===e?"hsl(":"hsla("}${Ut(this.h)}, ${100*jt(this.s)}%, ${100*jt(this.l)}%${1===e?")":`, ${e})`}`}}));const Lt=e=>()=>e;function Rt(e,t){var n=t-e;return n?function(e,t){return function(n){return e+n*t}}(e,n):Lt(isNaN(e)?t:e)}const Xt=function e(t){var n=function(e){return 1===(e=+e)?Rt:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Lt(isNaN(t)?n:t)}}(t);function r(e,t){var r=n((e=At(e)).r,(t=At(t)).r),a=n(e.g,t.g),i=n(e.b,t.b),o=Rt(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=a(t),e.b=i(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function Ft(e){return function(t){var n,r,a=t.length,i=new Array(a),o=new Array(a),s=new Array(a);for(n=0;n=1?(n=1,t-1):Math.floor(n*t),a=e[r],i=e[r+1],o=r>0?e[r-1]:2*a-i,s=ri&&(a=t.slice(i,a),s[o]?s[o]+=a:s[++o]=a),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:We(n,r)})),i=Yt.lastIndex;return i=0&&(e=e.slice(0,t)),!e||"start"===e})}(t)?Ve:Ye;return function(){var o=i(this,e),s=o.on;s!==r&&(a=(r=s).copy()).on(t,n),o.on=a}}(n,e,t))},attr:function(e,t){var n=N(e),r="transform"===n?nt:Wt;return this.attrTween(e,"function"==typeof t?(n.local?tn:en)(n,r,it(this,"attr."+e,t)):null==t?(n.local?Zt:Kt)(n):(n.local?Qt:Jt)(n,r,t))},attrTween:function(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;var r=N(e);return this.tween(n,(r.local?nn:rn)(r,t))},style:function(e,t,n){var r="transform"==(e+="")?tt:Wt;return null==t?this.styleTween(e,function(e,t){var n,r,a;return function(){var i=U(this,e),o=(this.style.removeProperty(e),U(this,e));return i===o?null:i===n&&o===r?a:a=t(n=i,r=o)}}(e,r)).on("end.style."+e,fn(e)):"function"==typeof t?this.styleTween(e,function(e,t,n){var r,a,i;return function(){var o=U(this,e),s=n(this),l=s+"";return null==s&&(this.style.removeProperty(e),l=s=U(this,e)),o===l?null:o===r&&l===a?i:(a=l,i=t(r=o,s))}}(e,r,it(this,"style."+e,t))).each(function(e,t){var n,r,a,i,o="style."+t,s="end."+o;return function(){var l=Ye(this,e),c=l.on,f=null==l.value[o]?i||(i=fn(t)):void 0;c===n&&a===f||(r=(n=c).copy()).on(s,a=f),l.on=r}}(this._id,e)):this.styleTween(e,function(e,t,n){var r,a,i=n+"";return function(){var o=U(this,e);return o===i?null:o===r?a:a=t(r=o,n)}}(e,r,t),n).on("end.style."+e,null)},styleTween:function(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==t)return this.tween(r,null);if("function"!=typeof t)throw new Error;return this.tween(r,function(e,t,n){var r,a;function i(){var i=t.apply(this,arguments);return i!==a&&(r=(a=i)&&function(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}(e,i,n)),r}return i._value=t,i}(e,t,n??""))},text:function(e){return this.tween("text","function"==typeof e?function(e){return function(){var t=e(this);this.textContent=t??""}}(it(this,"text",e)):function(e){return function(){this.textContent=e}}(null==e?"":e+""))},textTween:function(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(null==e)return this.tween(t,null);if("function"!=typeof e)throw new Error;return this.tween(t,function(e){var t,n;function r(){var r=e.apply(this,arguments);return r!==n&&(t=(n=r)&&function(e){return function(t){this.textContent=e.call(this,t)}}(r)),t}return r._value=e,r}(e))},remove:function(){return this.on("end.remove",function(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}(this._id))},tween:function(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r,a=Ge(this.node(),n).tween,i=0,o=a.length;i2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[a]):o=!1;o&&delete e.__transition}}(this,e)})},_e.prototype.transition=function(e){var t,n;e instanceof dn?(t=e._id,e=e._name):(t=hn(),(n=gn).time=Ie(),e=null==e?null:e+"");for(var r=this._groups,a=r.length,i=0;i=wn?10:i>=xn?5:i>=Mn?2:1;let s,l,c;return a<0?(c=Math.pow(10,-a)/o,s=Math.round(e*c),l=Math.round(t*c),s/ct&&--l,c=-c):(c=Math.pow(10,a)*o,s=Math.round(e/c),l=Math.round(t/c),s*ct&&--l),l0))return[];if((e=+e)===(t=+t))return[e];const r=t=a))return[];const s=i-a+1,l=new Array(s);if(r)if(o<0)for(let e=0;et?1:e>=t?0:NaN}function Sn(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function En(e){let t,n,r;function a(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<0?a=t+1:i=t}while(aAn(e(t),n),r=(t,n)=>e(t)-n):(t=e===An||e===Sn?e:Dn,n=e,r=e),{left:a,center:function(e,t,n=0,i=e.length){const o=a(e,t,n,i-1);return o>n&&r(e[o-1],t)>-r(e[o],t)?o-1:o},right:function(e,r,a=0,i=e.length){if(a>>1;n(e[t],r)<=0?a=t+1:i=t}while(at&&(n=e,e=t,t=n),c=function(n){return Math.max(e,Math.min(t,n))}),r=l>2?Bn:Fn,a=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(a||(a=r(o.map(e),s,l)))(e(c(t)))}return u.invert=function(n){return c(t((i||(i=r(s,o.map(e),We)))(n)))},u.domain=function(e){return arguments.length?(o=Array.from(e,Hn),f()):o.slice()},u.range=function(e){return arguments.length?(s=Array.from(e),f()):s.slice()},u.rangeRound=function(e){return s=Array.from(e),l=qn,f()},u.clamp=function(e){return arguments.length?(c=!!e||Rn,f()):c!==Rn},u.interpolate=function(e){return arguments.length?(l=e,f()):l},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,r){return e=n,t=r,f()}}function Gn(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}function Wn(e,t){switch(arguments.length){case 0:break;case 1:"function"==typeof e?this.interpolator(e):this.range(e);break;default:this.domain(e),"function"==typeof t?this.interpolator(t):this.range(t)}return this}var Kn,Zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Jn(e){if(!(t=Zn.exec(e)))throw new Error("invalid format: "+e);var t;return new Qn({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function Qn(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function er(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function tr(e){return(e=er(Math.abs(e)))?e[1]:NaN}function nr(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1];return a<0?"0."+new Array(-a).join("0")+r:r.length>a+1?r.slice(0,a+1)+"."+r.slice(a+1):r+new Array(a-r.length+2).join("0")}Jn.prototype=Qn.prototype,Qn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const rr={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:function(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)},e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>nr(100*e,t),r:nr,s:function(e,t){var n=er(e,t);if(!n)return e+"";var r=n[0],a=n[1],i=a-(Kn=3*Math.max(-8,Math.min(8,Math.floor(a/3))))+1,o=r.length;return i===o?r:i>o?r+new Array(i-o+1).join("0"):i>0?r.slice(0,i)+"."+r.slice(i):"0."+new Array(1-i).join("0")+er(e,Math.max(0,t+i-1))[0]},X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function ar(e){return e}var ir,or,sr,lr=Array.prototype.map,cr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function fr(e){var t=e.domain;return e.ticks=function(e){var n=t();return kn(n[0],n[n.length-1],e??10)},e.tickFormat=function(e,n){var r=t();return function(e,t,n,r){var a,i=function(e,t,n){n=+n;const r=(t=+t)<(e=+e),a=r?Nn(t,e,n):Nn(e,t,n);return(r?-1:1)*(a<0?1/-a:a)}(e,t,n);switch((r=Jn(r??",f")).type){case"s":var o=Math.max(Math.abs(e),Math.abs(t));return null!=r.precision||isNaN(a=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3)))-tr(Math.abs(e)))}(i,o))||(r.precision=a),sr(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(a=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,tr(t)-tr(e))+1}(i,Math.max(Math.abs(e),Math.abs(t))))||(r.precision=a-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(a=function(e){return Math.max(0,-tr(Math.abs(e)))}(i))||(r.precision=a-2*("%"===r.type))}return or(r)}(r[0],r[r.length-1],e??10,n)},e.nice=function(n){null==n&&(n=10);var r,a,i=t(),o=0,s=i.length-1,l=i[o],c=i[s],f=10;for(c0;){if((a=Nn(l,c,n))===r)return i[o]=l,i[s]=c,t(i);if(a>0)l=Math.floor(l/a)*a,c=Math.ceil(c/a)*a;else{if(!(a<0))break;l=Math.ceil(l*a)/a,c=Math.floor(c*a)/a}r=a}return e},e}function ur(){var e=Yn()(Rn,Rn);return e.copy=function(){return Vn(e,ur())},Gn.apply(e,arguments),fr(e)}function dr(e){return Math.log(e)}function hr(e){return Math.exp(e)}function pr(e){return-Math.log(-e)}function gr(e){return-Math.exp(-e)}function br(e){return isFinite(e)?+("1e"+e):e<0?0:e}function mr(e){return(t,n)=>-e(-t,n)}function _r(){const e=function(e){const t=e(dr,hr),n=t.domain;let r,a,i=10;function o(){return r=function(e){return e===Math.E?Math.log:10===e&&Math.log10||2===e&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}(i),a=function(e){return 10===e?br:e===Math.E?Math.exp:t=>Math.pow(e,t)}(i),n()[0]<0?(r=mr(r),a=mr(a),e(pr,gr)):e(dr,hr),t}return t.base=function(e){return arguments.length?(i=+e,o()):i},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=e=>{const t=n();let o=t[0],s=t[t.length-1];const l=s0){for(;u<=d;++u)for(c=1;cs)break;p.push(f)}}else for(;u<=d;++u)for(c=i-1;c>=1;--c)if(f=u>0?c/a(-u):c*a(u),!(fs)break;p.push(f)}2*p.length{if(null==e&&(e=10),null==n&&(n=10===i?"s":","),"function"!=typeof n&&(i%1||null!=(n=Jn(n)).precision||(n.trim=!0),n=or(n)),e===1/0)return n;const o=Math.max(1,i*e/t.ticks().length);return e=>{let t=e/a(Math.round(r(e)));return t*in(function(e,t){var n,r=0,a=(e=e.slice()).length-1,i=e[r],o=e[a];return oa(Math.floor(r(e))),ceil:e=>a(Math.ceil(r(e)))})),t}(Yn()).domain([1,10]);return e.copy=()=>Vn(e,_r()).base(e.base()),Gn.apply(e,arguments),e}function vr(){var e=fr(function(){var e,t,n,r,a,i=0,o=1,s=Rn,l=!1;function c(t){return null==t||isNaN(t=+t)?a:s(0===n?.5:(t=(r(t)-e)*n,l?Math.max(0,Math.min(1,t)):t))}function f(e){return function(t){var n,r;return arguments.length?([n,r]=t,s=e(n,r),c):[s(0),s(1)]}}return c.domain=function(a){return arguments.length?([i,o]=a,e=r(i=+i),t=r(o=+o),n=e===t?0:1/(t-e),c):[i,o]},c.clamp=function(e){return arguments.length?(l=!!e,c):l},c.interpolator=function(e){return arguments.length?(s=e,c):s},c.range=f(jn),c.rangeRound=f(qn),c.unknown=function(e){return arguments.length?(a=e,c):a},function(a){return r=a,e=a(i),t=a(o),n=e===t?0:1/(t-e),c}}()(Rn));return e.copy=function(){return t=e,vr().domain(t.domain()).interpolator(t.interpolator()).clamp(t.clamp()).unknown(t.unknown());var t},Wn.apply(e,arguments)}function yr(e){for(var t=e.length/6|0,n=new Array(t),r=0;r0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),i.push(e.substring(a-=s,a+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return i.reverse().join(n)}),a=void 0===e.currency?"":e.currency[0]+"",i=void 0===e.currency?"":e.currency[1]+"",o=void 0===e.decimal?".":e.decimal+"",s=void 0===e.numerals?ar:function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(lr.call(e.numerals,String)),l=void 0===e.percent?"%":e.percent+"",c=void 0===e.minus?"−":e.minus+"",f=void 0===e.nan?"NaN":e.nan+"";function u(e){var t=(e=Jn(e)).fill,n=e.align,u=e.sign,d=e.symbol,h=e.zero,p=e.width,g=e.comma,b=e.precision,m=e.trim,_=e.type;"n"===_?(g=!0,_="g"):rr[_]||(void 0===b&&(b=12),m=!0,_="g"),(h||"0"===t&&"="===n)&&(h=!0,t="0",n="=");var v="$"===d?a:"#"===d&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",y="$"===d?i:/[%p]/.test(_)?l:"",w=rr[_],x=/[defgprs%]/.test(_);function M(e){var a,i,l,d=v,M=y;if("c"===_)M=w(e)+M,e="";else{var $=(e=+e)<0||1/e<0;if(e=isNaN(e)?f:w(Math.abs(e),b),m&&(e=function(e){e:for(var t,n=e.length,r=1,a=-1;r0&&(a=0)}return a>0?e.slice(0,a)+e.slice(t+1):e}(e)),$&&0===+e&&"+"!==u&&($=!1),d=($?"("===u?u:c:"-"===u||"("===u?"":u)+d,M=("s"===_?cr[8+Kn/3]:"")+M+($&&"("===u?")":""),x)for(a=-1,i=e.length;++a(l=e.charCodeAt(a))||l>57){M=(46===l?o+e.slice(a+1):e.slice(a))+M,e=e.slice(0,a);break}}g&&!h&&(e=r(e,1/0));var k=d.length+e.length+M.length,N=k>1)+d+e+M+N.slice(k);break;default:e=N+d+e+M}return s(e)}return b=void 0===b?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b)),M.toString=function(){return e+""},M}return{format:u,formatPrefix:function(e,t){var n=u(((e=Jn(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(tr(t)/3))),a=Math.pow(10,-r),i=cr[8+r/3];return function(e){return n(a*e)+i}}}}({thousands:",",grouping:[3],currency:["$",""]}),or=ir.format,sr=ir.formatPrefix;const wr=(xr=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(yr),Bt(xr[xr.length-1]));var xr;function Mr(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}const $r=Mr(yr("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));function kr(e,t,n){this.k=e,this.x=t,this.y=n}function Nr(e,t=null){return Cr(e)?2:Pr(e)||null===t?1:function(e,{effDigits:t=2,fallbackSigFigs:n=3,maxSigFigs:r=5,maxDecimals:a=6}={}){const i=e.filter(e=>null!=e&&isFinite(e)),o=i.filter(e=>0!==e).map(Math.abs);if(0===o.length)return 0;const s=e=>Math.floor(Math.log10(e)+1e-10),l=(e,t)=>e[Math.min(e.length-1,Math.floor(t*(e.length-1)))],c=[...i].sort((e,t)=>e-t),f=(e,t)=>l(c,t)-l(c,e),u=f(.25,.75)||f(.1,.9)||f(0,1),d=l([...o].sort((e,t)=>e-t),.75),h=u>0?t-1-s(u):n-1-s(d),p=r-1-s(d);return Math.min(Math.max(h,0),Math.max(p,0),a)}(t)}function Ar(e,t,n){if(null==t||!isFinite(t))return"";if(Cr(e))return t.toFixed(2);if(Pr(e))return t.toFixed(1);const r=Math.pow(10,-n);return 0!==t&&Math.abs(t)-":"<")+r.toFixed(n):t.toFixed(n)}function Sr(e){return parseFloat(e.slice(18))}function Er(e){const t=e.indexOf("__");return-1===t?null:{base:e.slice(0,t),label:e.slice(t+2)}}function Dr(e){const t=Er(e);return t?t.base:e}function Tr(e){return"n"===e||e.startsWith("n_")}function Pr(e){return/^interval_coverage_/.test(e)}function Cr(e){return/_scaled_relative_skill$/.test(Dr(e))}Mr(yr("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Mr(yr("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Mr(yr("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kr.prototype={constructor:kr,scale:function(e){return 1===e?this:new kr(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new kr(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new kr(1,0,0),kr.prototype;const zr=new Map([["model_id","Model"],["wis","WIS"],["wis_scaled_relative_skill","Rel. WIS"],["ae_median","MAE"],["ae_median_scaled_relative_skill","Rel. MAE"],["ae_point","MAE"],["ae_point_scaled_relative_skill","Rel. MAE"],["se_point","MSE"],["se_point_scaled_relative_skill","Rel. MSE"]]);function Ir(e){if(Tr(e))return"N";if(Pr(e))return`${Sr(e)}% Cov.`;const t=Er(e),n=t?t.base:e,r=zr.get(n)||n.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());return t?`${r} (${t.label})`:r}function Or(e){return null==e?[]:Array.isArray(e)?e:[e]}function Ur(e){return 0===e.length?"category":e.every(e=>/^\d{4}-\d{2}-\d{2}$/.test(e))?"date":e.every(e=>""!==e&&!isNaN(e))?"numeric":"category"}const jr={ae_median:["Absolute error of the median. Calculated as the magnitude of the observed value minus the median prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/ae_median_quantile.html"],ae_median_scaled_relative_skill:["Relative skill of the absolute error of the median, scaled in comparison to the baseline model. Compares Model M's average absolute error of the median to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],ae_point:["Absolute error of the point forecast. Calculated as the magnitude of the observed value minus the point prediction. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],ae_point_scaled_relative_skill:["Relative skill of the absolute error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average absolute error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],interval_coverage_50:["50% interval coverage. Measures how often the observed value is captured within the bounds of the 50% prediction interval. Closer to nominal (50%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],interval_coverage_95:["95% interval coverage. Measures how often the observed value is captured within the bounds of the 95% prediction interval. Closer to nominal (95%) coverage is better.","https://epiforecasts.io/scoringutils/reference/interval_coverage.html"],se_point:["Squared error of point forecasts. Calculated as the observed value minus the point prediction, squared. Smaller values are better.","https://epiforecasts.io/scoringutils/reference/get_metrics.forecast_point.html"],se_point_scaled_relative_skill:["Relative skill of the squared error of point forecasts, scaled in comparison to the baseline model. Compares Model M's average squared error of point forecasts to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"],wis:["Weighted interval score. The averaged interval scores (IS) of every prediction interval, plus the difference between the observed value and median. The interval score is the sum of three components: overprediction, underprediction, and dispersion. Lower is better.","https://epiforecasts.io/scoringutils/reference/wis.html"],wis_scaled_relative_skill:["Relative skill of the weighted interval score, scaled in comparison to the baseline model. Compares Model M's average WIS to all other models', for all possible forecasts, then divides that by the same score for the baseline for easy comparison. Smaller values are better, and the baseline always has a value of 1.0.","https://epiforecasts.io/scoringutils/reference/get_pairwise_comparisons.html"]},qr="Number of predictions scored for the associated metric(s).",Hr={_fetchData:null,state:{targets:[],eval_sets:[],task_id_text:{},selected_target:"",selected_plot_type:"Heatmap",selected_disaggregate_by:"",selected_eval_set:"",xaxis_values:[],xaxis_kind:"category",scores_table:[],scores_plot:[]},getSelectedTargetObj(){return this.state.targets.filter(e=>e.target_id===this.state.selected_target)[0]},initialize(e,t,n){console.debug("initialize(): entered");const r=document.getElementById(e);if(null===r)throw`componentDiv DOM node not found: '${e}'`;return this._fetchData=t,this.state.targets=n.targets.map(e=>({...e,metrics:Or(e.metrics),relative_metrics:Or(e.relative_metrics),disaggregate_by:Or(e.disaggregate_by)})),this.state.eval_sets=n.eval_sets,this.state.task_id_text=n.task_id_text,this.state.selected_target=n.targets[0].target_id,this.state.selected_eval_set=n.eval_sets[0].eval_set_name,this.state.selected_disaggregate_by=n.targets[0].disaggregate_by[0],this.state.selected_metric=this.getSelectedTargetObj().metrics[0],function(e){function t(e,t){return $(`
\n \n
\n \n
\n
`)}const n=$('
'),r=$("
"),a=$('
');a.append($('General Options')),a.append(t("predeval_target","Target")),a.append(t("predeval_eval_set","Evaluation set"));const i=$('
').hide();i.append($('Plot Options')),i.append(t("predeval_plot_type","Plot type")),i.append(t("predeval_disaggregate_by","Disaggregate by")),i.append(t("predeval_metric","Metric"));const o=$('
').hide();o.append($('Transformation Definition ')),o.append($('
').hide());const s=$('
');s.append($('Metric Definitions ')),s.append($('
').hide()),r.append(a,i,o,s),n.append(r);const l=$(''),c=$('
'),f=$('').append('').append(''),u=$('
'),d=$('
'),h=$('
').append($('
'));u.append(d,h),c.append(f,u);const p=$('
');p.append(n,l,c),e.empty().append(p)}($(r)),this.initializeUI(),this.addEventHandlers(),this.fetchDataUpdateDisplay(!0,!0),null},initializeUI(){this.initializeTargetUI(),this.initializeEvalSetUI(),this.initializePlotTypeUI(),this.initializeDisaggregateByUI(),this.initializeMetricUI(),this.updateTransformPanel(),this.updateGlossary();const e=document.getElementById("predeval_plotly_div"),t=this.getPlotlyLayout();Plotly.newPlot(e,[],t,{modeBarButtonsToRemove:["lasso2d","autoScale2d"]})},initializeTargetUI(){const e=$("#predeval_target"),t=this.state;t.targets.forEach(function(n){const r=$("").attr("value",n.target_id).prop("selected",n.target_id===t.selected_target).text(n.target_name||n.target_id);e.append(r)})},initializeEvalSetUI(){const e=$("#predeval_eval_set"),t=this.state;this.state.eval_sets.forEach(function(n){const r=n.eval_set_name,a=$("").attr("value",r).prop("selected",r===t.selected_eval_set).text(r);e.append(a)})},initializePlotTypeUI(){const e=$("#predeval_plot_type"),t=this.state;["Line plot","Heatmap"].forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_plot_type).text(n);e.append(r)})},initializeDisaggregateByUI(){const e=$("#predeval_disaggregate_by"),t=this.state,n=this.getSelectedTargetObj();e.empty(),n.disaggregate_by.includes(t.selected_disaggregate_by)||(t.selected_disaggregate_by=n.disaggregate_by[0]),n.disaggregate_by.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===t.selected_disaggregate_by).text(n);e.append(r)})},initializeMetricUI(){const e=this.state,t=$("#predeval_metric"),n=this.getSelectedTargetObj();t.empty(),n.metrics.includes(e.selected_metric)||(e.selected_metric=n.metrics[0]),n.metrics.forEach(function(n){const r=$("").attr("value",n).prop("selected",n===e.selected_metric).text(Ir(n));t.append(r)})},updateGlossary(){let e,t=[];if($("#predeval_plot_tab").hasClass("active"))e=[this.state.selected_metric];else{const n=this.getSelectedTargetObj(),r=(n.metrics||[]).concat(n.relative_metrics||[]);e=[...new Set(r)],t=(this.state.scores_table.columns||[]).filter(Tr)}const n=[...new Set(e.map(Dr))].map(function(e){const[t,n]=jr[e]||["No definition available.",null],r=n?` `:"";return{term:Ir(e),bodyHtml:`${t}${r}`}});if(t.length>0){const e=t.length>1?`${qr} Each N count refers to the metric column(s) to its left.`:qr;n.push({term:"N",bodyHtml:e})}const r=$("#predeval_glossary_list");r.empty(),n.forEach(function(e,t){r.append(`
${e.term}
`),r.append(`
${e.bodyHtml}
`)})},updateTransformPanel(){const e=$("#predeval_options_transform"),t=this.getSelectedTargetObj().transform;if(!t)return void e.hide();const n=$("#predeval_transform_description");n.empty(),n.append($('
').text(t.label)),n.append($('
').text(t.description||"")),e.show()},addEventHandlers(){$("#predeval_target").on("change",function(){Hr.state.selected_target=this.value,Hr.initializeDisaggregateByUI(),Hr.initializeMetricUI(),Hr.updateTransformPanel(),Hr.updateGlossary(),Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_eval_set").on("change",function(){Hr.state.selected_eval_set=this.value,Hr.fetchDataUpdateDisplay(!0,!0)}),$("#predeval_plot_type").on("change",function(){Hr.state.selected_plot_type=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$("#predeval_disaggregate_by").on("change",function(){Hr.state.selected_disaggregate_by=this.value,Hr.fetchDataUpdateDisplay(!0,!1)}),$("#predeval_metric").on("change",function(){Hr.state.selected_metric=this.value,Hr.fetchDataUpdateDisplay(!1,!1)}),$('button[data-bs-toggle="tab"]').on("shown.bs.tab",function(e){"predeval_plot_tab"===e.target.id?(Hr.updatePlot(),$("#predeval_options_plot").fadeIn()):$("#predeval_options_plot").fadeOut(),Hr.updateGlossary()}),$("#predeval_glossary_legend").on("click",function(){const e=$("#predeval_glossary_list"),t=$("#predeval_glossary_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_transform_legend").on("click",function(){const e=$("#predeval_transform_description"),t=$("#predeval_transform_toggle");e.slideToggle(200,function(){e.is(":visible")?t.html("▼"):t.html("▶")})}),$("#predeval_sidebar_toggle").on("click",function(){const e=$(this),t=e.find("i"),n=$("#predeval_options");"true"===e.attr("aria-expanded")?(n.animate({width:"0px"},300),t.removeClass("bi-chevron-left").addClass("bi-chevron-right"),e.attr("aria-expanded","false").removeClass("border-start-0 rounded-end")):(n.animate({width:"25%"},300),t.removeClass("bi-chevron-right").addClass("bi-chevron-left"),e.attr("aria-expanded","true").addClass("border-start-0 rounded-end")),$("#predeval_plot_tab").hasClass("active")&&setTimeout(()=>Hr.updatePlot(),350)})},fetchDataUpdateDisplay(e,t){if(e){const n=[this.fetchScores(t)];console.debug(`fetchDataUpdateDisplay(${e}): waiting on promises`),Promise.all(n).then(t=>{console.debug(`fetchDataUpdateDisplay(${e}): Promise.all() done. updating display`,t),this.updateDisplay()})}else console.debug(`fetchDataUpdateDisplay(${e}): updating display`),this.updateDisplay()},fetchScores(e){const t=[this.fetchScoresTableOrPlot(!1)];return e&&t.push(this.fetchScoresTableOrPlot(!0)),Promise.all(t).then(e=>console.debug("fetchScores(): Promise.all() done")).catch(e=>console.error(`fetchScores(): error: ${e.message}`))},fetchScoresTableOrPlot(e){let t;return e?(t="(None)",this.state.scores_table=[]):(t=this.state.selected_disaggregate_by,this.state.scores_plot=[]),this._fetchData(this.state.selected_target,this.state.selected_eval_set,t).then(t=>{!function(e,t){for(const n of t.columns)if("model_id"!==n&&n!==e)if(Tr(n))for(let e=0;econsole.error(`fetchScoresTableOrPlot(${e}): error: ${t.message}`))},updateDisplay(){console.log("updateDisplay(): entered"),this.updateTable(),this.updatePlot(),this.updateGlossary()},updateTable(){const e=this.state,t=$("#predeval_table_pane");if($.fn.DataTable.isDataTable("#predeval_table")&&$("#predeval_table").DataTable().destroy(),!e.scores_table.columns)return void t.empty().append($('

No data available for the selected target and evaluation set.

'));const n=$('
'),r=$(""),a=$(""),i=$(""),o=e.scores_table.columns;o.forEach(function(e){a.append(i.clone().text(Ir(e)))}),r.append(a),n.append(r),t.empty().append(n);const s=o.map(t=>{if("model_id"===t||Tr(t))return{data:t,name:t};{const n=e.scores_table.map(e=>e[t]),r=Nr(t,n),a=(e,n)=>"display"===n||"filter"===n?Ar(t,e,r):e;return{data:t,name:t,render:a}}}),l=this.getSelectedTargetObj(),c=l&&l.metrics&&l.metrics.length>0?l.metrics[0]:null,f=c&&o.includes(c)?c:"model_id",u=o.indexOf("model_id"),d={data:e.scores_table,columns:s,columnControl:["order",["search","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]],columnDefs:u>=0?[{targets:[u],columnControl:["order",["searchList","spacer","orderAsc","orderDesc","orderClear","spacer","colVis"]]}]:[],order:[{name:f,dir:"asc"}],ordering:{indicators:!1},paging:!1,layout:{topStart:null,topEnd:null},scrollX:!0,fixedColumns:{start:1}};n.DataTable(d)},updatePlot(){const e=document.getElementById("predeval_plotly_div");this.setXaxisValues();const t=this.getPlotlyData();let n=this.getPlotlyLayout();if(0===t.length&&(n={title:{text:"No score data found."}}),e.data&&e.data.length>0){const n={};e.data.forEach(e=>{n[e.name]=e.visible}),t.forEach(e=>{e.name in n&&(e.visible=n[e.name])})}Plotly.react(e,t,n)},setXaxisValues(){const e=this.state.scores_plot.map(e=>e[this.state.selected_disaggregate_by]),t=[...new Set(e)],n="numeric"===Ur(t)?t.sort((e,t)=>Number(e)-Number(t)):t.sort(),r=[...new Set(this.taskIdValuesToText(this.state.selected_disaggregate_by,n))];this.state.xaxis_kind=Ur(r),this.state.xaxis_values=r},getPlotlyLayout(){if(0===this.state.scores_plot.length)return{};let e;"Line plot"===this.state.selected_plot_type?e=Ir(this.state.selected_metric):"Heatmap"===this.state.selected_plot_type&&(e=null);let t={autosize:!0,showlegend:!0,title:{text:`${Ir(this.state.selected_metric)} by ${this.state.selected_disaggregate_by}`,xanchor:"center",yanchor:"top"},xaxis:{title:{text:this.state.selected_disaggregate_by},type:"date"===this.state.xaxis_kind?"date":"category",categoryorder:"array",categoryarray:this.state.xaxis_values,fixedrange:!1,automargin:!0},yaxis:{title:{text:e},fixedrange:!1,automargin:!0}};if("Line plot"===this.state.selected_plot_type){t.autosize=!0,Pr(this.state.selected_metric)&&(t.yaxis.range=[0,100],t.xaxis.showline=!0,t.xaxis.mirror=!0,t.yaxis.zeroline=!1);const e=Pr(n=this.state.selected_metric)?Sr(n):Cr(n)?1:null;null!==e&&(t.shapes=[{type:"line",xref:"paper",x0:0,x1:1,yref:"y",y0:e,y1:e,line:{color:"#444444",width:1.5,dash:"dash"},layer:"above"}]),$("#predeval_plotly_div").css("height","75vh")}else if("Heatmap"===this.state.selected_plot_type){t.width="#predeval_plotly_div".width;const e=new Set(this.state.scores_plot.map(e=>e.model_id)).size,n=Math.max(200+20*e,.75*$(window).height());t.height=n,$("#predeval_plotly_div").css("height",n+"px")}var n;return t},getPlotlyData(){return"Line plot"===this.state.selected_plot_type?this.getPlotlyDataLinePlot():"Heatmap"===this.state.selected_plot_type?this.getPlotlyDataHeatmap():void 0},getPlotlyDataLinePlot(){const e=this.state;let t=[];if(0===e.scores_plot.length)return t;const n=a(e.scores_plot,e=>e.model_id),r=e.scores_plot.map(t=>t[e.selected_metric]),i=Nr(e.selected_metric,r);for(const[r,a]of n){let n=a.map(t=>t[e.selected_disaggregate_by]);n=this.taskIdValuesToText(e.selected_disaggregate_by,n);const o=a.map(t=>t[e.selected_metric]);let s=n.map((e,t)=>[e,o[t]]);s.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const l=s.map(e=>e[0]),c=s.map(e=>e[1]),f={x:l,y:c,mode:"lines+markers",type:"scatter",name:r,cliponaxis:!1,hovermode:!1,customdata:c.map(t=>Ar(e.selected_metric,t,i)),hovertemplate:`model: %{data.name}
${e.selected_disaggregate_by}: %{x}
${Ir(this.state.selected_metric)}: %{customdata}`,opacity:.7};t.push(f)}return t},getPlotlyDataHeatmap(){console.log("getPlotlyDataHeatmap(): entered");const e=this.state,t=Pr(e.selected_metric),n=Cr(e.selected_metric);let r=[];if(0===e.scores_plot.length)return r;const o=e.scores_plot.map(t=>t[e.selected_metric]),s=Nr(e.selected_metric,o);let l,c,f,u,d;const h=i(e.scores_plot,t=>t[e.selected_metric]),p=function(e,t){let n;if(void 0===t)for(const t of e)null!=t&&(n=t)&&(n=t);else{let r=-1;for(let a of e)null!=(a=t(a,++r))&&(n=a)&&(n=a)}return n}(e.scores_plot,t=>t[e.selected_metric]);if(t){l=0,d=`.${s}f`,f=vr(wr);const t=[0,1],n=Sr(e.selected_metric),r=Math.max(n,100-n);c=ur([n-r,n+r],t)}else{const t=i(e.scores_plot.filter(t=>t[e.selected_metric]>0),t=>t[e.selected_metric]);let r;if(l=t/2,d=`.${s}f`,n){const e=vr(wr);f=t=>e(1-t),r=[0,1];const t=Math.max(1/(h+l),p+l);c=_r([1/t,t],r)}else{const e=vr($r);f=t=>function(e){return`rgb(${parseInt(e.substring(1,3),16)}, ${parseInt(e.substring(3,5),16)}, ${parseInt(e.substring(5,7),16)})`}(e(t)),r=[0,1],c=_r([h+l,p+l],r)}}const g=e.scores_plot.map(t=>c(t[e.selected_metric]+l)),b=[...new Set(g)].filter(e=>void 0!==e).sort((e,t)=>e-t),m=ur([b[0],b[b.length-1]],[0,1]),_=b.map(e=>[m(e),f(e)]);u={colorscale:_,showscale:!0,colorbar:{tickmode:"array",tickvals:c.ticks().map(e=>c(e+l)),ticktext:c.ticks().map(c.tickFormat(12,d))}};const v=a(e.scores_plot,e=>e.model_id);let y=e.xaxis_values,w=Array.from(v.keys()),x=[],M=[];for(const[t,n]of v){let t=n.map(t=>t[e.selected_disaggregate_by]);t=this.taskIdValuesToText(e.selected_disaggregate_by,t);const r=n.map(t=>c(t[e.selected_metric]+l)),a=n.map(t=>t[e.selected_metric]);let i=t.map((e,t)=>[e,r[t],a[t]]);i.sort((t,n)=>e.xaxis_values.indexOf(t[0])-e.xaxis_values.indexOf(n[0]));const o=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[1]:null}),s=e.xaxis_values.map(e=>{const t=i.find(t=>t[0]===e);return t?t[2]:null});x.push(o),M.push(s)}let $={x:y,y:w,z:x,customdata:M.map(t=>t.map(t=>null===t?null:Ar(e.selected_metric,t,s))),type:"heatmap",hovertemplate:`${e.selected_disaggregate_by}: %{x}
model: %{y}
${Ir(this.state.selected_metric)}: %{customdata}`,hoverongaps:!1};return r.push({...$,...u}),r},taskIdValuesToText(e,t){const n=this.state;if(void 0!==n.task_id_text&&Object.keys(n.task_id_text).includes(e)){const r=n.task_id_text[e];return t.map(e=>r[e])}return t}},Lr=Hr;export{Lr as default}; \ No newline at end of file diff --git a/src/predevals.js b/src/predevals.js index d2c8c0a..1b75d2c 100644 --- a/src/predevals.js +++ b/src/predevals.js @@ -909,8 +909,11 @@ const App = { cliponaxis: false, hovermode: false, - // pre-format rather than let Plotly round, so a hover value and its table cell - // always read the same + // pre-format through render_score() rather than let Plotly round, so hover goes + // through the same rule as every other score display -- including its '<0.01' + // floor and its '' for a missing score, where `%{y:.Nf}` rendered a bare 'NaN'. + // (The table's own decimals come from the non-disaggregated `scores_table`, so + // while disaggregation is on the two panes can still differ in decimals.) customdata: y.map(v => render_score(thisState.selected_metric, v, metricDecimals)), hovertemplate: `model: %{data.name}
${thisState.selected_disaggregate_by}: %{x}
${score_col_name_to_text(this.state.selected_metric)}: %{customdata}`, opacity: 0.7, @@ -1078,8 +1081,8 @@ const App = { y: y, z: z, - // pre-format rather than let Plotly round, so a hover value and its table cell always - // read the same + // pre-format through render_score() rather than let Plotly round, so hover goes through + // the same rule as every other score display (see the line plot's note on this) customdata: z_orig.map(row => row.map(v => v === null ? null : render_score(thisState.selected_metric, v, metricDecimals))), type: 'heatmap', hovertemplate: `${thisState.selected_disaggregate_by}: %{x}
model: %{y}
${score_col_name_to_text(this.state.selected_metric)}: %{customdata}`, diff --git a/src/utils.js b/src/utils.js index 476cd44..85227cc 100644 --- a/src/utils.js +++ b/src/utils.js @@ -46,6 +46,12 @@ function get_round_decimals(col_name, values = null) { * renders as `12346`, never `12300`. `maxSigFigs` only ever removes decimals, and it bottoms out * at 0. * + * Note: `maxSigFigs` is applied as a hard minimum against the spread, so it wins where the two + * disagree. Above ~1e4 that can flatten neighbors the spread would have resolved: [12345.1, + * 12345.2] wants 1 decimal and gets 0. The loss is the sixth significant figure rather than the + * first, which is the trade the cap is there to make; raise `maxSigFigs` if a hub's scores live at + * that scale and the distinction matters. + * * Note: depends on the rows currently in `scores_table`, so precision can shift under filtering. * That is inherent to any column-wide rule, and is the price of keeping decimal points aligned. * @@ -63,8 +69,13 @@ function score_decimals(values, {effDigits = 2, fallbackSigFigs = 3, maxSigFigs const quantile = (sorted, p) => sorted[Math.min(sorted.length - 1, Math.floor(p * (sorted.length - 1)))]; const sorted = [...vals].sort((a, b) => a - b); - // fall back to the full range when the IQR is degenerate (few rows, or many ties) - const spread = (quantile(sorted, 0.75) - quantile(sorted, 0.25)) || (sorted[sorted.length - 1] - sorted[0]); + // Widen the window in rungs when the IQR is degenerate (few rows, or many ties). Going straight + // from the IQR to the full range would hand the column back to the outliers the IQR anchoring + // exists to keep out: eight tied 0.5s next to one 52000 would render as "1" nine times over, + // which is the very failure this function was written to fix. The full range is still the last + // rung, but by then the column is tied from P10 to P90 and there is nothing else left to measure. + const spread_between = (lo, hi) => quantile(sorted, hi) - quantile(sorted, lo); + const spread = spread_between(0.25, 0.75) || spread_between(0.10, 0.90) || spread_between(0, 1); const large = quantile([...nonZeroAbs].sort((a, b) => a - b), 0.75); const d_spread = spread > 0 ? effDigits - 1 - mag(spread) : fallbackSigFigs - 1 - mag(large); diff --git a/test/utils.js b/test/utils.js index b4668e3..e088e8a 100644 --- a/test/utils.js +++ b/test/utils.js @@ -118,9 +118,22 @@ test('whole-number-scale columns drop to 0 decimals', assert => { assert.equal(render_score('ae_median', 12345.6, 0), '12346'); }); -test('falls back to the range, then to sig figs, as the IQR degenerates', assert => { +test('widens the quantile window, then falls back to sig figs, as the IQR degenerates', assert => { assert.equal(score_decimals([42.7]), 1, 'single value: 3 sig figs'); - assert.equal(score_decimals([5, 5, 5]), 2, 'all identical: IQR and range both zero'); + assert.equal(score_decimals([5, 5, 5]), 2, 'all identical: every window is zero-width'); +}); + +test('a tie-heavy column is not handed back to its outlier', assert => { + // the IQR is zero here, so the window widens to P10-P90 rather than dropping to the full + // range. Going straight to the range would let the 52000 set the precision and render the + // nine rows that matter as "1" nine times over - the issue-88 failure, one fallback later + const tied = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.52, 52000]; + assert.equal(score_decimals(tied), 3); + assert.equal(render_score('wis', 0.5, 3), '0.500'); + assert.equal(render_score('wis', 0.52, 3), '0.520'); + + // tied past P10-P90 too: nothing left to measure, so the range is the last rung + assert.equal(score_decimals([1, 1, 1, 1, 1, 1, 1, 1, 1, 1000]), 0); }); test('one high outlier does not flatten the column', assert => { @@ -144,6 +157,19 @@ test('guards floating-point overshoot at exact powers of ten', assert => { assert.equal(score_decimals([0.001, 0.002, 0.009]), 4); }); +test('resolves the covidhub tiny-WIS column (issue #48 fixture)', assert => { + // real data: document.predevals.state.scores_table wis column. The old min-anchored rule gave + // 4 decimals, which flattened 0.000805 and 0.000759 onto the same "0.0008" + const wisValues = [0.000925048661683814, 0.00075907107176393, 0.000804968609706757, + 0.00138310730984419, 0.00143697666395866, 0.00055223613252158, 0.000892415568463205]; + assert.equal(score_decimals(wisValues), 5); + + const rendered = wisValues.map(v => render_score('wis', v, 5)); + assert.deepEqual(rendered, + ['0.00093', '0.00076', '0.00080', '0.00138', '0.00144', '0.00055', '0.00089']); + assert.equal(new Set(rendered).size, wisValues.length, 'no two rows collapse onto one string'); +}); + test('respects maxDecimals', assert => { assert.equal(score_decimals([0.000925, 0.000759, 0.000805]), 6, 'jointly binding with the spread'); assert.equal(score_decimals([0.000925, 0.000759, 0.000805], {maxDecimals: 4}), 4); From ee428b6d4db72d4946c353262e177191e6439f2c Mon Sep 17 00:00:00 2001 From: matthewcornell Date: Tue, 15 Sep 2026 11:35:37 -0400 Subject: [PATCH 3/4] Say what each score-precision test is asserting, per review on #97 Co-Authored-By: Claude Opus 5 (1M context) --- test/ui.js | 24 +++++++- test/utils.js | 151 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 158 insertions(+), 17 deletions(-) diff --git a/test/ui.js b/test/ui.js index efe910c..aed3f1b 100644 --- a/test/ui.js +++ b/test/ui.js @@ -274,6 +274,12 @@ QUnit.module('scores table headers', (hooks) => { // scores table cell rendering tests // +// These tests cover the whole per-column path the scores table takes: read the column's values -> +// pick one decimal count for the column (get_round_decimals()) -> turn each value into a cell +// string (render_score()). test/utils.js pins down the two functions in isolation; what is asserted +// here is that updateTable() actually wires them together, on the DataTables column config, with +// the column's real values rather than the fixed 1 decimal that predates issue #88. + QUnit.module('scores table cell rendering', (hooks) => { useStubbedApp(hooks); const dtConfig = stubDataTable(hooks); @@ -302,6 +308,11 @@ QUnit.module('scores table cell rendering', (hooks) => { const renderFor = (columnName) => dtConfig().columns.find((c) => c.name === columnName).render; test('renders score cells at the decimals that resolve the column (issue #88)', assert => { + // Case: the table is handed the flusight `wis__log` column, whose values all sit + // between 0.19 and 1.27. + // Desired: the cells come back at the 2 decimals that separate these models. Rendering at + // the old fixed 1 decimal would print all three of these rows as "0.3", which is the + // screenshot in issue #88. App.state.scores_table = tableWith({wis__log: WIS_LOG_ROWS}); App.updateTable(); @@ -312,8 +323,12 @@ QUnit.module('scores table cell rendering', (hooks) => { }); test('hands DataTables the raw number for sorting', assert => { - // render() runs for every DataTables type, and '<0.01' in a sort key would silently switch - // the column to lexicographic ordering + // Case: DataTables calls the same render() for every data type it needs, not just for + // display - 'sort' and 'type' among them. + // Desired: only 'display' and 'filter' get the rounded string. Sorting and type detection + // get the untouched number, so the column orders by value; a string such as '<0.01' in a + // sort key would silently switch the whole column to lexicographic ordering. 'filter' gets + // the string on purpose, so that a search matches what the reader can actually see. App.state.scores_table = tableWith({wis__log: WIS_LOG_ROWS}); App.updateTable(); @@ -324,6 +339,11 @@ QUnit.module('scores table cell rendering', (hooks) => { }); test('renders whole-number-scale columns without a decimal place', assert => { + // Case: an ae_median column in the tens-to-hundreds, spread wide enough that a tenth + // of a case carries no information. + // Desired: whole numbers, and every integer digit kept - "291", not "290.7" and not the + // "290" that a significant-figures rule would produce. The decimal count is per column, so + // this and the wis__log column above coexist in one table at different widths. App.state.scores_table = tableWith({ae_median: [290.690197703552, 101.287927350427, 76.9, 498.2, 11.3]}); App.updateTable(); diff --git a/test/utils.js b/test/utils.js index e088e8a..55ed3cf 100644 --- a/test/utils.js +++ b/test/utils.js @@ -46,7 +46,16 @@ test('hexToRGB() handles 6-char hex', assert => { QUnit.module('get_round_decimals'); +// `get_round_decimals()` is the per-column entry point the scores table calls once per column. It +// answers one question: does this column get a fixed decimal count, independent of the values, or +// should its precision be measured from the values in it? Relative skill (always 2 decimals) and +// coverage (always 1; the values are 0-100 percentages) are fixed. Every other metric column is +// measured, by `score_decimals()` below. + test('returns 1 for plain metric columns (no values)', assert => { + // Case: a caller has the column name but not the column's values. + // Desired: fall back to the fixed 1 decimal that predates issue #88. With no values in hand + // there is no variation to measure, so the historical default stands. assert.equal(get_round_decimals('wis'), 1); assert.equal(get_round_decimals('mae'), 1); assert.equal(get_round_decimals('wis__log'), 1); @@ -54,23 +63,38 @@ test('returns 1 for plain metric columns (no values)', assert => { }); test('returns 2 for scaled_relative_skill columns', assert => { + // Case: a relative skill column, whose values are ratios centered on the 1.0 baseline. + // Desired: always 2 decimals. The scale is fixed and known in advance, and "1.05 vs 0.98" is + // the comparison readers make, so this column does not want the measured rule. assert.equal(get_round_decimals('wis_scaled_relative_skill'), 2); assert.equal(get_round_decimals('mae_scaled_relative_skill'), 2); assert.equal(get_round_decimals('mae_scaled_relative_skill__log'), 2); }); test('with values: defers to score_decimals() for non-coverage, non-skill columns', assert => { + // Case: an ordinary metric column with its values in hand - the normal scores-table path. + // Desired: hand off to score_decimals(), so the decimals track each column's own variation. A + // covidhub-scale WIS column needs 6 decimals; a column spanning 1.5 to 47.7 needs 2. assert.equal(get_round_decimals('wis', [0.000925, 0.000759, 0.000805]), 6); assert.equal(get_round_decimals('ae_median', [0.001, 0.002, 0.009]), 4); assert.equal(get_round_decimals('wis', [1.5, 2.3, 47.7]), 2); }); test('with values: still returns 2 for scaled_relative_skill regardless of values', assert => { + // Case: a relative skill column whose values the measured rule would read very differently - + // near-zero ratios, or ratios in the hundreds. + // Desired: the fixed 2 still wins. This column's decimal count does not depend on its values + // at all, so a filtered-down set of rows can never change its width. assert.equal(get_round_decimals('wis_scaled_relative_skill', [0.000925, 0.000759]), 2); assert.equal(get_round_decimals('mae_scaled_relative_skill', [100, 200]), 2); }); test('with values: still returns 1 for interval_coverage columns (values are 0-100)', assert => { + // Case: a coverage column. convertDataColumnTypes() has already rescaled it to 0-100, so + // the values are percentages; the 0-1 values in the second assertion are a shape that should + // never reach here. + // Desired: the fixed 1 decimal wins either way. "52.9" is the readable form of a coverage + // rate, and the measured rule would otherwise pad the column out on odd inputs. assert.equal(get_round_decimals('interval_coverage_50', [47.7, 93.3]), 1); assert.equal(get_round_decimals('interval_coverage_95', [0.001, 0.0005]), 1); }); @@ -78,6 +102,33 @@ test('with values: still returns 1 for interval_coverage columns (values are 0-1 QUnit.module('score_decimals'); +// WHAT `score_decimals()` IS FOR, AND WHAT THE TESTS BELOW ASSERT +// +// It picks ONE decimal count for an entire score column, so every cell in the column prints with +// the same number of decimal places and the decimal points line up. The desired behavior, which +// the tests in this module pin down one rule at a time: +// +// 1. Resolve the comparison between models, not the precision of any single score. The reader's +// question is "how do these models rank against each other", so the column carries enough +// decimals to show roughly two digits of the SPREAD among the models. A column whose models all +// sit between 0.19 and 1.27 has to separate them (2 decimals); a column whose models sit +// between 1247 and 15679 does not need a decimal place at all (0). +// 2. Measure that spread between quantiles (Q1 to Q3), never between min and max, so that one +// blown-up model cannot flatten the leaderboard and one near-zero model cannot pad every other +// row with spurious decimals. The significant-figure cap is anchored on Q3 for the same reason. +// 3. Never round to the left of the decimal point. This is a decimals rule (`toFixed`), not a +// significant-figures rule (R's `signif`, the alternative weighed on issue #88): a +// national-scale MAE of 12345.6 prints as "12346", never as "12300". +// 4. Degrade in rungs rather than off a cliff when the IQR is zero (too few rows, or many tied +// rows): widen Q1-Q3 to P10-P90, then to the full range, and only then fall back to 3 +// significant figures of a typical value. Each rung gives up a little outlier resistance, in +// order, so the resistant answer is always tried first. +// +// One consequence to keep in mind while reading the expected numbers below: because the decimals +// are set by the spread, they can be one more than it takes to merely tell adjacent rows apart. A +// spread of 0.02 asks for 3 decimals, since two digits of that spread is "0.020" - not the 2 +// decimals that distinguishing 0.50 from 0.52 would need on its own. + // The issue-88 regression case: flusight-dashboard `wis__log`, all 58 models. Every value sits in // [0.19, 1.27], so the old min-anchored rule cleared its "nothing rounds to zero" bar at one // decimal and rendered 21 of these 58 rows as the same "0.3". @@ -100,6 +151,11 @@ const WIS_LOG_VALUES = [ ]; test('returns 0 when there is nothing non-zero to resolve', assert => { + // Case: a column with no non-zero finite value in it at all - no rows survived the + // filters, or every score is zero, missing, or infinite. + // Desired: 0 decimals. There is no magnitude to anchor on, so any decimal count would be + // invented. 0 prints these cells as a plain "0" instead of implying a precision (0.00) that + // nothing in the data supports. assert.equal(score_decimals([]), 0); assert.equal(score_decimals([0, 0, 0]), 0); assert.equal(score_decimals([null, undefined]), 0); @@ -107,59 +163,92 @@ test('returns 0 when there is nothing non-zero to resolve', assert => { }); test('resolves the flusight `wis__log` column past one decimal (issue #88)', assert => { + // Case: the bug report itself. 58 flusight models, every wis__log score between 0.19 and + // 1.27, with a Q1-Q3 spread of 0.161. + // Desired: 2 decimals, so neighboring models stay distinguishable. The old rule asked only + // "does any value round to zero at this width", cleared that bar at 1 decimal, and printed 21 + // of the 58 models as the identical string "0.3". assert.equal(score_decimals(WIS_LOG_VALUES), 2, 'IQR of 0.161 resolves at 2 decimals'); }); test('whole-number-scale columns drop to 0 decimals', assert => { - // national-scale MAE: every integer digit is kept, only the decimal place goes. A - // significant-figure rule (R's signif) would render these as 1250, 12300 - this one does not + // Case: a national-scale MAE column - values in the thousands, spread (Q1-Q3) about 3000. + // Desired: 0 decimals. A tenth of a case is noise at this scale, so the decimal place goes - + // but every integer digit stays, which is rule 3 above. R's signif() would have rendered these + // as 1250 and 12300, discarding real information; a decimals rule cannot do that. const national = [1247.3, 1583.9, 2104.6, 2890.2, 3312.8, 4501.7, 5120.4, 8842.1, 12345.6, 15678.9]; assert.equal(score_decimals(national), 0); assert.equal(render_score('ae_median', 12345.6, 0), '12346'); }); test('widens the quantile window, then falls back to sig figs, as the IQR degenerates', assert => { + // Case: columns with no measurable spread anywhere - a single row, or every row tied. No + // comparison is being made, so there is nothing for rule 1 to resolve. + // Desired: the last rung, 3 significant figures of a typical value, which is a reasonable + // default for a number about which nothing else is known: 42.7 keeps its tenth, and 5 prints + // as "5.00". assert.equal(score_decimals([42.7]), 1, 'single value: 3 sig figs'); assert.equal(score_decimals([5, 5, 5]), 2, 'all identical: every window is zero-width'); }); test('a tie-heavy column is not handed back to its outlier', assert => { - // the IQR is zero here, so the window widens to P10-P90 rather than dropping to the full - // range. Going straight to the range would let the 52000 set the precision and render the - // nine rows that matter as "1" nine times over - the issue-88 failure, one fallback later + // Case: nine models effectively tied around 0.5 (one of them at 0.52) and one model that + // blew up at 52000. Q1 and Q3 are both 0.5, so the IQR is zero and the rule has to widen. + // Desired: 3 decimals, measured from the P10-P90 spread of 0.02, so the tied models stay + // legible as "0.500" and "0.520". That is one decimal more than telling 0.50 from 0.52 needs: + // the rule shows two digits of the spread itself ("0.020"), per rule 1 above. + // Why P10-P90 and not the full range: the range here is 52000, which yields 0 decimals and + // prints the nine models that matter as "1" nine times over - exactly the issue-88 failure, + // one fallback rung later. const tied = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.52, 52000]; assert.equal(score_decimals(tied), 3); assert.equal(render_score('wis', 0.5, 3), '0.500'); assert.equal(render_score('wis', 0.52, 3), '0.520'); - // tied past P10-P90 too: nothing left to measure, so the range is the last rung + // Case: tied past P10-P90 as well, so even the widened window measures nothing. + // Desired: fall to the next rung, the full range, which is the last thing left to measure. It + // gives 0 decimals here, which is also the right answer for a column that really is nine 1s + // and one 1000. assert.equal(score_decimals([1, 1, 1, 1, 1, 1, 1, 1, 1, 1000]), 0); }); test('one high outlier does not flatten the column', assert => { - // the cap is anchored on Q3, not the max: anchoring on the max would give d_cap = 0 here and - // render the nine rows that matter as "0", "1", "1", ... + // Case: an ordinary leaderboard (0.42 to 2.05) with one model that blew up at 52000 - the + // common real-world shape, and the one rule 2 exists for. + // Desired: 2 decimals, set by the contenders. Both anchors ignore the outlier: the spread is + // Q1-Q3 (0.58), and the significant-figure cap is anchored on Q3 (1.19). Anchoring the cap on + // the max instead would give 0 decimals and print the nine models that matter as "0", "1", + // "1", ... const withOutlier = [0.42, 0.55, 0.61, 0.73, 0.88, 1.02, 1.19, 1.41, 2.05, 52000]; assert.equal(score_decimals(withOutlier), 2); assert.equal(render_score('wis', 0.42, 2), '0.42'); }); test('one low outlier does not pad the column with decimals', assert => { - // min-anchoring - the old rule, and the `minSigFigs` floor considered on #88 - would force - // decimals here to keep 0.05 visible, giving "183.70" and "392.80" + // Case: the mirror image - a column in the hundreds with one model scoring 0.05. + // Desired: 0 decimals, again set by the contenders (Q1-Q3 is 107). Min-anchoring - the old + // rule, and the `minSigFigs` floor weighed on issue #88 - would keep 0.05 visible by giving + // every other row two decimals it cannot support: "183.70", "392.80". The 0.05 row instead + // renders as "<1" (see render_score below), which is how the column stays honest about that + // model without taxing all the others. const withOutlier = [0.05, 183.7, 220.4, 250.9, 290.7, 312.5, 392.8]; assert.equal(score_decimals(withOutlier), 0); assert.equal(render_score('wis', 183.7, 0), '184'); }); test('guards floating-point overshoot at exact powers of ten', assert => { - // log10(0.001) is -3.0000000000000004, which would floor to -4 without the epsilon + // Case: a spread that lands on an exact power of ten (0.002 - 0.001 = 0.001). + // Desired: 4 decimals. This is a numerical guard rather than a display policy: log10(0.001) + // evaluates to -3.0000000000000004, which floors to -4 and would hand the column a spurious + // fifth decimal were it not for the epsilon in mag(). assert.equal(score_decimals([0.001, 0.002, 0.009]), 4); }); test('resolves the covidhub tiny-WIS column (issue #48 fixture)', assert => { - // real data: document.predevals.state.scores_table wis column. The old min-anchored rule gave - // 4 decimals, which flattened 0.000805 and 0.000759 onto the same "0.0008" + // Case: real covidhub data - an entire WIS column down at 1e-3, spread 1.7e-4. + // Desired: enough decimals that no two models collapse onto the same string, which for this + // column is 5. The Set assertion at the end is the requirement; the 5 is just what meets it. + // The old min-anchored rule stopped at 4 and printed both 0.000805 and 0.000759 as "0.0008". const wisValues = [0.000925048661683814, 0.00075907107176393, 0.000804968609706757, 0.00138310730984419, 0.00143697666395866, 0.00055223613252158, 0.000892415568463205]; assert.equal(score_decimals(wisValues), 5); @@ -171,18 +260,28 @@ test('resolves the covidhub tiny-WIS column (issue #48 fixture)', assert => { }); test('respects maxDecimals', assert => { + // Case: a column so tightly spread (4.6e-5) that resolving it asks for more decimals than + // a table cell can usefully show. + // Desired: the measured spread governs until it reaches maxDecimals (6 by default), and then + // maxDecimals governs. It is a hard ceiling on the column's width, not a suggestion. assert.equal(score_decimals([0.000925, 0.000759, 0.000805]), 6, 'jointly binding with the spread'); assert.equal(score_decimals([0.000925, 0.000759, 0.000805], {maxDecimals: 4}), 4); }); test('ignores null, undefined, and non-finite entries', assert => { + // Case: a column with holes - models missing a score for this target, or an infinite one. + // Desired: those entries take no part in the decision. The column's width is exactly what the + // finite values alone would have produced. assert.equal(score_decimals([null, undefined, Infinity, -Infinity, 1.5, 2.3, 47.7]), score_decimals([1.5, 2.3, 47.7])); }); test('counts zeros as observations when measuring the spread', assert => { - // a zero is a real score, so it belongs in the column's distribution even though it can't - // anchor a magnitude. Only the magnitude anchors skip it + // Case: a column holding a genuine 0.0 score alongside ordinary values. + // Desired: the zero counts as a row when measuring the spread - it widens Q1-Q3 from 0.8 to + // 2.3 here, which takes the column from 2 decimals down to 1 - but it is skipped when picking + // the typical magnitude for the significant-figure cap, since log10(0) is not a magnitude. A + // zero is a real score and belongs in the column's distribution; it just cannot anchor one. assert.equal(score_decimals([0, 1.5, 2.3, 47.7]), 1, 'the zero widens the IQR'); assert.equal(score_decimals([1.5, 2.3, 47.7]), 2); }); @@ -190,7 +289,16 @@ test('counts zeros as observations when measuring the spread', assert => { QUnit.module('render_score'); +// `render_score()` turns one value into the string for one cell, given the decimals that +// get_round_decimals() chose for the whole column. Its three jobs, one per test below: apply the +// fixed decimal counts for skill and coverage columns; never let the column-wide rounding claim +// that a real non-zero score is zero (the "<0.01" form); and render absent data as an empty cell. + test('distinguishes `wis__log` values that all rendered as "0.3" (issue #88)', assert => { + // Case: the issue-88 column once more, this time end to end - decimals from score_decimals(), + // strings from render_score(). + // Desired: the three rows visible in the issue screenshot print as three different numbers, + // and the column as a whole resolves into 34 distinct strings where the old rule produced 7. const decimals = score_decimals(WIS_LOG_VALUES); // the three rows visible in the issue screenshot @@ -204,11 +312,21 @@ test('distinguishes `wis__log` values that all rendered as "0.3" (issue #88)', a }); test('overrides the column decimals for skill and coverage columns', assert => { + // Case: a caller passes decimals of 0 for a skill or coverage column. + // Desired: render_score() ignores the argument and applies the fixed decimal count anyway - 2 + // for skill, 1 for coverage. These columns are pinned here as well as in get_round_decimals(), + // so no caller can accidentally unpin them. assert.equal(render_score('wis_scaled_relative_skill', 0.798407240258868, 0), '0.80'); assert.equal(render_score('interval_coverage_50', 52.884615384615394, 0), '52.9'); }); test('flags values too small to survive the column rounding', assert => { + // Case: a column rounded to 2 decimals contains a score of 0.0001 - a real, non-zero + // result that toFixed(2) would print as "0.00". + // Desired: "<0.01" instead, so the reader sees "smaller than this column can show" rather than + // a claim that the model scored zero. This is what makes the outlier-resistant anchors safe: a + // low outlier loses its digits but not its meaning. A value that rounds up to a visible digit + // prints normally, and a true zero is not flagged, because it really is zero. assert.equal(render_score('wis', 0.0001, 2), '<0.01'); assert.equal(render_score('wis', -0.0001, 2), '>-0.01'); assert.equal(render_score('wis', 0.05, 0), '<1'); @@ -217,6 +335,9 @@ test('flags values too small to survive the column rounding', assert => { }); test('renders missing and non-finite values as empty', assert => { + // Case: a model with no score for this cell, or a non-finite one. + // Desired: an empty cell. "NaN" or "Infinity" sitting in a leaderboard reads as if it were a + // scoring result. assert.equal(render_score('wis', null, 2), ''); assert.equal(render_score('wis', undefined, 2), ''); assert.equal(render_score('wis', Infinity, 2), ''); From 13578f995da6305edccca82883c47566afad324f Mon Sep 17 00:00:00 2001 From: matthewcornell Date: Wed, 16 Sep 2026 10:11:39 -0400 Subject: [PATCH 4/4] Document the score rounding rule in the README Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5f22d7f..fe06c27 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # predevals A JavaScript module for interactive exploration of forecast evaluations. +## Score rounding + +Each score column in the table gets one number of decimal places, chosen from the values in that column so the decimal points line up. The rule is: measure the spread of the middle half of the column (its interquartile range) and use just enough decimals to show that spread to two digits. A column whose models fall between 0.19 and 1.27 gets 2 decimals (`0.27`, `0.31`, `0.30`); one whose models fall between 1247 and 15679 gets none (`1247`, `15679`). Two guards sit on top: no column shows more than 5 significant figures, and rounding never touches digits left of the decimal point, so 12345.6 displays as `12346`, never `12300`. Using the middle half rather than the smallest and largest values is what keeps one blown-up model from flattening the whole column and one near-zero model from padding every other row with meaningless decimals; a value too small to show at the column's width displays as less than the smallest value that width can show -- `<0.01` in a 2-decimal column, `<0.0001` in a 4-decimal one -- rather than as `0`. Relative skill columns always use 2 decimals and coverage columns 1, since those scales are known in advance. Rounding is display-only: sorting and downloaded data always use the full values. + # Development ## Installing dev requirements