chromosomix 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -11
- package/dist/THIRD-PARTY-NOTICES.txt +2 -2
- package/dist/assets/{ConnectCard-CWRFeF4q.js → ConnectCard-CNwlR_yV.js} +1 -1
- package/dist/assets/{Tour-5RTXNjqt.js → Tour-Dn4L7jES.js} +1 -1
- package/dist/assets/analysis.worker-2Jx8_NWN.js +8 -0
- package/dist/assets/annotations.worker-Bd03nKdJ.js +28 -0
- package/dist/assets/index-BZqg8J4S.js +106 -0
- package/dist/assets/index-Cxw-esX1.css +1 -0
- package/dist/assets/likelihood.worker-CUgAXfAe.js +1 -0
- package/dist/assets/reader.worker-DKXrm0nO.js +9 -0
- package/dist/assets/{three-D5ICz1As.js → three-BZagS2ne.js} +1 -1
- package/dist/assets/{tutorial-qCyAYx6Y.js → tutorial-DOptkiKU.js} +1 -1
- package/dist/assets/workspace-ZYKuBclx.js +15 -0
- package/dist/index.html +2 -2
- package/dist-cli/THIRD-PARTY-NOTICES.txt +2 -2
- package/dist-cli/chromosomix.mjs +5965 -1369
- package/package.json +6 -1
- package/dist/assets/analysis.worker-DZ9FXIW0.js +0 -8
- package/dist/assets/annotations.worker-Bybt4X5J.js +0 -27
- package/dist/assets/index-CJPGLvTr.css +0 -1
- package/dist/assets/index-DkMx8MnH.js +0 -103
- package/dist/assets/reader.worker-CuEqyC9X.js +0 -9
- package/dist/assets/workspace-tu5v3vK_.js +0 -17
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{bq as Gl,br as Gn,bs as Oa,bt as Vl,bu as Hl,bv as kl,bw as Wl}from"./index-BZqg8J4S.js";/**
|
|
2
2
|
* @license
|
|
3
3
|
* Copyright 2010-2026 Three.js Authors
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{E as Se,F as qe,L as Te,G as xe,H as Ae}from"./index-DkMx8MnH.js";const m="4DNESC23ZYOF",A="4dn",r="chr15",oe="4DNFIKI77KEM",re="4DNFI3OPG4RB",ae="4DNFI4GZZC7Z",v={start:3e7,end:6e7},S={start:381e5,end:50025e3},$e=15e6,$=5e3,q=4,d={rows:45662501,cols:48312501},E=47215001,Ee=25e3,Oe="1",De="analysis:compartment-e1",Ne="analysis:insulation-w",O="analysis:insulation:insulation-domains";function f(e){return e instanceof HTMLElement&&e.getClientRects().length>0}function i(e,n=document){for(const c of n.querySelectorAll(e))if(f(c))return c;return null}function l(e){return(e?.textContent??"").replace(/\s+/g," ").trim()}function p(){return i(".analysis-drawer:not(.collapsed)")}function se(e){for(const n of document.querySelectorAll(".analysis-row"))if(f(n)&&l(n.querySelector(".analysis-row-title"))===e)return n;return null}function y(e){const n=e.charAt(0).toUpperCase()+e.slice(1);return i(`.panel-${e} .panel-tab`)??i(`.head-panels button[aria-label="${n} panel"]`)}function ie(e){return i(`.panel-${e}:not(.collapsed) .panel-column-body`)??y(e)}function Ie(e){for(const n of document.querySelectorAll(".panel-analysis section.analysis-card"))if(f(n)&&l(n.querySelector(".card-head")).startsWith(e))return n;return null}function le(){return i('select.res-pick, [role="radiogroup"][aria-label="resolution"]')}function ge(){for(const e of document.querySelectorAll(".controls-card"))if(f(e)&&l(e.querySelector(".controls-title"))==="Map")return e;return null}function ce(e){for(const n of ge()?.querySelectorAll("label.field")??[])if(l(n.querySelector(".field-label"))===e)return n.querySelector("select, input");return null}function Ce(){for(const e of ge()?.querySelectorAll("button")??[])if(l(e)==="O/E")return e;return null}function _(e){for(const n of p()?.querySelectorAll(".param-field")??[]){if(l(n.querySelector(".field-label"))!==e)continue;const c=n.querySelector('input[type="number"]')??n.querySelector('input:not([type="range"])');return c instanceof HTMLInputElement?c:null}return null}function Me(e,n){e!==null&&(e.value=n,e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})))}function H(){for(const e of document.querySelectorAll("section.annotation-card"))if(f(e)&&l(e.querySelector(".card-head, .card-title, h3")).startsWith("Manual annotations"))return e;return null}function D(e){for(const n of H()?.querySelectorAll(".manual-form")??[])if(l(n.querySelector(".manual-form-title"))===e)return n;return null}function ue(e){for(const n of e?.querySelectorAll("button")??[])if(l(n)==="add")return n;return null}function N(){for(const e of document.querySelectorAll(".controls-card"))if(f(e)&&l(e.querySelector(".controls-title"))==="Export")return e.querySelector(".export-row");return null}function Re(e){for(const n of p()?.querySelectorAll("label.param-field")??[]){if(l(n.querySelector(".field-label"))!==e)continue;const c=n.querySelector("select");return c instanceof HTMLSelectElement?c:null}return null}function Le(){const e=Re("phase by gene density");e===null||e.value===""||(e.value="",e.dispatchEvent(new Event("change",{bubbles:!0})))}function de(e){for(const n of p()?.querySelectorAll(".analysis-figure")??[])if(l(n.querySelector(".analysis-figure-head")).startsWith(e))return n;return null}function he(){for(const e of document.querySelectorAll(".store-drawer .portal-group"))if(f(e)&&l(e.querySelector(".portal-group-key"))===m)return e;return null}function I(){const e=i(".store-drawer .portal-search");return e instanceof HTMLInputElement?e:null}function pe(){const e=p()?.querySelector(".param-sequences");return e==null?null:[...e.querySelectorAll("label.param-check")].filter(n=>n.querySelector("input")?.checked===!0).map(n=>l(n.querySelector("span")))}function Pe(e){for(const n of p()?.querySelectorAll(".param-sequences label.param-check")??[])if(l(n.querySelector("span"))===e)return n;return null}function Fe(e){if(e===void 0)return null;for(const n of p()?.querySelectorAll("label.param-check")??[])if(l(n.querySelector("span"))===e.label)return n;return null}function me(){return p()?.querySelector(".analysis-run > button")??null}function C(e,n){return e!==null&&e.length===n.length&&e.every((c,M)=>c===n[M])}function z(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):null}function Be(e){return e===null||e.view!=="region"||e.region===void 0?null:e.region.split(":")[0]}function Ue(e){if(e===null||e.view!=="region"||e.region===void 0)return null;const n=/^([^:]+):([\d,]+)-([\d,]+)$/.exec(e.region);return n===null?null:{contig:n[1],start:Number(n[2].replace(/,/g,"")),end:Number(n[3].replace(/,/g,""))}}function fe(e){return i(`.content .tviewport .tr .td[title="${e}"]`)}function be(e){const n=i(".content input.input-region");n instanceof HTMLInputElement&&(n.value=e,n.dispatchEvent(new Event("input",{bubbles:!0})),n.dispatchEvent(new KeyboardEvent("keydown",{key:"Enter",bubbles:!0})))}function s(e){return e.toLocaleString("en-US")}function _e(e){const n=()=>e.view()?.uri.includes(oe)===!0||e.file()?.includes(oe)===!0,c=()=>Be(e.view())===r,M=t=>e.runs(t).some(o=>C(z(o.provenance.params.sequences),[r])),Z=t=>e.tracks()?.entries.find(o=>o.source.kind==="remote"&&o.source.url.includes(t)),ke=()=>e.tracks()?.byId(De),G=()=>e.tracks()?.entries.filter(t=>t.id.startsWith(Ne))??[],R=()=>{const t=G()[0];return t===void 0?null:i(`.ann-row[data-id="${t.id}"]`)},K=()=>R()?.querySelector(".ann-more")?.getAttribute("aria-expanded")==="true",Y=t=>e.saved().some(o=>o.toLowerCase().endsWith(t)),w=(t,o)=>t.contig===r&&Math.abs(t.bp-o)<=Ee,ye=()=>(e.marks()??[]).some(t=>t.kind==="arrowhead"&&(w(t.a,d.rows)&&w(t.b,d.cols)||w(t.a,d.cols)&&w(t.b,d.rows))),we=()=>(e.marks()??[]).some(t=>t.kind==="line"&&t.axis!=="horizontal"&&w(t.at,E)),T=()=>i(`.ann-row[data-id="${O}"]`),x=()=>T()?.querySelector(".ann-more")?.getAttribute("aria-expanded")==="true",L=()=>{const t=e.tracks()?.byId(O);return t!==void 0&&qe(t)==="lane"},V=()=>{const t=e.tracks()?.laneFor(O,Te)?.placement;return t===void 0?null:{bottom:t.bottom,left:t.left}},j=t=>{for(const o of T()?.querySelectorAll(".ann-place")??[])if(f(o)&&new RegExp(`\\b${t} edge\\b`).test(o.title))return o;return null},b=()=>i(".content .panel-grid"),P=t=>()=>t()??y("aesthetics"),Q=t=>()=>{const o=i(".content .heatmap-canvas");if(o===null)return null;const a=e.square({contig:r,...t});return a===null?o:{within:o,box:{left:a.left,top:a.top,right:a.right,bottom:a.bottom}}},X=Se()?"⇧ Shift and ⌥ Option":"Shift and Alt";let F=!1;const ve=()=>{if(F||fe(r)!==null)return;const t=i(".content .tviewport"),o=e.sequences()?.indexOf(r)??-1;if(t===null||o<0)return;F=!0;const a=t.querySelector(".tr")?.offsetHeight??28;t.scrollTop=Math.max(0,o*a-t.clientHeight/2),t.dispatchEvent(new Event("scroll"))},J=(t,o)=>({id:t,chapter:o,title:"Open the Analysis panel",text:"Analyses run here, in this page, on the map on screen.",target:()=>y("analysis"),done:()=>e.panelOpen("analysis"),needs:{holds:n,back:"open-set"}}),ee=(t,o,a,u,h)=>({id:t,chapter:o,title:u,text:h,action:"choose",target:P(()=>ce("score")),done:()=>e.score()===a,needs:{holds:n,back:"open-set"}}),te=(t,o,a,u,h={})=>{const W=`analysis-${o}`,g=()=>e.task()===o;return[J(W,t),...h.tour?.(W)??[],{id:o,chapter:t,title:`Choose ${a}`,text:u.choose,target:()=>se(a),done:g,needs:{holds:()=>e.panelOpen("analysis"),back:W},missing:"Not in the list — empty the box over it if a word is typed there."},{id:`${o}-none`,chapter:t,title:"Untick every sequence",text:u.none,prepare:h.setup,target:()=>p()?.querySelector('button[title="Untick every sequence"]')??null,done:()=>{const k=pe();return k!==null&&(k.length===0||C(k,[r]))},needs:{holds:g,back:o}},{id:`${o}-sequence`,chapter:t,title:`Tick ${r}`,text:u.tick,target:()=>Pe(r),done:()=>C(pe(),[r]),needs:{holds:g,back:o}},...h.form?.(g)??[],{id:`${o}-run`,chapter:t,title:"Run it",text:u.run,prepare:h.setup,target:me,done:()=>h.ran===void 0?M(o):e.runs(o).some(k=>C(z(k.provenance.params.sequences),[r])&&h.ran(k.provenance.params)),needs:{holds:()=>g()||e.running(o),back:o}},...h.after?.(g)??[],{id:`${o}-close`,chapter:t,title:"Back to the map",text:"The result is a track as well as a figure. Close the drawer to see it beside the map.",target:()=>p()?.querySelector(".analysis-drawer-head .btn-close")??null,done:()=>e.task()===null}]},ne=()=>{const t=G();return[Z(ae),Z(re),ke(),...t.length===0?[void 0]:t]},B=()=>ne().map(t=>Fe(t)),U=(t,o,a,u)=>({id:t,chapter:"Compartments",title:o,text:a,target:()=>Ie(o),needs:{holds:()=>e.panelOpen("analysis"),back:u}});return[{id:"welcome",chapter:"Welcome",title:"A first session, on real data",text:`Open a Hi-C map from the 4D Nucleome project, find its compartments, domains and a loop on ${r}, save what you made, and set it against 4DN’s own — in the real app, one step at a time.`,hero:!0,agenda:!0,next:"let’s go"},{id:"stores",chapter:"The 4DN store",title:"Open the data stores",text:"Stores are catalogues of published data, read from where they are kept. Press this button to open the drawer that holds them.",target:()=>i('.head-files button[aria-label="stores"]'),done:()=>e.store()!==null},{id:"store",chapter:"The 4DN store",title:"Switch to 4DN",text:"It opens on the lab’s own store, RSG. Press 4DN to switch to the 4D Nucleome project’s.",target:()=>i(`.store-drawer .store-tile[data-store="${A}"]`),done:()=>e.store()===A,needs:{holds:()=>e.store()!==null,back:"stores"}},{id:"search",chapter:"The 4DN store",title:"Find an experiment",text:["Type ",{name:m,copy:!0}," in the search box: Hi-C on K562 cells, about 190 million contacts."],action:"type",target:I,focus:!0,done:()=>I()?.value.toUpperCase().includes(m)===!0&&he()!==null,mistake:()=>{const t=(I()?.value??"").trim().toUpperCase();return t===""||m.startsWith(t)||t.includes(m)?null:t},needs:{holds:()=>e.store()===A,back:"store"},assist:{label:"type it for me",title:`Put ${m} in the search box`,run:()=>{const t=I();t!==null&&(t.value=m,t.dispatchEvent(new Event("input",{bubbles:!0})))}}},{id:"open-set",chapter:"The 4DN store",title:"Open it with its tracks",text:"One press opens the contact map with the tracks 4DN computed from it — compartments, insulation and boundaries — without downloading its 1.9 GB.",target:()=>he()?.querySelector(".portal-session")??null,done:n,needs:{holds:()=>e.store()===A||n(),back:"store"},missing:`Not on screen — type ${m} in the store’s search box again.`},{id:"look-general",chapter:"The map",title:"The General panel",text:"What the file is: its bin size and contacts under File, its sequences under Sequences, and anything else it carries under Metadata.",target:()=>ie("general")},{id:"resolution-250",chapter:"The map",title:"Pick 250 kb",text:"A map is stored at several resolutions, the size of one bin. 250 kb is coarse enough to show a whole chromosome’s compartments.",action:"choose",target:le,done:()=>e.binsize()===25e4,needs:{holds:n,back:"open-set"},missing:"Waiting for the map to open."},{id:"chromosome",chapter:"The map",title:`Open ${r}`,text:`Press ${r} in the table to open its map.`,prepare:()=>{F=!1},target:()=>(ve(),fe(r)),done:c,needs:{holds:n,back:"open-set"},missing:`Not on screen — scroll the table to ${r}.`},{id:"look-map",chapter:"The map",title:"The contact map",text:`Each pixel is how often two stretches of ${r} touch; 4DN’s tracks are drawn under it. Scroll to zoom into the picture at this resolution, drag to move around, and double-click to fit it back.`,target:b},{id:"look-aesthetics",chapter:"The map",title:"The Aesthetics panel",text:"How the picture is drawn: the Map card sets its score, smoothing and colours, the Tracks card its tracks, and Export saves it as a figure.",target:()=>ie("aesthetics")},ee("score-correlation","Compartments",xe,"Draw it as a correlation","In the Map card, set score to correlation."),{id:"look-correlation",chapter:"Compartments",title:"The plaid",text:"Red where two stretches share a compartment, blue where they do not. Compartments sums this pattern up as one track, E1, positive in one compartment and negative in the other.",target:b},...te("Compartments","compartments","Compartments",{choose:"It splits a chromosome into A and B compartments from the map’s plaid.",none:"It runs on every sequence of the file to begin with. Press none…",tick:`…then tick ${r}, the chromosome on screen.`,run:"Press run. It takes a few seconds."},{tour:t=>[U("tasks-2d","2D tasks","These read the contact map: its decay with distance, insulation, compartments, loops and more.",t),U("tasks-3d","3D tasks","These build a model of the chromosome’s shape from the map, or set one against it.",t),U("tasks-1d","1D tasks","These read tracks rather than the map: peaks, profiles over features, correlations between tracks.",t)],setup:Le,after:t=>[{id:"look-saddle",chapter:"Compartments",title:"The saddle",text:"Bins sorted by E1, low to high: bright corners on the diagonal mean like touches like, A with A and B with B. The numbers under it say how much.",target:()=>de("Saddle"),needs:{holds:t,back:"compartments"}}]}),{id:"look-compartments",chapter:"Compartments",title:"Your compartments",text:"E1 and its A and B calls are drawn left of the map. Compare them with 4DN’s compartment track under it.",target:b},ee("score-balanced","Zooming in",Ae,"Back to contacts","Domains are about how often stretches touch, not how alike they are: set score back to balanced."),{id:"zoom",chapter:"Zooming in",title:"Zoom along the diagonal",text:`Hold ${X}, then drag across the lit square, from one corner to the other: that stretch opens.`,action:"drag",target:Q(v),done:()=>{const t=e.view();return c()&&t?.region?.includes(":")===!0&&t.region2===void 0},needs:{holds:c,back:"chromosome"},assist:{label:"zoom for me",title:`Open ${r}:${s(v.start)}-${s(v.end)}`,run:()=>be(`${r}:${s(v.start)}-${s(v.end)}`)}},{id:"resolution-5",chapter:"Zooming in",title:"Switch to 5 kb",text:"At 5 kb the domains along the diagonal come into view, and the loops at their corners.",action:"choose",target:le,done:()=>e.binsize()===$,needs:{holds:n,back:"open-set"}},{id:"zoom-domains",chapter:"Zooming in",title:"Closer, on a few domains",text:`Once more: hold ${X} and drag across the lit square.`,action:"drag",target:Q(S),done:()=>{const t=Ue(e.view());return t!==null&&t.contig===r&&t.end-t.start<=$e&&e.binsize()===$},needs:{holds:()=>c()&&e.binsize()===$,back:"resolution-5"},missing:"Not in view — press zoom for me, or go back a step.",assist:{label:"zoom for me",title:`Open ${r}:${s(S.start)}-${s(S.end)}`,run:()=>be(`${r}:${s(S.start)}-${s(S.end)}`)}},{id:"look-domains",chapter:"Zooming in",title:"Domains",text:"Each dark square along the diagonal is a domain, or TAD: a stretch that touches itself more than its neighbours. Most sit inside bigger ones — the big square from 45.7 to 48.3 Mb holds two.",target:b},{id:"oe-on",chapter:"Zooming in",title:"Turn on O/E",text:"O/E divides each pixel by what its distance predicts, so what is left is structure rather than distance.",target:P(Ce),done:()=>e.view()?.oe===!0,needs:{holds:n,back:"open-set"}},{id:"smooth",chapter:"Zooming in",title:"Smooth it",text:"At 5 kb most pixels hold a handful of contacts. Set smooth to 3 × 3, which averages each pixel with the eight around it.",action:"choose",target:P(()=>ce("smooth")),done:()=>e.view()?.smooth===Oe,needs:{holds:n,back:"open-set"}},{id:"look-oe",chapter:"Zooming in",title:"Domains and compartments",text:"Red is more contact than the distance predicts, blue less: the domains are red squares, and the checkerboard behind them is A and B again.",target:b},...te("Insulation","insulation","Diamond insulation",{choose:"It scores how much contact crosses each bin; its dips are the boundaries between domains.",none:"Again, press none…",tick:`…then tick ${r}.`,run:"Press run. Four windows over a whole chromosome at 5 kb take a little while."},{form:t=>[{id:"insulation-scales",chapter:"Insulation",title:"Four scales",text:`Set scales to ${q}. The window is 10 bins, 50 kb here, and each scale doubles it: 50, 100, 200 and 400 kb, one insulation track each.`,action:"type",target:()=>_("scales"),focus:!0,done:()=>Number(_("scales")?.value)===q,needs:{holds:t,back:"insulation"},assist:{label:"set it for me",title:`Set scales to ${q}`,run:()=>Me(_("scales"),String(q))}}],ran:t=>t.scales===q&&e.binsize()===$}),{id:"look-insulation",chapter:"Insulation",title:"Your insulation, at four scales",text:"Four scores are drawn left of the map, one per window, with the boundaries and the domains between them. The scales are the TAD hierarchy: the 50 kb window dips at the edge of every small domain, the 400 kb one only at the borders of the big ones. A border every window finds is high in the hierarchy; one only the narrow windows see is a subTAD’s, nested inside a bigger domain.",target:b},{id:"annotations",chapter:"Marks",title:"Open the Annotations panel",text:"Every track has a row here, the ones you computed among them, and so do the marks you draw.",target:()=>y("annotations"),done:()=>e.panelOpen("annotations"),needs:{holds:n,back:"open-set"}},{id:"mark-loop",chapter:"Marks",title:"Mark the loop",text:["The big domain has a dot at its corner: a loop, its two borders held together. In Manual annotations, under Arrowheads, type ",{name:`${r}:${s(d.rows)}`,copy:!0}," in rows and ",{name:`${r}:${s(d.cols)}`,copy:!0}," in columns, then press add."],target:()=>D("Arrowheads")??H(),done:ye,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"Not on screen — scroll the Annotations panel to Manual annotations.",assist:{label:"mark it for me",title:`An arrowhead at ${r}:${s(d.rows)} × ${r}:${s(d.cols)}`,run:()=>{const t=D("Arrowheads"),[o,a]=[...t?.querySelectorAll("input")??[]];o===void 0||a===void 0||(o.value=`${r}:${s(d.rows)}`,a.value=`${r}:${s(d.cols)}`,ue(t)?.click())}}},{id:"mark-border",chapter:"Marks",title:"Mark the weak border",text:["Inside that domain one border is weak: the 400 kb window barely dips there, 4DN calls it Weak, and it splits the domain into two subTADs. Under Lines, keep vertical, type ",{name:`${r}:${s(E)}`,copy:!0}," and press add."],target:()=>D("Lines")??H(),done:we,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"Not on screen — scroll the Annotations panel to Manual annotations.",assist:{label:"mark it for me",title:`A vertical line at ${r}:${s(E)}`,run:()=>{const t=D("Lines"),o=t?.querySelector("select"),a=t?.querySelector("input");o==null||a===null||a===void 0||(o.value="vertical",a.value=`${r}:${s(E)}`,ue(t)?.click())}}},{id:"look-marks",chapter:"Marks",title:"A loop and a subTAD border",text:"The arrowhead points at the loop closing the big domain, and the line marks the border inside it. Find the same place on your four insulation tracks, left of the map: a deep dip at 50 kb, barely one at 400 kb — that is the hierarchy, read off one bin.",target:b},{id:"insulation-row",chapter:"Tracks",title:"Unfold your insulation’s settings",text:"A computed track is a track like any other: press the arrow on your first insulation row.",target:()=>R()?.querySelector(".ann-more")??null,done:K,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"No insulation row — run Diamond insulation again."},{id:"insulation-bigwig",chapter:"Tracks",title:"Save it as a bigWig",text:"Press bigWig to save the score as a file IGV, deepTools and pyBigWig open — written here, in this page, with nothing uploaded.",target:()=>{for(const t of R()?.querySelectorAll(".ann-exports button")??[])if(l(t)==="bigWig")return t;return null},done:()=>Y(".bw"),needs:{holds:()=>e.panelOpen("annotations")&&K(),back:"insulation-row"}},{id:"domains",chapter:"Tracks",title:"Unfold the domains’ settings",text:"Press the arrow on the Insulation domains row.",target:()=>T()?.querySelector(".ann-more")??null,done:x,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"No Insulation domains row — run Diamond insulation with its domains on."},{id:"domains-display",chapter:"Tracks",title:"Draw the domains as a 1D track",text:"Domains are outlined on the map. Choose 1D track to draw them as a lane beside it instead.",action:"choose",target:()=>T()?.querySelector(`select[data-display="${O}"]`)??null,done:L,needs:{holds:x,back:"domains"}},{id:"domains-bottom",chapter:"Tracks",title:"Put it under the map",text:"Press the bottom edge to draw the lane under the map…",target:()=>j("bottom"),done:()=>V()?.bottom===!0,needs:{holds:()=>x()&&L(),back:"domains-display"}},{id:"domains-left",chapter:"Tracks",title:"Take it off the side",text:"…and the left edge to take it off the left.",target:()=>j("left"),done:()=>{const t=V();return t!==null&&t.bottom&&!t.left},needs:{holds:()=>x()&&L(),back:"domains-display"}},{id:"export-format",chapter:"The figure",title:"Choose PDF",text:"The Export card at the top of the Aesthetics panel saves what is on screen — the map, your marks and every track — as a figure. Choose PDF (vector): lines and text stay sharp at any size.",action:"choose",target:()=>N()?.querySelector("select.select-format")??y("aesthetics"),done:()=>N()?.querySelector("select.select-format")?.value==="pdf",needs:{holds:n,back:"open-set"}},{id:"export-save",chapter:"The figure",title:"Save the figure",text:"Press the download button beside it.",target:()=>N()?.querySelector(".export-acts button")??y("aesthetics"),done:()=>Y(".pdf"),needs:{holds:()=>N()?.querySelector("select.select-format")?.value==="pdf",back:"export-format"}},J("analysis-trackcorr","Track correlation"),{id:"trackcorr",chapter:"Track correlation",title:"Choose Track correlation",text:"It measures how closely every pair of loaded tracks agrees.",target:()=>se("Track correlation"),done:()=>e.task()==="trackcorr",needs:{holds:()=>e.panelOpen("analysis"),back:"analysis-trackcorr"},missing:"Not in the list — empty the box over it if a word is typed there."},{id:"tick-tracks",chapter:"Track correlation",title:"Tick every track",text:[{name:ae}," and ",{name:re},", 4DN’s insulation and E1, your E1, and your insulation at all four scales."],target:()=>B().map(t=>t?.closest(".param-field")??null).find(t=>t!==null)??null,done:()=>B().every(t=>t?.querySelector("input")?.checked===!0),needs:{holds:()=>e.task()==="trackcorr",back:"trackcorr"},missing:"Not in the list — a track did not load, or was closed.",assist:{label:"tick them for me",title:"Tick every track in the list",run:()=>{for(const t of B()){const o=t?.querySelector("input");o!=null&&!o.checked&&o.click()}}}},{id:"trackcorr-run",chapter:"Track correlation",title:"Run it",text:`Every pair is compared over the windows all of them have values in, which is ${r}.`,target:me,done:()=>{const t=ne();return t.some(o=>o===void 0)?!1:e.runs("trackcorr").some(o=>{const a=new Set(z(o.provenance.params.tracks)??[]);return t.every(u=>u!==void 0&&a.has(u.id))})},needs:{holds:()=>e.task()==="trackcorr"||e.running("trackcorr"),back:"trackcorr"}},{id:"look-trackcorr",chapter:"Track correlation",title:"Yours against 4DN’s",text:"Each square compares two tracks: red where they rise and fall together, blue where one rises as the other falls. Find yours against 4DN’s — an unphased E1 can match upside down, at −1 — and your four scales against each other: neighbouring windows agree most, the hierarchy again.",target:()=>de("Track correlation")},{id:"console",chapter:"The console",title:"Every step is a command",text:"Open the console: each file you opened and each run you made is a line you can paste into a terminal to do it again.",target:()=>i('.head-actions button[aria-label="console"]')??i('button[aria-label="console"]'),done:()=>e.consoleOpen()},{id:"finish",chapter:"Done",title:"That’s the tour",text:`You opened a map from 4DN, called compartments and domains at four scales on ${r}, marked a loop and a subTAD border, saved a track and a figure, and set it all against 4DN’s own. The tutorial is on the landing page and in About whenever you want it again.`,hero:!0}]}export{r as TUTORIAL_SEQUENCE,m as TUTORIAL_SET,A as TUTORIAL_STORE,_e as tutorialSteps};
|
|
1
|
+
import{E as Se,F as qe,L as Te,G as xe,H as Ae}from"./index-BZqg8J4S.js";const m="4DNESC23ZYOF",A="4dn",r="chr15",oe="4DNFIKI77KEM",re="4DNFI3OPG4RB",ae="4DNFI4GZZC7Z",v={start:3e7,end:6e7},S={start:381e5,end:50025e3},$e=15e6,$=5e3,q=4,d={rows:45662501,cols:48312501},E=47215001,Ee=25e3,Oe="1",De="analysis:compartment-e1",Ne="analysis:insulation-w",O="analysis:insulation:insulation-domains";function f(e){return e instanceof HTMLElement&&e.getClientRects().length>0}function i(e,n=document){for(const c of n.querySelectorAll(e))if(f(c))return c;return null}function l(e){return(e?.textContent??"").replace(/\s+/g," ").trim()}function p(){return i(".analysis-drawer:not(.collapsed)")}function se(e){for(const n of document.querySelectorAll(".analysis-row"))if(f(n)&&l(n.querySelector(".analysis-row-title"))===e)return n;return null}function y(e){const n=e.charAt(0).toUpperCase()+e.slice(1);return i(`.panel-${e} .panel-tab`)??i(`.head-panels button[aria-label="${n} panel"]`)}function ie(e){return i(`.panel-${e}:not(.collapsed) .panel-column-body`)??y(e)}function Ie(e){for(const n of document.querySelectorAll(".panel-analysis section.analysis-card"))if(f(n)&&l(n.querySelector(".card-head")).startsWith(e))return n;return null}function le(){return i('select.res-pick, [role="radiogroup"][aria-label="resolution"]')}function ge(){for(const e of document.querySelectorAll(".controls-card"))if(f(e)&&l(e.querySelector(".controls-title"))==="Map")return e;return null}function ce(e){for(const n of ge()?.querySelectorAll("label.field")??[])if(l(n.querySelector(".field-label"))===e)return n.querySelector("select, input");return null}function Ce(){for(const e of ge()?.querySelectorAll("button")??[])if(l(e)==="O/E")return e;return null}function _(e){for(const n of p()?.querySelectorAll(".param-field")??[]){if(l(n.querySelector(".field-label"))!==e)continue;const c=n.querySelector('input[type="number"]')??n.querySelector('input:not([type="range"])');return c instanceof HTMLInputElement?c:null}return null}function Me(e,n){e!==null&&(e.value=n,e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})))}function H(){for(const e of document.querySelectorAll("section.annotation-card"))if(f(e)&&l(e.querySelector(".card-head, .card-title, h3")).startsWith("Manual annotations"))return e;return null}function D(e){for(const n of H()?.querySelectorAll(".manual-form")??[])if(l(n.querySelector(".manual-form-title"))===e)return n;return null}function ue(e){for(const n of e?.querySelectorAll("button")??[])if(l(n)==="add")return n;return null}function N(){for(const e of document.querySelectorAll(".controls-card"))if(f(e)&&l(e.querySelector(".controls-title"))==="Export")return e.querySelector(".export-row");return null}function Re(e){for(const n of p()?.querySelectorAll("label.param-field")??[]){if(l(n.querySelector(".field-label"))!==e)continue;const c=n.querySelector("select");return c instanceof HTMLSelectElement?c:null}return null}function Le(){const e=Re("phase by gene density");e===null||e.value===""||(e.value="",e.dispatchEvent(new Event("change",{bubbles:!0})))}function de(e){for(const n of p()?.querySelectorAll(".analysis-figure")??[])if(l(n.querySelector(".analysis-figure-head")).startsWith(e))return n;return null}function he(){for(const e of document.querySelectorAll(".store-drawer .portal-group"))if(f(e)&&l(e.querySelector(".portal-group-key"))===m)return e;return null}function I(){const e=i(".store-drawer .portal-search");return e instanceof HTMLInputElement?e:null}function pe(){const e=p()?.querySelector(".param-sequences");return e==null?null:[...e.querySelectorAll("label.param-check")].filter(n=>n.querySelector("input")?.checked===!0).map(n=>l(n.querySelector("span")))}function Pe(e){for(const n of p()?.querySelectorAll(".param-sequences label.param-check")??[])if(l(n.querySelector("span"))===e)return n;return null}function Fe(e){if(e===void 0)return null;for(const n of p()?.querySelectorAll("label.param-check")??[])if(l(n.querySelector("span"))===e.label)return n;return null}function me(){return p()?.querySelector(".analysis-run > button")??null}function C(e,n){return e!==null&&e.length===n.length&&e.every((c,M)=>c===n[M])}function z(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):null}function Be(e){return e===null||e.view!=="region"||e.region===void 0?null:e.region.split(":")[0]}function Ue(e){if(e===null||e.view!=="region"||e.region===void 0)return null;const n=/^([^:]+):([\d,]+)-([\d,]+)$/.exec(e.region);return n===null?null:{contig:n[1],start:Number(n[2].replace(/,/g,"")),end:Number(n[3].replace(/,/g,""))}}function fe(e){return i(`.content .tviewport .tr .td[title="${e}"]`)}function be(e){const n=i(".content input.input-region");n instanceof HTMLInputElement&&(n.value=e,n.dispatchEvent(new Event("input",{bubbles:!0})),n.dispatchEvent(new KeyboardEvent("keydown",{key:"Enter",bubbles:!0})))}function s(e){return e.toLocaleString("en-US")}function _e(e){const n=()=>e.view()?.uri.includes(oe)===!0||e.file()?.includes(oe)===!0,c=()=>Be(e.view())===r,M=t=>e.runs(t).some(o=>C(z(o.provenance.params.sequences),[r])),Z=t=>e.tracks()?.entries.find(o=>o.source.kind==="remote"&&o.source.url.includes(t)),ke=()=>e.tracks()?.byId(De),G=()=>e.tracks()?.entries.filter(t=>t.id.startsWith(Ne))??[],R=()=>{const t=G()[0];return t===void 0?null:i(`.ann-row[data-id="${t.id}"]`)},K=()=>R()?.querySelector(".ann-more")?.getAttribute("aria-expanded")==="true",Y=t=>e.saved().some(o=>o.toLowerCase().endsWith(t)),w=(t,o)=>t.contig===r&&Math.abs(t.bp-o)<=Ee,ye=()=>(e.marks()??[]).some(t=>t.kind==="arrowhead"&&(w(t.a,d.rows)&&w(t.b,d.cols)||w(t.a,d.cols)&&w(t.b,d.rows))),we=()=>(e.marks()??[]).some(t=>t.kind==="line"&&t.axis!=="horizontal"&&w(t.at,E)),T=()=>i(`.ann-row[data-id="${O}"]`),x=()=>T()?.querySelector(".ann-more")?.getAttribute("aria-expanded")==="true",L=()=>{const t=e.tracks()?.byId(O);return t!==void 0&&qe(t)==="lane"},V=()=>{const t=e.tracks()?.laneFor(O,Te)?.placement;return t===void 0?null:{bottom:t.bottom,left:t.left}},j=t=>{for(const o of T()?.querySelectorAll(".ann-place")??[])if(f(o)&&new RegExp(`\\b${t} edge\\b`).test(o.title))return o;return null},b=()=>i(".content .panel-grid"),P=t=>()=>t()??y("aesthetics"),Q=t=>()=>{const o=i(".content .heatmap-canvas");if(o===null)return null;const a=e.square({contig:r,...t});return a===null?o:{within:o,box:{left:a.left,top:a.top,right:a.right,bottom:a.bottom}}},X=Se()?"⇧ Shift and ⌥ Option":"Shift and Alt";let F=!1;const ve=()=>{if(F||fe(r)!==null)return;const t=i(".content .tviewport"),o=e.sequences()?.indexOf(r)??-1;if(t===null||o<0)return;F=!0;const a=t.querySelector(".tr")?.offsetHeight??28;t.scrollTop=Math.max(0,o*a-t.clientHeight/2),t.dispatchEvent(new Event("scroll"))},J=(t,o)=>({id:t,chapter:o,title:"Open the Analysis panel",text:"Analyses run here, in this page, on the map on screen.",target:()=>y("analysis"),done:()=>e.panelOpen("analysis"),needs:{holds:n,back:"open-set"}}),ee=(t,o,a,u,h)=>({id:t,chapter:o,title:u,text:h,action:"choose",target:P(()=>ce("score")),done:()=>e.score()===a,needs:{holds:n,back:"open-set"}}),te=(t,o,a,u,h={})=>{const W=`analysis-${o}`,g=()=>e.task()===o;return[J(W,t),...h.tour?.(W)??[],{id:o,chapter:t,title:`Choose ${a}`,text:u.choose,target:()=>se(a),done:g,needs:{holds:()=>e.panelOpen("analysis"),back:W},missing:"Not in the list — empty the box over it if a word is typed there."},{id:`${o}-none`,chapter:t,title:"Untick every sequence",text:u.none,prepare:h.setup,target:()=>p()?.querySelector('button[title="Untick every sequence"]')??null,done:()=>{const k=pe();return k!==null&&(k.length===0||C(k,[r]))},needs:{holds:g,back:o}},{id:`${o}-sequence`,chapter:t,title:`Tick ${r}`,text:u.tick,target:()=>Pe(r),done:()=>C(pe(),[r]),needs:{holds:g,back:o}},...h.form?.(g)??[],{id:`${o}-run`,chapter:t,title:"Run it",text:u.run,prepare:h.setup,target:me,done:()=>h.ran===void 0?M(o):e.runs(o).some(k=>C(z(k.provenance.params.sequences),[r])&&h.ran(k.provenance.params)),needs:{holds:()=>g()||e.running(o),back:o}},...h.after?.(g)??[],{id:`${o}-close`,chapter:t,title:"Back to the map",text:"The result is a track as well as a figure. Close the drawer to see it beside the map.",target:()=>p()?.querySelector(".analysis-drawer-head .btn-close")??null,done:()=>e.task()===null}]},ne=()=>{const t=G();return[Z(ae),Z(re),ke(),...t.length===0?[void 0]:t]},B=()=>ne().map(t=>Fe(t)),U=(t,o,a,u)=>({id:t,chapter:"Compartments",title:o,text:a,target:()=>Ie(o),needs:{holds:()=>e.panelOpen("analysis"),back:u}});return[{id:"welcome",chapter:"Welcome",title:"A first session, on real data",text:`Open a Hi-C map from the 4D Nucleome project, find its compartments, domains and a loop on ${r}, save what you made, and set it against 4DN’s own — in the real app, one step at a time.`,hero:!0,agenda:!0,next:"let’s go"},{id:"stores",chapter:"The 4DN store",title:"Open the data stores",text:"Stores are catalogues of published data, read from where they are kept. Press this button to open the drawer that holds them.",target:()=>i('.head-files button[aria-label="stores"]'),done:()=>e.store()!==null},{id:"store",chapter:"The 4DN store",title:"Switch to 4DN",text:"It opens on the lab’s own store, RSG. Press 4DN to switch to the 4D Nucleome project’s.",target:()=>i(`.store-drawer .store-tile[data-store="${A}"]`),done:()=>e.store()===A,needs:{holds:()=>e.store()!==null,back:"stores"}},{id:"search",chapter:"The 4DN store",title:"Find an experiment",text:["Type ",{name:m,copy:!0}," in the search box: Hi-C on K562 cells, about 190 million contacts."],action:"type",target:I,focus:!0,done:()=>I()?.value.toUpperCase().includes(m)===!0&&he()!==null,mistake:()=>{const t=(I()?.value??"").trim().toUpperCase();return t===""||m.startsWith(t)||t.includes(m)?null:t},needs:{holds:()=>e.store()===A,back:"store"},assist:{label:"type it for me",title:`Put ${m} in the search box`,run:()=>{const t=I();t!==null&&(t.value=m,t.dispatchEvent(new Event("input",{bubbles:!0})))}}},{id:"open-set",chapter:"The 4DN store",title:"Open it with its tracks",text:"One press opens the contact map with the tracks 4DN computed from it — compartments, insulation and boundaries — without downloading its 1.9 GB.",target:()=>he()?.querySelector(".portal-session")??null,done:n,needs:{holds:()=>e.store()===A||n(),back:"store"},missing:`Not on screen — type ${m} in the store’s search box again.`},{id:"look-general",chapter:"The map",title:"The General panel",text:"What the file is: its bin size and contacts under File, its sequences under Sequences, and anything else it carries under Metadata.",target:()=>ie("general")},{id:"resolution-250",chapter:"The map",title:"Pick 250 kb",text:"A map is stored at several resolutions, the size of one bin. 250 kb is coarse enough to show a whole chromosome’s compartments.",action:"choose",target:le,done:()=>e.binsize()===25e4,needs:{holds:n,back:"open-set"},missing:"Waiting for the map to open."},{id:"chromosome",chapter:"The map",title:`Open ${r}`,text:`Press ${r} in the table to open its map.`,prepare:()=>{F=!1},target:()=>(ve(),fe(r)),done:c,needs:{holds:n,back:"open-set"},missing:`Not on screen — scroll the table to ${r}.`},{id:"look-map",chapter:"The map",title:"The contact map",text:`Each pixel is how often two stretches of ${r} touch; 4DN’s tracks are drawn under it. Scroll to zoom into the picture at this resolution, drag to move around, and double-click to fit it back.`,target:b},{id:"look-aesthetics",chapter:"The map",title:"The Aesthetics panel",text:"How the picture is drawn: the Map card sets its score, smoothing and colours, the Tracks card its tracks, and Export saves it as a figure.",target:()=>ie("aesthetics")},ee("score-correlation","Compartments",xe,"Draw it as a correlation","In the Map card, set score to correlation."),{id:"look-correlation",chapter:"Compartments",title:"The plaid",text:"Red where two stretches share a compartment, blue where they do not. Compartments sums this pattern up as one track, E1, positive in one compartment and negative in the other.",target:b},...te("Compartments","compartments","Compartments",{choose:"It splits a chromosome into A and B compartments from the map’s plaid.",none:"It runs on every sequence of the file to begin with. Press none…",tick:`…then tick ${r}, the chromosome on screen.`,run:"Press run. It takes a few seconds."},{tour:t=>[U("tasks-2d","2D tasks","These read the contact map: its decay with distance, insulation, compartments, loops and more.",t),U("tasks-3d","3D tasks","These build a model of the chromosome’s shape from the map, or set one against it.",t),U("tasks-1d","1D tasks","These read tracks rather than the map: peaks, profiles over features, correlations between tracks.",t)],setup:Le,after:t=>[{id:"look-saddle",chapter:"Compartments",title:"The saddle",text:"Bins sorted by E1, low to high: bright corners on the diagonal mean like touches like, A with A and B with B. The numbers under it say how much.",target:()=>de("Saddle"),needs:{holds:t,back:"compartments"}}]}),{id:"look-compartments",chapter:"Compartments",title:"Your compartments",text:"E1 and its A and B calls are drawn left of the map. Compare them with 4DN’s compartment track under it.",target:b},ee("score-balanced","Zooming in",Ae,"Back to contacts","Domains are about how often stretches touch, not how alike they are: set score back to balanced."),{id:"zoom",chapter:"Zooming in",title:"Zoom along the diagonal",text:`Hold ${X}, then drag across the lit square, from one corner to the other: that stretch opens.`,action:"drag",target:Q(v),done:()=>{const t=e.view();return c()&&t?.region?.includes(":")===!0&&t.region2===void 0},needs:{holds:c,back:"chromosome"},assist:{label:"zoom for me",title:`Open ${r}:${s(v.start)}-${s(v.end)}`,run:()=>be(`${r}:${s(v.start)}-${s(v.end)}`)}},{id:"resolution-5",chapter:"Zooming in",title:"Switch to 5 kb",text:"At 5 kb the domains along the diagonal come into view, and the loops at their corners.",action:"choose",target:le,done:()=>e.binsize()===$,needs:{holds:n,back:"open-set"}},{id:"zoom-domains",chapter:"Zooming in",title:"Closer, on a few domains",text:`Once more: hold ${X} and drag across the lit square.`,action:"drag",target:Q(S),done:()=>{const t=Ue(e.view());return t!==null&&t.contig===r&&t.end-t.start<=$e&&e.binsize()===$},needs:{holds:()=>c()&&e.binsize()===$,back:"resolution-5"},missing:"Not in view — press zoom for me, or go back a step.",assist:{label:"zoom for me",title:`Open ${r}:${s(S.start)}-${s(S.end)}`,run:()=>be(`${r}:${s(S.start)}-${s(S.end)}`)}},{id:"look-domains",chapter:"Zooming in",title:"Domains",text:"Each dark square along the diagonal is a domain, or TAD: a stretch that touches itself more than its neighbours. Most sit inside bigger ones — the big square from 45.7 to 48.3 Mb holds two.",target:b},{id:"oe-on",chapter:"Zooming in",title:"Turn on O/E",text:"O/E divides each pixel by what its distance predicts, so what is left is structure rather than distance.",target:P(Ce),done:()=>e.view()?.oe===!0,needs:{holds:n,back:"open-set"}},{id:"smooth",chapter:"Zooming in",title:"Smooth it",text:"At 5 kb most pixels hold a handful of contacts. Set smooth to 3 × 3, which averages each pixel with the eight around it.",action:"choose",target:P(()=>ce("smooth")),done:()=>e.view()?.smooth===Oe,needs:{holds:n,back:"open-set"}},{id:"look-oe",chapter:"Zooming in",title:"Domains and compartments",text:"Red is more contact than the distance predicts, blue less: the domains are red squares, and the checkerboard behind them is A and B again.",target:b},...te("Insulation","insulation","Diamond insulation",{choose:"It scores how much contact crosses each bin; its dips are the boundaries between domains.",none:"Again, press none…",tick:`…then tick ${r}.`,run:"Press run. Four windows over a whole chromosome at 5 kb take a little while."},{form:t=>[{id:"insulation-scales",chapter:"Insulation",title:"Four scales",text:`Set scales to ${q}. The window is 10 bins, 50 kb here, and each scale doubles it: 50, 100, 200 and 400 kb, one insulation track each.`,action:"type",target:()=>_("scales"),focus:!0,done:()=>Number(_("scales")?.value)===q,needs:{holds:t,back:"insulation"},assist:{label:"set it for me",title:`Set scales to ${q}`,run:()=>Me(_("scales"),String(q))}}],ran:t=>t.scales===q&&e.binsize()===$}),{id:"look-insulation",chapter:"Insulation",title:"Your insulation, at four scales",text:"Four scores are drawn left of the map, one per window, with the boundaries and the domains between them. The scales are the TAD hierarchy: the 50 kb window dips at the edge of every small domain, the 400 kb one only at the borders of the big ones. A border every window finds is high in the hierarchy; one only the narrow windows see is a subTAD’s, nested inside a bigger domain.",target:b},{id:"annotations",chapter:"Marks",title:"Open the Annotations panel",text:"Every track has a row here, the ones you computed among them, and so do the marks you draw.",target:()=>y("annotations"),done:()=>e.panelOpen("annotations"),needs:{holds:n,back:"open-set"}},{id:"mark-loop",chapter:"Marks",title:"Mark the loop",text:["The big domain has a dot at its corner: a loop, its two borders held together. In Manual annotations, under Arrowheads, type ",{name:`${r}:${s(d.rows)}`,copy:!0}," in rows and ",{name:`${r}:${s(d.cols)}`,copy:!0}," in columns, then press add."],target:()=>D("Arrowheads")??H(),done:ye,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"Not on screen — scroll the Annotations panel to Manual annotations.",assist:{label:"mark it for me",title:`An arrowhead at ${r}:${s(d.rows)} × ${r}:${s(d.cols)}`,run:()=>{const t=D("Arrowheads"),[o,a]=[...t?.querySelectorAll("input")??[]];o===void 0||a===void 0||(o.value=`${r}:${s(d.rows)}`,a.value=`${r}:${s(d.cols)}`,ue(t)?.click())}}},{id:"mark-border",chapter:"Marks",title:"Mark the weak border",text:["Inside that domain one border is weak: the 400 kb window barely dips there, 4DN calls it Weak, and it splits the domain into two subTADs. Under Lines, keep vertical, type ",{name:`${r}:${s(E)}`,copy:!0}," and press add."],target:()=>D("Lines")??H(),done:we,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"Not on screen — scroll the Annotations panel to Manual annotations.",assist:{label:"mark it for me",title:`A vertical line at ${r}:${s(E)}`,run:()=>{const t=D("Lines"),o=t?.querySelector("select"),a=t?.querySelector("input");o==null||a===null||a===void 0||(o.value="vertical",a.value=`${r}:${s(E)}`,ue(t)?.click())}}},{id:"look-marks",chapter:"Marks",title:"A loop and a subTAD border",text:"The arrowhead points at the loop closing the big domain, and the line marks the border inside it. Find the same place on your four insulation tracks, left of the map: a deep dip at 50 kb, barely one at 400 kb — that is the hierarchy, read off one bin.",target:b},{id:"insulation-row",chapter:"Tracks",title:"Unfold your insulation’s settings",text:"A computed track is a track like any other: press the arrow on your first insulation row.",target:()=>R()?.querySelector(".ann-more")??null,done:K,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"No insulation row — run Diamond insulation again."},{id:"insulation-bigwig",chapter:"Tracks",title:"Save it as a bigWig",text:"Press bigWig to save the score as a file IGV, deepTools and pyBigWig open — written here, in this page, with nothing uploaded.",target:()=>{for(const t of R()?.querySelectorAll(".ann-exports button")??[])if(l(t)==="bigWig")return t;return null},done:()=>Y(".bw"),needs:{holds:()=>e.panelOpen("annotations")&&K(),back:"insulation-row"}},{id:"domains",chapter:"Tracks",title:"Unfold the domains’ settings",text:"Press the arrow on the Insulation domains row.",target:()=>T()?.querySelector(".ann-more")??null,done:x,needs:{holds:()=>e.panelOpen("annotations"),back:"annotations"},missing:"No Insulation domains row — run Diamond insulation with its domains on."},{id:"domains-display",chapter:"Tracks",title:"Draw the domains as a 1D track",text:"Domains are outlined on the map. Choose 1D track to draw them as a lane beside it instead.",action:"choose",target:()=>T()?.querySelector(`select[data-display="${O}"]`)??null,done:L,needs:{holds:x,back:"domains"}},{id:"domains-bottom",chapter:"Tracks",title:"Put it under the map",text:"Press the bottom edge to draw the lane under the map…",target:()=>j("bottom"),done:()=>V()?.bottom===!0,needs:{holds:()=>x()&&L(),back:"domains-display"}},{id:"domains-left",chapter:"Tracks",title:"Take it off the side",text:"…and the left edge to take it off the left.",target:()=>j("left"),done:()=>{const t=V();return t!==null&&t.bottom&&!t.left},needs:{holds:()=>x()&&L(),back:"domains-display"}},{id:"export-format",chapter:"The figure",title:"Choose PDF",text:"The Export card at the top of the Aesthetics panel saves what is on screen — the map, your marks and every track — as a figure. Choose PDF (vector): lines and text stay sharp at any size.",action:"choose",target:()=>N()?.querySelector("select.select-format")??y("aesthetics"),done:()=>N()?.querySelector("select.select-format")?.value==="pdf",needs:{holds:n,back:"open-set"}},{id:"export-save",chapter:"The figure",title:"Save the figure",text:"Press the download button beside it.",target:()=>N()?.querySelector(".export-acts button")??y("aesthetics"),done:()=>Y(".pdf"),needs:{holds:()=>N()?.querySelector("select.select-format")?.value==="pdf",back:"export-format"}},J("analysis-trackcorr","Track correlation"),{id:"trackcorr",chapter:"Track correlation",title:"Choose Track correlation",text:"It measures how closely every pair of loaded tracks agrees.",target:()=>se("Track correlation"),done:()=>e.task()==="trackcorr",needs:{holds:()=>e.panelOpen("analysis"),back:"analysis-trackcorr"},missing:"Not in the list — empty the box over it if a word is typed there."},{id:"tick-tracks",chapter:"Track correlation",title:"Tick every track",text:[{name:ae}," and ",{name:re},", 4DN’s insulation and E1, your E1, and your insulation at all four scales."],target:()=>B().map(t=>t?.closest(".param-field")??null).find(t=>t!==null)??null,done:()=>B().every(t=>t?.querySelector("input")?.checked===!0),needs:{holds:()=>e.task()==="trackcorr",back:"trackcorr"},missing:"Not in the list — a track did not load, or was closed.",assist:{label:"tick them for me",title:"Tick every track in the list",run:()=>{for(const t of B()){const o=t?.querySelector("input");o!=null&&!o.checked&&o.click()}}}},{id:"trackcorr-run",chapter:"Track correlation",title:"Run it",text:`Every pair is compared over the windows all of them have values in, which is ${r}.`,target:me,done:()=>{const t=ne();return t.some(o=>o===void 0)?!1:e.runs("trackcorr").some(o=>{const a=new Set(z(o.provenance.params.tracks)??[]);return t.every(u=>u!==void 0&&a.has(u.id))})},needs:{holds:()=>e.task()==="trackcorr"||e.running("trackcorr"),back:"trackcorr"}},{id:"look-trackcorr",chapter:"Track correlation",title:"Yours against 4DN’s",text:"Each square compares two tracks: red where they rise and fall together, blue where one rises as the other falls. Find yours against 4DN’s — an unphased E1 can match upside down, at −1 — and your four scales against each other: neighbouring windows agree most, the hierarchy again.",target:()=>de("Track correlation")},{id:"console",chapter:"The console",title:"Every step is a command",text:"Open the console: each file you opened and each run you made is a line you can paste into a terminal to do it again.",target:()=>i('.head-actions button[aria-label="console"]')??i('button[aria-label="console"]'),done:()=>e.consoleOpen()},{id:"finish",chapter:"Done",title:"That’s the tour",text:`You opened a map from 4DN, called compartments and domains at four scales on ${r}, marked a loop and a subTAD border, saved a track and a figure, and set it all against 4DN’s own. The tutorial is on the landing page and in About whenever you want it again.`,hero:!0}]}export{r as TUTORIAL_SEQUENCE,m as TUTORIAL_SET,A as TUTORIAL_STORE,_e as tutorialSteps};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{e as p,I as Ls,J as z,K as Is,N as Te,O as Rt,P as ve,Q as Kt,R as _t,V as xn,T as Os,U as Fs,W as $t,X as st,L as J,Y as Ps,Z as Bs,_ as qs,$ as Ce,a0 as zs,a1 as Sn,a2 as Rs,a3 as _s,a4 as $n,a5 as ct,a6 as Ds,a7 as qt,a8 as Vs,a9 as Ws,aa as Gs,ab as Hs,ac as Ks,ad as Ys,ae as Us,af as Zs,ag as Mn,b as I,ah as _,ai as et,aj as Xs,ak as js,al as Qs,am as En,an as Tn,ao as Cn,ap as Js,aq as ti,ar as ei,as as ni,at as si,au as Ae,av as ii,aw as oi,ax as ri,i as ie,ay as An,az as Nn,aA as Ln,aB as In,aC as ai,aD as At,aE as li,aF as ci,aG as ui,aH as Ne,aI as di,aJ as hi,aK as fi,aL as mi,aM as Le,aN as pi,aO as gi,aP as bi,aQ as yi,aR as Ie,aS as vi,aT as oe,aU as wi,aV as j,aW as it,aX as On,aY as re,aZ as ki,a_ as xi,a$ as Si,b0 as Zt,b1 as $i,b2 as gt,b3 as Oe,C as Fe,b4 as Fn,b5 as Mi,b6 as Ei,b7 as Ti,b8 as Pe,b9 as Ci,ba as Ai,bb as Ni,bc as wt,bd as Li,be as Ii,bf as Oi,bg as Fi,bh as Pi,bi as Bi,bj as qi,bk as Be,bl as zi,bm as Ri,bn as Pn,bo as qe,bp as _i}from"./index-BZqg8J4S.js";function Bn(n,t){if(t===void 0)return"—";if(n.kind!=="number")return String(t);const e=typeof t=="number"?t:Number(t);return Number.isFinite(e)?n.coordinate==="start"?Ls(e):n.coordinate==="end"?z.pos(e):n.digits===void 0?z.int(e):n.scientific===!0&&e!==0&&Math.abs(e)<10**-n.digits?e.toExponential(2):e.toFixed(n.digits):"—"}function Di(n,t){const e=t.filter.trim().toLowerCase();let s=n.rows;e!==""&&(s=s.filter(l=>n.columns.some(c=>Bn(c,l[c.key]).toLowerCase().includes(e))));const i=t.sortKey;if(i===null)return s;const o=n.columns.find(l=>l.key===i);if(o===void 0)return s;const r=t.sortDown?-1:1,a=l=>l===void 0||o.kind==="number"&&!Number.isFinite(Number(l));return[...s].sort((l,c)=>{const u=l[i],d=c[i];return a(u)!==a(d)?a(u)?1:-1:a(u)?0:o.kind==="number"?r*(Number(u)-Number(d)):r*String(u).localeCompare(String(d))})}function Vi(n,t){const e=t.columns;if(e===null)return n.columns;const s=n.columns.filter(i=>e.includes(i.key));return s.length===0?n.columns:s}function Wi(n,t,e){const s=Vi(n,t),i=Di(n,t),o=p("thead",{class:"thead"},p("tr",{},...s.map(u=>{const d=t.sortKey===u.key,f=p("th",{class:`td figure-th${d?" is-sorted":""}${u.kind==="number"?" num":""}`,text:`${u.label}${d?t.sortDown?" ↓":" ↑":""}`,title:u.hint??`Sort by ${u.label}`,attrs:{role:"button",tabindex:"0"}}),m=()=>e(u.key,d?!t.sortDown:!1);return f.addEventListener("click",m),f.addEventListener("keydown",h=>{h.key!=="Enter"&&h.key!==" "||(h.preventDefault(),m())}),f}))),r=p("tbody",{});for(const u of i)r.appendChild(p("tr",{style:{borderTop:"1px solid var(--border)"}},...s.map(d=>p("td",{class:d.kind==="number"?"td num":"td",text:Bn(d,u[d.key])}))));const a=p("table",{style:{borderCollapse:"collapse",width:"100%",fontVariantNumeric:"tabular-nums"}},o,r),l=n.rows.length===0?"This run produced no rows.":`No row matches “${t.filter}”. ${n.rows.length} were produced.`;return{el:p("div",{class:"analysis-figure-scroll"},i.length===0?p("div",{class:"tempty",text:l}):a),destroy(){}}}function Gi(n,t){const e=n[t];return Array.isArray(e)?e.filter(s=>typeof s=="string"):typeof e=="string"&&e!==""?[e]:[]}function Hi(n,t){let e=null;for(const s of n){if(s.kind!=="region")continue;const i=t[s.key];if(typeof i!="string"||i.trim()==="")continue;const o=s.many===!0?Is(i).map(Te).join(", "):Te(i);o!==i&&(e??={...t},e[s.key]=o)}return e??t}function Ki(n,t){const e=n[t];return typeof e=="string"&&e!==""?e:null}function ze(){const n=new Error("cancelled");return n.name="AbortError",n}function Yi(n){return n.rows[1]<=n.rows[0]&&n.cols[1]<=n.cols[0]}const Ui="chromosomix",Zi="count";function qn(n){const t=[],e=[Ui,n.task.id],{framing:s,params:i}=n.provenance,o=Yi(s);o||(e.push(K(s.uri)),so(s.uri)&&s.binsize>0&&e.push("--bin-size",String(s.binsize)));const r=n.task.params.some(b=>b.key==="window");if(!o&&!r){const b=eo(s.rows,s.cols,n.context);b.locus!==null&&e.push("--window",K(b.locus)),b.note!==null&&t.push(b.note)}const a=n.task.params.find(b=>b.key==="balance"),l=a!==void 0&&Rt(a),c=l&&typeof i.balance=="boolean"?i.balance:s.balance;!o&&!c&&e.push("--no-balance"),!o&&l&&c!==s.balance&&t.push(`The map was drawn ${s.balance?"balanced":"unbalanced"} while the task read it ${c?"balanced":"unbalanced"}, and --no-balance sets both together. This follows the task, so the numbers match; only the framing line the run records will differ.`);const u=(s.circular??[]).filter(b=>b!=="");u.length>0&&e.push("--circular",K(u.join(",")));const d=Object.entries(s.origins??{}).filter(([b,S])=>b!==""&&Number.isFinite(S));if(d.length>0&&e.push("--origin",K(d.map(([b,S])=>`${b}:${S+1}`).join(","))),!o){s.value!==""&&s.value!==Zi&&e.push("--value",K(s.value)),s.contacts!==void 0&&e.push("--contacts",String(s.contacts)),s.coarsen!==void 0&&e.push("--coarsen",String(s.coarsen)),s.edit!==void 0&&t.push("The map was drawn through an edit of its reference, which the command line cannot yet apply: this line measures the file as it is.");const b=n.context?.selectedCells??[];b.length>0?e.push("--cell",K(b.join(","))):n.context!==null&&(n.context.cells??0)>0&&(n.context.activeCells??n.context.cells??0)<(n.context.cells??0)&&t.push("The map was summed from a subset of the file’s cells, and the record does not name them. Add --cell <name> for each.")}if(n.task.needsPeers===!0){const b=n.context?.peers??[];for(const S of b)e.push("--against",K(S.uri));b.length===0&&t.push(`${n.task.id} compares this map with the others on screen, and the record does not name them. Add --against <file> for each.`)}const f=n.context?.entries??[],m=[],h=new Set,y=Xi(n.task);for(const b of n.task.params)if(zn(b))for(const S of Rn(i[b.key])){const A=_n(f,S);if(A===null){t.push(`--${b.key} named something with no file behind it${Ji(f,S)} — a set this app computed, most likely. Point it at a file, or export that row first.`);continue}const v=b.kind==="sequence"?"--sequence":b.kind==="pairSet"?"--pairs":b.kind==="track"?`--${b.key}`:"--features";(v===`--${b.key}`||b.kind==="sequence"&&b.key===y)&&h.add(b.key);const k=`${v} ${K(A)}`;m.includes(k)||m.push(k)}for(const b of m)e.push(...b.split(" "));for(const b of n.task.params){if(b.key==="balance"&&Rt(b)||h.has(b.key)||b.retired===!0&&ji(b,i[b.key]))continue;const S=Qi(b,i[b.key],f);S!==null&&e.push(...S)}const g=e.join(" ");return{text:[...t.map(b=>`# ${b}`),g].join(`
|
|
2
|
+
`)}}function Xi(n){const t=n.params.filter(e=>e.kind==="sequence"&&e.multiple!==!0);return t.some(e=>e.key==="sequence")?"sequence":n.upstreamParams===void 0||(n.requires??[]).length===0?null:t.length===1?t[0].key:null}function ji(n,t){const e=Kt([n])[n.key];return Array.isArray(e)||Array.isArray(t)?Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((s,i)=>s===t[i]):t===void 0||t===e}function zn(n){return n.kind==="featureSet"||n.kind==="pairSet"||n.kind==="track"||n.kind==="sequence"}function Rn(n){return typeof n=="string"?n===""?[]:[n]:Array.isArray(n)?n.filter(t=>typeof t=="string"):[]}function Qi(n,t,e){if(t==null)return null;if(zn(n)){const s=Rn(t).map(i=>_n(e,i)).filter(i=>i!==null);return s.length===0?null:[`--${n.key}`,K(s.join(","))]}if(typeof t=="boolean")return[t?`--${n.key}`:`--${n.key}=false`];if(Array.isArray(t)){const s=t.filter(i=>i!=null).map(String);return s.length===0?null:[`--${n.key}`,K(s.join(","))]}return typeof t=="number"?Number.isFinite(t)?[`--${n.key}`,String(t)]:null:t===""?null:[`--${n.key}`,K(String(t))]}function _n(n,t){const e=n.find(i=>i.id===t);if(e===void 0)return null;const s=e.source;return s.kind==="local"||s.kind==="detached"?s.name:s.kind==="remote"?to(s.url):null}function Ji(n,t){const e=n.find(s=>s.id===t);return e===void 0?"":` (“${e.label}”)`}function to(n){const e=n.split(/[?#]/)[0].split("/").filter(s=>s!=="").pop();return e===void 0||e===""?n:e}function eo(n,t,e){if(e===null)return{locus:null,note:null};const s=e.nBins;if(n[0]===0&&n[1]>=s&&t[0]===0&&t[1]>=s||s===0)return{locus:null,note:null};if(n[0]!==t[0]||n[1]!==t[1])return{locus:null,note:"The view was an off-diagonal block — two different windows on the two axes — and --window names one. This runs over the whole file."};const o=e.genomes?.find(c=>c.extent[0]===n[0]&&c.extent[1]===n[1]);if(o!==void 0)return{locus:o.name,note:null};const r=no(e.contigs,n);if(r===null)return{locus:null,note:"The view covered several sequences without covering the file, and --window names one locus. This runs over the whole file."};if(n[0]===r.startBin&&n[1]>=r.startBin+r.bins)return{locus:r.name,note:null};const a=(n[0]-r.startBin)*e.binsize,l=Math.min(r.length,(n[1]-r.startBin)*e.binsize);return{locus:ve({contig:r.name,start:a,end:l}),note:null}}function no(n,t){for(const e of n){if(e.bins===0)continue;const s=e.startBin,i=e.startBin+e.bins;if(t[0]>=s&&t[1]<=i)return e}return null}function K(n){return n===""?"''":/^[A-Za-z0-9_@%+=:,./-]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}function so(n){return/\.pairs(\.b?gz)?$/i.test(n.split("::")[0].split(/[?#]/)[0])}const Dn=6,Vn=100;function R(n){if(!Number.isFinite(n))return"";if(Number.isInteger(n))return Math.abs(n)<1e21?String(n):n.toFixed(0);const t=Math.floor(Math.log10(Math.abs(n))),e=Math.min(Vn,Math.max(0,Dn-1-t));return we(n.toFixed(e))}function Wn(n,t,e=!1){return Number.isFinite(n)?t===void 0?R(Math.round(n)):e&&n!==0&&Math.abs(n)<10**-t?io(n):we(n.toFixed(Math.min(Vn,Math.max(0,t)))):""}function io(n){const[t,e]=n.toExponential(Dn-1).split("e");return`${we(t)}e${e}`}function we(n){if(n.indexOf(".")<0)return n;let t=n.length;for(;n.charCodeAt(t-1)===48;)t--;return t===n.length?n:(n.charCodeAt(t-1)===46&&t--,n.slice(0,t))}function N(n){return n.replace(/[\t\r\n]+/g," ")}function D(n){return n.join(" ")}const oo=4096;class Gn{block=[];push(t){return this.block.push(t),this.block.length===oo?this.flush():void 0}flush(){if(this.block.length===0)return;const t=`${this.block.join(`
|
|
3
|
+
`)}
|
|
4
|
+
`;return this.block.length=0,t}}function*tt(n){for(const t of n)yield`${t}
|
|
5
|
+
`}function ro(n){return n===null?"":typeof n=="number"?R(n):typeof n=="boolean"?n?"true":"false":Array.isArray(n)?n.join(","):String(n)}function ft(n){const{framing:t,params:e}=n,s=[`# chromosomix ${N(n.app)}`,`# created: ${N(n.createdAt)}`,`# file: ${N(t.uri)}`,`# task: ${N(n.task)} v${R(n.taskVersion)}`,`# framing: ${N(t.label)}`];for(const i of Object.keys(e).sort())s.push(`# param ${N(i)}: ${N(ro(e[i]))}`);return s}function*ao(n){const[t]=n.extent;yield*tt([`# output: ${N(n.label)}${n.unit===""?"":` (${N(n.unit)})`}`,`# binsize: ${R(n.binsize)}`,D(["bin","start","end","value"])]);const{binsize:e,values:s}=n,i=new Gn;for(let r=0;r<s.length;r++){const a=t+r,l=a*e,c=i.push(`${a} ${l} ${l+e} ${R(s[r])}`);c!==void 0&&(yield c)}const o=i.flush();o!==void 0&&(yield o)}function lo(n){const t=[`# output: ${N(n.label)}`,`# x: ${N(n.xLabel)} y: ${N(n.yLabel)}`],e=[N(n.xLabel)===""?"x":N(n.xLabel)];let s=0,i=new Float64Array(0);for(const r of n.series){const a=N(r.name);e.push(a),r.low!==void 0&&r.high!==void 0&&e.push(`${a}_low`,`${a}_high`),r.y.length>s&&(s=r.y.length,i=r.x),r.n!==void 0&&t.push(`# n ${a}: ${R(r.n)}`)}t.push(D(e));const o=n.xTicks;for(let r=0;r<s;r++){const a=o?.[r],l=[a!==void 0?N(a):r<i.length?R(i[r]):""];for(const c of n.series){const u=r<c.y.length;l.push(u?R(c.y[r]):""),c.low!==void 0&&c.high!==void 0&&l.push(u?R(c.low[r]):"",u?R(c.high[r]):"")}t.push(D(l))}return t}function co(n){const t=[`# output: ${N(n.label)}`,`# x: ${N(n.xLabel)} y: ${N(n.yLabel)}`];for(const r of n.stats??[])t.push(`# ${N(r.label)}: ${Wn(r.value,r.digits??4)}`);const e=(r,a)=>r.length===a&&a>0;for(const[r,a,l]of[["x",n.xTicks,n.ncols],["y",n.yTicks,n.nrows]])a.length===0||e(a,l)||t.push(`# ${r} ticks, evenly spaced across the axis: ${a.map(N).join(", ")}`);const s=(r,a,l)=>e(r,l)?N(r[a]):String(a),i=[N(n.yLabel)];for(let r=0;r<n.ncols;r++)i.push(s(n.xTicks,r,n.ncols));t.push(D(i));for(let r=0;r<n.nrows;r++){const a=[s(n.yTicks,r,n.nrows)];for(let l=0;l<n.ncols;l++)a.push(R(n.values[r*n.ncols+l]));t.push(D(a))}const o=[...(n.margins?.top??[]).map(r=>["top",r]),...(n.margins?.right??[]).map(r=>["right",r])];if(o.length>0){const r=Math.max(...o.map(([,a])=>a.values.length));t.push(""),t.push("# aggregate profiles along the edges: top runs along x, right runs down y"),t.push(D(["edge","track",...Array.from({length:r},(a,l)=>String(l))]));for(const[a,l]of o){const c=[a,N(l.name)];for(const u of l.values)c.push(R(u));t.push(D(c))}}return t}function uo(n){const t=[`# output: ${N(n.label)}`,`# columns: ${n.columns.map(e=>`${N(e.label)}${e.coordinate==="start"?" (0-based)":""}`).join(", ")}`,D(n.columns.map(e=>N(e.key)))];for(const e of n.rows)t.push(D(n.columns.map(s=>{const i=e[s.key];return i==null?"":typeof i=="number"?s.kind==="number"?Wn(i,s.digits,s.scientific===!0):R(i):N(i)})));return t}function ho(n){return n>0?"+":n<0?"-":"."}function fo(n){const t=[`# output: ${N(n.label)}`];if(n.payload.kind==="features"){const s=n.payload.data;t.push(D(["chrom","start","end","name","score","strand","detail"]));for(let i=0;i<s.length;i++)t.push(D([N(s.contigs[s.contig[i]]??""),String(s.start[i]),String(s.end[i]),N(s.name[i]??""),R(s.score[i]),ho(s.strand[i]),N(s.detail[i]??"")]));return t}const e=n.payload.data;t.push(D(["chrom1","start1","end1","chrom2","start2","end2","name","score","detail"]));for(let s=0;s<e.length;s++)t.push(D([N(e.contigs[e.contig1[s]]??""),String(e.start1[s]),String(e.end1[s]),N(e.contigs[e.contig2[s]]??""),String(e.start2[s]),String(e.end2[s]),N(e.name[s]??""),R(e.score[s]),N(e.detail[s]??"")]));return t}function mo(n,t,e,s,i){const o=[...ft(i),`# output: ${N(n)}${t===""?"":` (${N(t)})`}`,D(["chrom","start","end","value"])],r=new Map;for(const a of e){const l=r.get(a.contig);l===void 0?r.set(a.contig,[a]):l.push(a)}for(const a of s){const l=r.get(a.name);if(l===void 0)continue;const c=[];for(const u of l)for(let d=0;d<u.starts.length;d+=1){const f=u.values[d];if(!Number.isFinite(f))continue;const m=Math.max(0,u.starts[d]),h=Math.min(a.length,u.ends[d]);h>m&&c.push([m,h,f])}c.sort((u,d)=>u[0]-d[0]);for(const[u,d,f]of c)o.push(D([N(a.name),String(u),String(d),R(f)]))}return tt(o)}function*ae(n,t){yield*tt(ft(t)),yield*Kn(n)}function*po(n,t){yield*tt(Hn(t)),yield*Kn(n)}function Hn(n){const t=[],e=n[0]?.provenance.app;e!==void 0&&t.push(`# chromosomix ${N(e)}`),t.push(`# maps: ${R(n.length)}`);for(const s of n){t.push(`# map: ${N(s.label)}`);for(const i of ft(s.provenance).slice(1))t.push(`# ${i.slice(2)}`)}return t}function Kn(n){switch(n.kind){case"profile":return ao(n);case"curve":return tt(lo(n));case"matrix":return tt(co(n));case"table":return tt(uo(n));case"intervals":return tt(fo(n))}}function Mt(n,t,e){const s=_t(n),i=t.id===""?"":_t(t.id);return`${[...i===""||i===s?[s]:[s,i],e].join("-")}.tsv`}const go=[xn,Os].filter(n=>n!=="").join(" ");function bo(n,t,e){return{task:n.id,taskVersion:n.version,params:t,framing:e,app:go,createdAt:new Date().toISOString()}}function Re(n){const{task:t,provenance:e,context:s,where:i}=n,o=qn({task:t,provenance:e,context:s}),r=ft(e),a=i===void 0?{}:{where:i},l=o.text.split(`
|
|
6
|
+
`);return{kind:"run",line:l[l.length-1],shell:!0,notes:l.slice(0,-1),detail:r,...a}}function Yn(n,t){return yo(n.params,t.params)&&wo(n.framing,t.framing)}function yo(n,t){const e=Object.keys(n);if(e.length!==Object.keys(t).length)return!1;for(const s of e)if(!(s in t)||!vo(n[s],t[s]))return!1;return!0}function vo(n,t){return Array.isArray(n)||Array.isArray(t)?!Array.isArray(n)||!Array.isArray(t)||n.length!==t.length?!1:n.every((e,s)=>e===t[s]):Object.is(n,t)}function wo(n,t){return n.uri===t.uri&&n.rows[0]===t.rows[0]&&n.rows[1]===t.rows[1]&&n.cols[0]===t.cols[0]&&n.cols[1]===t.cols[1]&&n.binsize===t.binsize&&n.binsPerCell===t.binsPerCell&&n.balance===t.balance&&n.value===t.value&&n.level===t.level&&(n.contacts??null)===(t.contacts??null)&&(n.edit??null)===(t.edit??null)&&(n.coarsen??null)===(t.coarsen??null)&&ko(n.circular??[],t.circular??[])&&xo(n.origins??{},t.origins??{})}function ko(n,t){if(n.length!==t.length)return!1;const e=new Set(n);return t.every(s=>e.has(s))}function xo(n,t){const e=Object.keys(n);return e.length===Object.keys(t).length&&e.every(s=>n[s]===t[s])}const So=100;function pt(n,t){return`${n}\0${t}`}const $o=8;function Xt(n,t){return`${n}\0${t}`}function Mo(n,t,e,s,i,o){const r=t===void 0||t.length===0?n:`${n}\0${t.join("\0")}`,a=e===void 0?r:`${r}\0${e.base}:${e.rungs}`,l=s===void 0?a:`${a}\0contacts:${s.contacts}:${s.seed??""}:${s.alpha??""}`,c=i===void 0?l:`${l}\0edit:${Rs(i)}`;return o===void 0?c:`${c}\0coarsen:${o}`}function _e(n){return Sn(n.label)}function Eo(n){return{line:n.line,notes:n.notes??[],detail:n.detail??[]}}class To{host;makeClient;client=null;mounted=null;states=new Map;results=new Map;history=new Map;resultTargets=new Map;queue=[];current=null;held=new Map;listeners=new Set;lastNotifiedAt=0;trailing=null;destroyed=!1;constructor(t,e=()=>new Fs){this.host=t,this.makeClient=e}stateOf(t){return this.states.get(t)??{status:"idle"}}holdFile(t,e,s){const i=Xt(t,e);s===null?this.held.delete(i):this.held.set(i,s)}heldFile(t,e){return this.held.get(Xt(t,e))}resultOf(t,e){const s=e??this.homeOf(t);return this.results.get(pt(s,t))??null}homeOf(t){const e=this.host.task?.(t)??$t(t);return e!==void 0&&!st(e)?J:this.host.targetMap?.()??J}runsOf(t,e){const s=e??this.homeOf(t),i=pt(s,t),o=this.results.get(i),r=this.history.get(i)??[];return o===void 0?[...r]:[o,...r]}resultsFor(t){const e=this.host.allTargets?.()??[],s=new Set,i=[];for(const o of e){const r=this.results.get(pt(o.map,t));r!==void 0&&(s.add(o.map),i.push({target:o,result:r}))}for(const[o,r]of this.results){const a=this.resultTargets.get(o);a===void 0||s.has(a.map)||o===pt(a.map,t)&&i.push({target:a,result:r})}return i}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}get busy(){return this.current!==null||this.queue.length>0}run(t,e){this.queueOne(t,e,null)}runAll(t,e,s){if(!st(t)){this.queueOne(t,e,null);return}if(s.length!==0){if(s.length===1){this.queueOne(t,e,null,s[0]);return}this.cancel(t.id),s.forEach((i,o)=>{this.queueOne(t,e,{at:o,of:s.length},i)})}}queueOne(t,e,s,i){if(this.destroyed)return;const o=this.host.context(t);if(o===null){this.refuse(t,s,"nothing is open");return}const r=t.mapless===!0?De(o,"sequences"):o.framing??(t.venue==="annotations"?De(o):null);if(r===null){this.refuse(t,s,"this view has no contact map to run against");return}const a=st(t)?i??this.hostTarget(r,t):{...this.hostTarget(r,t),map:J};if(s===null){if(this.current?.task.id===t.id&&this.current.target.map===a.map)return;const l=this.queue.find(c=>c.task.id===t.id&&c.target.map===a.map);if(l!==void 0){l.params=e,l.framing=r;return}}this.queue.push({task:t,params:e,framing:r,target:a,batch:s,cancelled:!1,running:null}),this.setState(t.id,{status:"queued"}),this.pump()}targets(){return this.host.allTargets?.()??[]}async readyTargets(){return await this.host.allTargetsReady?.()??this.targets()}targetCount(){return this.host.targetCount?.()??this.targets().length}target(){const t=this.host.targetMap?.();return t===void 0?null:this.targets().find(e=>e.map===t)??null}hostTarget(t,e){const s=this.host.source(e);return{map:this.host.targetMap?.()??J,uri:s?.uri??t.uri,...s===null?{}:{source:s.source},...s?.cells===void 0?{}:{cells:s.cells},...s?.binning===void 0?{}:{binning:s.binning},...s?.orientation===void 0?{}:{orientation:s.orientation},...s?.pairsStats===void 0?{}:{pairsStats:s.pairsStats},...s?.resample===void 0?{}:{resample:s.resample},...s?.edit===void 0?{}:{edit:s.edit},label:s?.label??t.uri}}cancel(t){let e=0;for(let i=this.queue.length-1;i>=0;i--)this.queue[i].task.id===t&&(this.queue.splice(i,1),e++);const s=this.current;if(s===null||s.task.id!==t){e>0&&this.setState(t,{status:"cancelled"});return}s.cancelled=!0,s.running?.handle.cancel()}destroy(){this.destroyed=!0;for(const t of this.queue)this.setState(t.task.id,{status:"cancelled"});this.queue.length=0,this.current!==null&&(this.current.cancelled=!0,this.setState(this.current.task.id,{status:"cancelled"})),this.trailing!==null&&(clearTimeout(this.trailing),this.trailing=null),this.client?.terminate(),this.client=null,this.mounted=null,this.listeners.clear()}pump(){if(this.current!==null||this.destroyed)return;const t=this.queue.shift();t!==void 0&&(this.current=t,this.execute(t).finally(()=>{this.current=null,this.pump()}))}batchOf(t){return t.batch===null?{}:{batch:{at:t.batch.at,of:t.batch.of,label:t.target.label}}}async execute(t){const e=performance.now();let s=null;const i=this.recordStart(t);let o=null;this.setState(t.task.id,{status:"running",done:0,total:0,note:"starting",startedAt:e,...this.batchOf(t)});try{const r=this.plan(t.task,t.params),a=this.ensureClient();r.some(c=>c.task.venue!=="annotations")&&await this.mount(t,a,e);const l={};for(let c=0;c<r.length;c++){if(s=r[c],t.cancelled)throw ze();const u=s.task.id===t.task.id,d=this.results.get(pt(t.target.map,s.task.id));if(!u&&d!==void 0&&Yn(d.provenance,{params:s.params,framing:t.framing})){l[s.task.id]=d;continue}const f=await this.runStep(t,a,s,r,c,l,e);if(t.cancelled)throw ze();const m=pt(t.target.map,s.task.id),h=this.results.get(m);if(h!==void 0&&h!==f){const y=this.history.get(m)??[];y.unshift(h),this.history.set(m,y.slice(0,$o))}this.results.set(m,f),this.resultTargets.set(m,t.target),u?(this.setState(s.task.id,{status:"done",result:f,ms:performance.now()-e}),this.host.finished(t.task,f,t.target),o={status:"ok",ms:performance.now()-e,...Eo(Re({task:t.task,provenance:this.recordable(t,f.provenance),context:this.host.context(t.task),where:_e(t.target)}))}):(l[s.task.id]=f,this.setState(s.task.id,{status:"done",result:f,ms:f.ms}))}}catch(r){const a=t.cancelled||Ps(r),l=a?{status:"cancelled"}:{status:"failed",message:r instanceof Error?r.message:String(r)};s!==null&&s.task.id!==t.task.id&&this.setState(s.task.id,l),this.setState(t.task.id,l),o=a?{status:"cancelled"}:{status:"failed",error:r instanceof Error?r.message:String(r)}}finally{if(t.running=null,Bs(i,o??{status:"cancelled"}),$t(t.task.id)!==void 0){const r=o?.status??"cancelled";qs({name:"task",task:t.task.id,outcome:r==="ok"?"done":r==="failed"?"failed":"cancelled",ms:performance.now()-e})}}}refuse(t,e,s){this.setState(t.id,{status:"failed",message:s}),!(e!==null&&e.at>0)&&Ce({kind:"run",line:`ran ${t.title}`,status:"failed",error:s})}recordStart(t){const e=Re({task:t.task,provenance:this.recordable(t,bo(t.task,t.params,t.framing)),context:this.host.context(t.task),where:_e(t.target)});return Ce({...e,status:"running"})}recordable(t,e){const s=t.target.uri;return s===""||s===e.framing.uri?e:{...e,framing:{...e.framing,uri:s}}}async mount(t,e,s){const i=t.target;if(i.source===void 0)throw new Error(`${t.task.title} reads a contact map, and this session is browsing a genome without one.`);const o=t.framing.coarsen,r=Mo(i.uri,i.cells,i.binning,i.resample,i.edit,o);this.mounted!==r&&(this.setState(t.task.id,{status:"running",done:0,total:0,note:"opening the file",startedAt:s,...this.batchOf(t)}),this.mounted=null,await e.request({kind:"open",uri:i.uri,source:i.source,...i.cells===void 0?{}:{cells:i.cells},...i.binning===void 0?{}:{binning:i.binning},...i.resample===void 0?{}:{resample:i.resample},...i.edit===void 0?{}:{edit:i.edit},...o===void 0?{}:{coarsen:o}}),this.mounted=r)}async runStep(t,e,s,i,o,r,a){const l=m=>{const h=m===void 0||m===""?"":m;if(i.length===1)return h===""?s.task.title:h;const y=`${s.task.title} (${o+1}/${i.length})`;return h===""?y:`${y} — ${h}`};this.setState(t.task.id,{status:"running",done:0,total:0,note:l(),startedAt:a,...this.batchOf(t)});const c=(m,h,y)=>{this.setState(t.task.id,{status:"running",done:m,total:h,note:l(y),startedAt:a,...this.batchOf(t)},!0)},u={kind:"run",task:s.task.id,params:Hi(s.task.params,s.params),framing:t.framing,inputs:await this.inputsFor(s,t,r)};let d;if(s.task.venue==="annotations"){const m=this.host.annotations?.();if(m==null)throw new Error(`${s.task.title} runs against the loaded tracks, and this session has no annotations worker.`);const h=m.cancellable(u,c);t.running={id:s.task.id,handle:h},d=await h.promise,t.running=null}else{const m=e.cancellable(u,c);t.running={id:s.task.id,handle:m},d=await m.promise,t.running=null}const f=t.framing.normalise===null?d.notes:[...d.notes,`The map is drawn with ${t.framing.normalise.toUpperCase()} normalisation, which is computed from the block after it is read and cannot be asked of the file. These numbers are the underlying counts.`];return{...d,notes:f,provenance:{...d.provenance,params:s.params,taskVersion:s.task.version}}}ensureClient(){return this.client??=this.makeClient(),this.client}plan(t,e){const s=[],i=new Set,o=new Set,r=(a,l)=>{if(!i.has(a.id)){if(o.has(a.id))throw new Error(`the analysis task ${a.id} requires itself`);o.add(a.id);for(const c of a.requires??[]){const u=this.host.task?.(c)??$t(c);if(u===void 0)throw new Error(`${a.id} requires the task ${c}, which this session does not offer`);const d=zs(a,c,l);d!==null&&r(u,{...Kt(u.params),...d})}o.delete(a.id),i.add(a.id),s.push({task:a,params:l})}};return r(t,e),s}async inputsFor(t,e,s){const i=e.framing,o={},r={},a={},l={};for(const m of t.task.params)if(!(m.kind!=="featureSet"&&m.kind!=="pairSet"&&m.kind!=="track"&&m.kind!=="sequence"))for(const[h,y]of Co(m,t.params)){const g=this.host.label?.(y);if(g!==void 0&&g!==""&&(l[y]=g),m.kind==="track"||m.kind==="sequence"){if(t.task.venue==="annotations")continue;const b=await this.host.vector?.(y);b!==void 0&&(a[h]=b);continue}const w=this.host.payload(y);w!==void 0&&(m.kind==="featureSet"&&w.kind==="features"&&(o[h]=w.data),m.kind==="pairSet"&&w.kind==="pairs"&&(r[h]=w.data))}const c={};for(const m of t.task.params){if(m.kind!=="file")continue;const h=this.held.get(Xt(t.task.id,m.key));h!==void 0&&h.value===t.params[m.key]&&(c[m.key]=h.source)}const u={};if(Object.keys(c).length>0&&(u.sources=c),Object.keys(o).length>0&&(u.features=o),Object.keys(r).length>0&&(u.pairs=r),Object.keys(l).length>0&&(u.labels=l),t.task.venue==="annotations"){const m=this.host.contigLengths?.(e.task);m!==void 0&&(u.contigLengths=m)}if(Object.keys(a).length>0&&(u.vectors=a),Object.keys(s).length>0&&(u.upstream={...s}),e.target.orientation!==void 0&&(u.orientation=e.target.orientation),e.target.binning!==void 0&&e.target.source!==void 0&&(u.mapSource=e.target.source),e.target.pairsStats!==void 0&&(u.pairsStats=e.target.pairsStats),t.task.id==="hicrep"){const m=[],h=await this.host.allTargetsReady?.()??this.host.allTargets?.()??[];for(const y of h)y.map===e.target.map||y.source===void 0||m.push({label:y.label,uri:y.uri,source:y.source,...y.cells===void 0?{}:{cells:y.cells},...y.binning===void 0?{}:{binning:y.binning},...y.resample===void 0?{}:{resample:y.resample},...e.framing.coarsen===void 0?{}:{coarsen:e.framing.coarsen}});m.length>0&&(u.peers=m),e.target.label!==""&&(u.mapLabel=e.target.label)}const d=this.hostBlockFor(e),f=(i.contacts??null)===(e.target.resample?.contacts??null);return d!==null&&f&&Ao(d)&&No(d,i)&&(u.block=d),u}hostBlockFor(t){const e=this.host.targetMap?.()??J;return t.framing.coarsen!==void 0?null:t.target.map===e?this.host.block():null}setState(t,e,s=!1){this.states.set(t,e),s?this.notifySoon():this.notifyNow()}notifyNow(){this.trailing!==null&&(clearTimeout(this.trailing),this.trailing=null),this.lastNotifiedAt=performance.now();for(const t of[...this.listeners])t()}notifySoon(){const t=So-(performance.now()-this.lastNotifiedAt);if(t<=0){this.notifyNow();return}this.trailing===null&&(this.trailing=setTimeout(()=>{this.trailing=null,this.notifyNow()},t))}}function Co(n,t){if(n.multiple===!0)return Gi(t,n.key).map(s=>[`${n.key}:${s}`,s]);const e=Ki(t,n.key);return e===null?[]:[[n.key,e]]}function Ao(n){return n.values.byteLength<=_s}function No(n,t){return n.rowExtent[0]===t.rows[0]&&n.rowExtent[1]===t.rows[1]&&n.colExtent[0]===t.cols[0]&&n.colExtent[1]===t.cols[1]&&n.binsPerCell===t.binsPerCell}function De(n,t="loaded tracks"){return{uri:n.uri,rows:[0,0],cols:[0,0],binsize:n.binsize,binsPerCell:1,balance:!1,value:"count",normalise:null,level:"bin",label:`${Sn(n.uri)} · ${t}, no contact map`,...n.circular===void 0?{}:{circular:[...n.circular]},...n.origins===void 0?{}:{origins:{...n.origins}}}}const Lo="map";function Io(n,t){const e=new Map,s=[];for(const r of n)for(const a of r.result.outputs)e.has(a.id)||(e.set(a.id,[]),s.push(a.id)),e.get(a.id)?.push({label:r.label,output:a});const i=[],o=[];for(const r of s){const a=e.get(r)??[];if(a.some(d=>Oo(d.output))){i.push(Fo(r,a));continue}const l=a.filter(d=>d.output.kind==="table");if(l.length>0&&l.length===a.length){i.push(Po(r,l));continue}const u=a.map(d=>({label:d.label,curve:t(d.output),output:d.output})).filter(d=>d.curve!==null);if(u.length<2){(a.length>0&&u.length!==a.length||a.length>1)&&o.push(a[0].output.label);continue}i.push(Bo(r,u))}return{outputs:i,perMapOnly:o}}function Oo(n){return(n.kind==="curve"||n.kind==="matrix"||n.kind==="table")&&n.acrossMaps===!0}function Fo(n,t){const e=i=>i.kind==="curve"?i.series.length:i.kind==="matrix"?i.nrows:i.kind==="table"?i.rows.length:0;let s=t[0].output;for(const i of t)e(i.output)>e(s)&&(s=i.output);return{...s,id:`${n}__all`,label:`${s.label} — all maps`}}function Po(n,t){const e=[],s=new Set;for(const a of t)for(const l of a.output.columns)s.has(l.key)||(s.add(l.key),e.push(l));let i=Lo;for(;s.has(i);)i=`${i}_`;const o=[];for(const a of t)for(const l of a.output.rows)o.push({[i]:a.label,...l});const r=t[0].output;return{kind:"table",id:`${n}__all`,label:`${r.label} — all maps`,columns:[{key:i,label:"Map",kind:"text",hint:"The map this row was measured on, by the name the deck gives it."},...e],rows:o}}function Bo(n,t){const e=t.every(a=>a.curve.series.length===1),s=[];for(const a of t)for(const l of a.curve.series)s.push({...l,name:e?a.label:`${a.label} · ${l.name}`,...l.colour===void 0?{}:{colour:l.colour},...l.stack===void 0?{}:{stack:`${a.label} · ${l.stack}`}});const i=t[0].curve,o=i.xTicks,r=o!==void 0&&t.every(a=>a.curve.xTicks?.join("\0")===o.join("\0"));return{kind:"curve",id:`${n}__all`,label:`${i.label} — all maps`,series:s,xLabel:i.xLabel,yLabel:i.yLabel,xScale:i.xScale,yScale:i.yScale,...r?{xTicks:[...o]}:{}}}function Ct(n){return n.filter(t=>Number.isFinite(t)).sort((t,e)=>t-e)}function ut(n,t){if(n.length===0)return Number.NaN;if(n.length===1)return n[0];const e=(n.length-1)*Math.min(1,Math.max(0,t)),s=Math.floor(e),i=Math.ceil(e);return s===i?n[s]:n[s]+(e-s)*(n[i]-n[s])}function Un(n){const t=Ct(n);if(t.length===0)return{low:Number.NaN,q1:Number.NaN,median:Number.NaN,q3:Number.NaN,high:Number.NaN,outliers:[]};const e=ut(t,.25),s=ut(t,.5),i=ut(t,.75),o=1.5*(i-e),r=e-o,a=i+o;let l=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;const u=[];for(const d of t){if(d<r||d>a){u.push(d);continue}d<l&&(l=d),d>c&&(c=d)}return Number.isFinite(l)||(l=s),Number.isFinite(c)||(c=s),{low:l,q1:e,median:s,q3:i,high:c,outliers:u}}function Yt(n,t=0){const e=Ct(n);if(e.length===0)return{edges:[],counts:[]};const s=e[0],i=e[e.length-1];if(s===i)return{edges:[s,s+1],counts:[e.length]};let o=Math.round(t);if(!(o>0)){const c=ut(e,.75)-ut(e,.25),u=c>0?2*c/Math.cbrt(e.length):0;o=u>0?Math.ceil((i-s)/u):Math.ceil(Math.sqrt(e.length))}o=Math.max(1,Math.min(400,o));const r=(i-s)/o,a=[];for(let c=0;c<=o;c++)a.push(s+c*r);const l=new Array(o).fill(0);for(const c of e){const u=Math.floor((c-s)/r);l[u>=o?o-1:u<0?0:u]+=1}return{edges:a,counts:l}}function Ve(n,t=64){const e=Ct(n);if(e.length<2)return{at:[],y:[]};const s=e.length,i=e.reduce((g,w)=>g+w,0)/s,o=e.reduce((g,w)=>g+(w-i)**2,0)/(s-1),r=Math.sqrt(Math.max(0,o)),a=ut(e,.75)-ut(e,.25),l=Math.min(r||Number.POSITIVE_INFINITY,a>0?a/1.34:Number.POSITIVE_INFINITY),c=Number.isFinite(l)&&l>0?.9*l*Math.pow(s,-.2):0;if(!(c>0))return{at:[],y:[]};const u=e[0]-3*c,f=(e[s-1]+3*c-u)/Math.max(1,t-1),m=[],h=[],y=1/(s*c*Math.sqrt(2*Math.PI));for(let g=0;g<t;g++){const w=u+g*f;let b=0;for(const S of e){const A=(w-S)/c;b+=Math.exp(-.5*A*A)}m.push(w),h.push(b*y)}return{at:m,y:h}}const qo={"&":"&","<":"<",">":">",'"':""","'":"'"};function dt(n){return n.replace(/[&<>"']/g,t=>qo[t]??t)}function jt(n){return`<div class="figure-tip-head">${dt(n)}</div>`}function zo(n){return typeof n!="string"||n===""?"":`<svg class="figure-tip-swatch" viewBox="0 0 10 10" aria-hidden="true"><circle cx="5" cy="5" r="5" fill="${dt(n)}"/></svg>`}function Nt(n,t,e){return`<div class="figure-tip-row">${zo(n)}<span class="figure-tip-name">${dt(t)}</span><span class="figure-tip-value">${dt(e)}</span></div>`}function Ro(n,t,e){return n.measure?.(t,e)??t.length*e*.6}function Zn(n,t,e,s){const i=e.colours[n.id];return i!==void 0?i:n.colour!==void 0?n.colour:s.series[t%s.series.length]}function le(n,t){return Ds(t.mark)?t.mark:n.mark??t.mark}function Y(n,t){return!Number.isFinite(n)||t&&n<=0?null:n}function _o(n,t){const e=t.x.scale==="log",s=t.y.scale==="log",i=[];for(let o=0;o<n.y.length;o++){const r=Y(n.x[o]??o,e),a=Y(n.y[o],s);i.push(r===null||a===null?null:[r,a])}return i}function Xn(n){const t=n.binsize;if(t!==void 0)return s=>z.bp(s*t);if(/\(bp\)/i.test(n.xLabel??""))return s=>z.bp(s);const e=n.xTicks;if(e!==void 0)return s=>Number.isInteger(s)?e[s]??"":""}function jn(n){if(/\(%\)/.test(n.yLabel??""))return t=>{const e=t*100;return z.pct(t,Math.abs(e-Math.round(e))<1e-9?0:1)}}const Do=["high","upper quartile","median","lower quartile","low"];function St(n){return typeof n=="number"&&Number.isFinite(n)}function Vo(n){const t=Array.isArray(n)?n[1]:n;return St(t)?t:null}function Wo(n,t){const e=t.mark==="histogram",s=t.x.scale==="log"?"log":"linear",i=t.y.scale==="log"?"log":"linear",o=e?void 0:Xn(n),r=e?void 0:jn(n),a=c=>{const u=o?.(c)??"";return u!==""?u:ct(c,s)},l=r??(c=>ct(c,i));return c=>{if(Array.isArray(c)){const h=c[0];if(h===void 0)return"";const y=c.flatMap(g=>{const w=Vo(g.value);return w===null?[]:[Nt(g.color,g.seriesName??"",l(w))]});return jt(St(h.axisValue)?a(h.axisValue):"")+y.join("")}if(c.seriesType==="boxplot"){const h=Array.isArray(c.value)?c.value.slice(-5):[],y=jt(c.name??"");if(h.length!==5||!h.every(St))return y;const g=[...h].reverse();return y+Do.map((w,b)=>Nt(null,w,ct(g[b],i))).join("")}const u=jt(c.seriesName??"");if(c.seriesType==="custom")return u;const d=Array.isArray(c.value)?c.value:[],[f,m]=d;return!St(f)||!St(m)?u:u+(e?Nt(c.color,a(f),z.int(m)):Nt(c.color,a(f),l(m)))}}function Q(n,t,e){return{axisLine:{onZero:!1,lineStyle:{color:n.ink,width:ce}},axisTick:{lineStyle:{color:n.ink,width:ce}},axisLabel:{color:n.muted,fontSize:t.fontSize,fontFamily:n.fontFamily},nameTextStyle:{color:n.ink,fontSize:t.fontSize,fontFamily:n.fontFamily},splitLine:{show:e,showMinLine:!1,showMaxLine:!1,lineStyle:{color:n.grid,type:"solid",width:Go}}}}const ce=1,Go=.5;function Qn(n){return{show:!0,backgroundColor:"transparent",borderColor:n.ink,borderWidth:ce,z:3}}const Lt=.05;function It(n,t,e){let s=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of n)!Number.isFinite(r)||t&&r<=0||(r<s&&(s=r),r>i&&(i=r));if(!(s<i))return null;if(!(e>0))return[s,i];if(t){const r=Math.log10(s),a=Math.log10(i),l=(a-r)*e;return[10**(r-l),10**(a+l)]}const o=(i-s)*e;return[s-o,i+o]}function ke(n,t,e){const s=n.series.filter(c=>!t.hidden.includes(c.id));if(t.mark==="histogram"){if(e==="y")return null;const c=s.flatMap(u=>Yt(u.y,t.bins).edges);return It(c,t.x.scale==="log",Lt)}if($n(t.mark))return e==="x"?null:It(sr(s,t),t.y.scale==="log",Lt);const i=s.map(c=>le(c,t));if(i.includes("bars")||e==="y"&&t.mark==="bars")return null;const o=t.x.scale==="log",r=t.y.scale==="log";if(e==="x"){const c=[];for(const u of s){const d=t.bands&&u.low!==void 0&&u.high!==void 0;for(let f=0;f<u.y.length;f++){const m=Y(u.x[f]??f,o);if(m===null)continue;(Y(u.y[f],r)!==null||d&&Y(u.low[f],r)!==null&&Y(u.high[f],r)!==null)&&c.push(m)}}return It(c,o,i.includes("points")?Lt:0)}const a=t.x.domain,l=[];for(const c of s){const u=le(c,t)!=="points",d=[c.y];t.bands&&c.low!==void 0&&c.high!==void 0&&d.push(c.low,c.high);for(const f of d)Ho(c,f,a,u,o,r,l)}return It(l,r,Lt)}function Ho(n,t,e,s,i,o,r){const a=(c,u)=>u?Math.log10(c):c;let l=null;for(let c=0;c<t.length;c++){const u=Y(n.x[c]??c,i),d=Y(t[c],o);if(u===null||d===null){l=null;continue}if((e===null||u>=e[0]&&u<=e[1])&&r.push(d),e!==null&&s&&l!==null)for(const f of e){if((l.x-f)*(u-f)>=0)continue;const m=(a(f,i)-a(l.x,i))/(a(u,i)-a(l.x,i)),h=a(l.y,o)+m*(a(d,o)-a(l.y,o));r.push(o?10**h:h)}l={x:u,y:d}}}function Jn(n,t){if(!(n>0)||!(t>n))return null;const e=Math.log10(n),s=Math.log10(t);if(s-e>=10){const u=Math.ceil((s-e)/6),d=[];for(let f=Math.ceil(e/u)*u;f<=s+1e-9;f+=u)d.push(10**f);return d}if(Math.floor(s+1e-9)-Math.ceil(e-1e-9)+1>=3)return null;const i=u=>u>=n*(1-1e-9)&&u<=t*(1+1e-9);for(const u of[[1,2,5],[1,2,3,4,5,6,7,8,9]]){const d=[];for(let f=Math.floor(e);f<=Math.ceil(s);f++)for(const m of u){const h=+`${m}e${f}`;i(h)&&d.push(h)}if(d.length>=3)return d}const o=(t-n)/4,r=10**Math.floor(Math.log10(o)),a=o/r,l=(a<=1?1:a<=2?2:a<=5?5:10)*r,c=[];for(let u=Math.ceil(n/l);u*l<=t*(1+1e-12);u++)c.push(Number((u*l).toPrecision(12)));return c}function Dt(n,t,e){const s=t.mark==="histogram";if(s&&e==="y")return{bounds:{},labels:{}};const i=t[e].scale==="log",r=n.series.filter(d=>!t.hidden.includes(d.id)).flatMap(d=>s?Yt(d.y,t.bins).edges:e==="x"?d.x:d.y),a=ue(t[e].domain,ke(n,t,e),r,i);if(!i)return a;const[l,c]=t[e].domain??[a.bounds.min,a.bounds.max],u=typeof l=="number"&&typeof c=="number"?Jn(l,c):null;return u===null?a:{...a,labels:ts(a.labels,u,l,c),ticks:u}}function ts(n,t,e,s){const i=(r,a)=>r!==void 0&&typeof a=="number"&&Math.abs(r-a)<=1e-9*Math.max(Math.abs(r),Math.abs(a)),o={...n};return i(t[0],e)||delete o.showMinLabel,i(t[t.length-1],s)||delete o.showMaxLabel,o}function We(n){return n===null?{start:0,end:100}:{startValue:n[0],endValue:n[1]}}function Ko(n){const t=n.legend;if(t===void 0||t.show===!1||!Array.isArray(t.data)||t.selected===void 0)return n;const e=t.selected;return{...n,legend:{...t,data:t.data.filter(s=>e[String(s)]!==!1)}}}const Ge=28,lt={right:8,padding:5,icon:25,iconGap:5},Yo=.35,Uo=72;function Zo(n,t,e){if(e(n)<=t)return[n];const s=[];let i="";for(const l of n)i+=l,".-_:/, ".includes(l)&&(s.push(i),i="");i!==""&&s.push(i);const o=[];let r="";const a=()=>{const l=r.trimEnd();l!==""&&o.push(l),r=""};for(const l of s){if(r!==""&&e(r+l)>t&&a(),e(l)<=t){r+=l;continue}for(const c of l)r!==""&&e(r+c)>t&&a(),r+=c}return a(),o}function Xo(n,t,e,s){const i=u=>Ro(e,u,t.fontSize),o=lt.right+2*lt.padding+lt.icon+lt.iconGap,r=t.fontSize,a=s===void 0?Number.POSITIVE_INFINITY:Math.max(Uo,s.width*Yo-o-r),l=new Map(n.map(u=>[u,Zo(u,a,i)]));let c=0;for(const u of l.values())for(const d of u)c=Math.max(c,i(d));return{room:Math.ceil(o+c+r),formatter:u=>(l.get(u)??[u]).join(`
|
|
7
|
+
`)}}function jo(n,t,e,s){const i=n.series.map((m,h)=>({series:m,index:h,colour:Zn(m,h,t,e),hidden:t.hidden.includes(m.id)})),o=i.map(m=>m.series.name),r=Object.fromEntries(i.map(m=>[m.series.name,!m.hidden])),a=$n(t.mark),l=a?"none":t.legend,c=l==="right"?Xo(o,t,e,s):null,u=t.legend==="none"?{show:!1,data:o,selected:r}:{show:!0,type:"scroll",data:o,selected:r,textStyle:{color:e.ink,fontSize:t.fontSize,fontFamily:e.fontFamily},...t.legend==="right"?{orient:"vertical",right:lt.right,top:"middle",padding:lt.padding,itemWidth:lt.icon,...c===null?{}:{formatter:c.formatter}}:t.legend==="top"?{orient:"horizontal",top:4,left:"center"}:{orient:"horizontal",bottom:4,left:"center"}},d={...Qn(e),left:8,right:c===null?16:c.room,top:l==="top"?Ge+8:16,bottom:l==="bottom"?Ge+8:8,outerBoundsMode:"same"},f=a?nr(n,t,e,i):Qo(n,t,e,i);return{backgroundColor:e.background,animation:!1,textStyle:{fontFamily:e.fontFamily,fontSize:t.fontSize,color:e.ink},...t.title===null||t.title===""?{}:{title:{text:t.title,left:"center",top:4,textStyle:{color:e.ink,fontSize:t.fontSize+4,fontFamily:e.fontFamily}}},grid:{...d,top:t.title===null||t.title===""?d.top:d.top+t.fontSize+12},legend:u,tooltip:t.tooltip?{trigger:a||t.mark==="points"||t.mark==="histogram"?"item":"axis",axisPointer:{type:"cross",lineStyle:{color:e.muted,type:"solid"},crossStyle:{color:e.muted,type:"solid"}},backgroundColor:e.background,borderColor:e.grid,textStyle:{color:e.ink,fontSize:t.fontSize},formatter:Wo(n,t)}:{show:!1},...f}}function ue(n,t,e,s){const i=c=>{const u=c[1]-c[0];return{...He(c[0],u,s)?{}:{showMinLabel:!1},...He(c[1],u,s)?{}:{showMaxLabel:!1}}};if(n===null)return t===null?{bounds:{},labels:{}}:{bounds:{min:t[0],max:t[1]},labels:i(t)};if(t!==null)return{bounds:{min:Math.min(t[0],n[0]),max:Math.max(t[1],n[1])},labels:i(n)};let o=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const c of e)!Number.isFinite(c)||s&&c<=0||(c<o&&(o=c),c>r&&(r=c));const a=o>r||n[0]<o,l=o>r||n[1]>r;return{bounds:{...a?{min:n[0]}:{},...l?{max:n[1]}:{}},labels:i(n)}}function He(n,t,e){if(e){if(!(n>0))return!1;const i=Math.log10(n);return Math.abs(i-Math.round(i))<1e-9}if(!Number.isFinite(n)||!(t>0))return!1;const s=n/10**(Math.floor(Math.log10(t))-1);return Math.abs(s-Math.round(s))<1e-6*Math.max(1,Math.abs(s))}function Qo(n,t,e,s){const i=t.mark==="histogram",o=[],r=Math.max(1,s.filter(h=>!h.hidden).length),a=Math.max(.07,.35/Math.sqrt(r));for(const h of s){if(i){o.push(...er(h,t,Math.min(1,.9/Math.sqrt(r)+.1)));continue}t.bands&&h.series.low!==void 0&&h.series.high!==void 0&&o.push(...tr(h,t)),o.push(Jo(h,t,a))}const l=t.x.label??(i?n.yLabel:n.xLabel),c=t.y.label??(i?"count":n.yLabel),u=i?void 0:Xn(n),d=i?void 0:jn(n),f=Dt(n,t,"x"),m=Dt(n,t,"y");return{xAxis:{type:t.x.scale==="log"?"log":"value",name:l,nameLocation:"middle",nameGap:t.fontSize*2.4,scale:!0,...n.xTicks!==void 0&&!i?{minInterval:1}:{},...i?{containShape:!1}:{},...f.bounds,...Q(e,t,t.x.grid),...f.ticks===void 0?{}:{axisTick:{...Q(e,t,t.x.grid).axisTick,customValues:f.ticks}},axisLabel:{...Q(e,t,t.x.grid).axisLabel,...f.ticks===void 0?{}:{customValues:f.ticks},...i?{}:{hideOverlap:!0},...f.labels,formatter:u??(h=>ct(h,t.x.scale==="log"?"log":"linear"))},axisPointer:{label:{formatter:Ke(u,t.x.scale)}}},yAxis:{type:t.y.scale==="log"?"log":"value",name:c,nameLocation:"middle",nameGap:t.fontSize*4,scale:t.mark!=="histogram"&&t.mark!=="bars",...m.bounds,...Q(e,t,t.y.grid),...m.ticks===void 0?{}:{axisTick:{...Q(e,t,t.y.grid).axisTick,customValues:m.ticks}},axisLabel:{...Q(e,t,t.y.grid).axisLabel,...m.ticks===void 0?{}:{customValues:m.ticks},...i?{}:{hideOverlap:!0},...m.labels,formatter:d??(h=>ct(h,t.y.scale==="log"?"log":"linear"))},axisPointer:{label:{formatter:Ke(d,t.y.scale)}}},dataZoom:[{id:xe,type:"inside",xAxisIndex:0,zoomOnMouseWheel:!0,moveOnMouseMove:!0,filterMode:"none",...We(t.x.domain)},{id:Se,type:"inside",yAxisIndex:0,zoomOnMouseWheel:"shift",moveOnMouseMove:!1,filterMode:"none",...We(t.y.domain)}],series:o}}const xe="zoom-x",Se="zoom-y";function Ke(n,t){return({value:e})=>{if(typeof e!="number"||!Number.isFinite(e))return"";const s=n?.(e)??"";return s!==""?s:ct(e,t==="log"?"log":"linear")}}function Jo(n,t,e){const s=le(n.series,t),i=_o(n.series,t),o={id:n.series.id,name:n.series.name,data:i,color:n.colour,emphasis:{focus:"series"}};if(s==="points")return{...o,type:"scatter",symbolSize:t.pointSize,itemStyle:{color:n.colour,opacity:.85}};if(s==="bars")return{...o,type:"bar",itemStyle:{color:n.colour},barMaxWidth:24,...n.series.stack===void 0?{}:{stack:n.series.stack}};const r=s==="area"||t.fillArea;return{...o,type:"line",step:s==="step"?"middle":!1,smooth:t.smooth,symbol:"none",lineStyle:{width:t.lineWidth,color:n.colour},...r?{areaStyle:{color:n.colour,opacity:e,origin:"auto"}}:{},connectNulls:!1,sampling:"lttb"}}function tr(n,t){const e=n.series.low,s=n.series.high,i=t.y.scale==="log",o=t.x.scale==="log",r=[],a=[];for(let u=0;u<e.length;u++){const d=Y(n.series.x[u]??u,o),f=Y(e[u],i),m=Y(s[u],i);if(d===null||f===null||m===null){r.push(null),a.push(null);continue}r.push([d,f]),a.push([d,m-f])}const l=`band-${n.series.id}`,c={type:"line",stack:l,stackStrategy:"all",symbol:"none",silent:!0,legendHoverLink:!1,lineStyle:{opacity:0},tooltip:{show:!1}};return[{...c,id:`${l}-low`,name:`${n.series.name} ${l}-low`,data:r},{...c,id:`${l}-high`,name:`${n.series.name} ${l}-high`,data:a,areaStyle:{color:n.colour,opacity:.18}}]}function er(n,t,e){const{edges:s,counts:i}=Yt(n.series.y,t.bins);if(i.length===0)return[];const o=i.map((r,a)=>[(s[a]+s[a+1])/2,r]);return[{id:n.series.id,name:n.series.name,type:"bar",data:o,color:n.colour,barGap:"-100%",barCategoryGap:"1%",itemStyle:{color:n.colour,opacity:e}}]}function nr(n,t,e,s){const i=s.filter(d=>!d.hidden),o=i.map(d=>d.series.name),r=t.y.label??n.yLabel,a=t.mark==="box"?es(i,t,e):ir(i,t,e);t.jitter&&a.push({id:"points",name:"points",type:"scatter",symbolSize:Math.max(2,t.pointSize/2),itemStyle:{color:e.muted,opacity:.4},silent:!0,data:i.flatMap((d,f)=>Ct(d.series.y).map(m=>[f,m]))});const l=t.y.scale==="log",c=t.y.domain??ke(n,t,"y"),u=l&&c!==null?Jn(c[0],c[1]):null;return{legend:{show:!1},xAxis:{type:"category",data:o,...Q(e,t,!1),axisTick:{show:!1}},yAxis:{type:t.y.scale==="log"?"log":"value",name:r,nameLocation:"middle",nameGap:t.fontSize*4,scale:!0,...c===null?{}:{min:c[0],max:c[1]},...Q(e,t,t.y.grid),...u===null?{}:{axisTick:{...Q(e,t,t.y.grid).axisTick,customValues:u}},axisLabel:{...Q(e,t,t.y.grid).axisLabel,...c===null?{}:u===null?ue(c,null,[],l).labels:ts(ue(c,null,[],l).labels,u,c[0],c[1]),...u===null?{}:{customValues:u},formatter:d=>ct(d,l?"log":"linear")}},series:a}}function sr(n,t){const e=t.mark==="violin"?n.map(o=>ns(o.y,t.y.scale==="log")):[],s=e.some(o=>o.y.some(r=>r>0)),i=[];return n.forEach((o,r)=>{if(s)for(const a of e[r].at)i.push(a);else{const a=Un(o.y);i.push(a.low,a.high,...a.outliers)}if(t.jitter)for(const a of o.y)i.push(a)}),i}function es(n,t,e){const s=n.map(i=>Un(i.series.y));return[{id:"box",name:"box",type:"boxplot",data:s.map((i,o)=>({value:[i.low,i.q1,i.median,i.q3,i.high],itemStyle:{color:n[o].colour,borderColor:e.ink,opacity:.55}})),boxWidth:[10,48]},{id:"outliers",name:"outliers",type:"scatter",symbolSize:Math.max(3,t.pointSize/1.5),itemStyle:{color:e.muted},silent:!0,data:s.flatMap((i,o)=>i.outliers.map(r=>[o,r]))}]}function ir(n,t,e){const s=t.y.scale==="log",i=n.map(r=>ns(r.series.y,s)),o=Math.max(0,...i.flatMap(r=>r.y));return o>0?n.map((r,a)=>({id:`violin-${r.series.id}`,name:r.series.name,type:"custom",color:r.colour,itemStyle:{color:r.colour},data:i[a].at.map(l=>[a,l]),clip:!0,renderItem:(l,c)=>{if(l.dataIndex!==0)return{type:"group",children:[]};const u=i[a];if(u.at.length===0)return{type:"group",children:[]};const d=c.size?.([1,0])??[24,0],f=Math.min(48,d[0]*.42),m=[];for(let h=0;h<u.at.length;h++){const[y,g]=c.coord([a,u.at[h]]);m.push([y-u.y[h]/o*f,g])}for(let h=u.at.length-1;h>=0;h--){const[y,g]=c.coord([a,u.at[h]]);m.push([y+u.y[h]/o*f,g])}return{type:"polygon",shape:{points:m},style:{fill:r.colour,opacity:.55,stroke:e.ink,lineWidth:t.lineWidth/2}}},encode:{x:0,y:1}})):es(n,t,e)}function ns(n,t){if(!t)return Ve(n);const e=Ct(n).filter(i=>i>0).map(i=>Math.log10(i)),s=Ve(e);return{at:s.at.map(i=>10**i),y:s.y}}const or=2e4;function Vt(n){const t=n.nrows*n.ncols;return t>0&&t<=or&&n.large!==!0&&n.aspect!=="fill"}const Ye=32;function rr(n){const t=Gs(n)?n:Ws,e=[];for(let s=0;s<Ye;s++)e.push(Vs(t,s/(Ye-1)));return e}function ar(n,t){let e=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const o of n.values)Number.isFinite(o)&&(o<e&&(e=o),o>s&&(s=o));const i=t??{vmin:null,vmax:null};if(i.vmin!==null||i.vmax!==null){const o=i.vmin??(Number.isFinite(e)?e:0),r=i.vmax??(Number.isFinite(s)?s:1);if(o<r)return{vmin:o,vmax:r}}if(n.range!==void 0&&n.range[1]>n.range[0])return{vmin:n.range[0],vmax:n.range[1]};if(!(e<=s))return null;if(n.centre!==void 0){const o=n.centre,r=Math.max(Math.abs(s-o),Math.abs(e-o))||1;return{vmin:o-r,vmax:o+r}}return{vmin:e,vmax:s>e?s:e+1}}function Wt(n,t){const e=new Array(Math.max(0,t)).fill("");if(n.length===0||t<=0)return e;if(n.length===t){for(let s=0;s<t;s++)e[s]=n[s]??"";return e}return n.length===1?(e[Math.floor((t-1)/2)]=n[0],e):(n.forEach((s,i)=>{const o=Math.round(i*(t-1)/(n.length-1));(e[o]===""||i===n.length-1)&&(e[o]=s)}),e)}function lr(n){const t=[];for(let e=0;e<n.nrows;e++)for(let s=0;s<n.ncols;s++){const i=n.values[e*n.ncols+s];Number.isFinite(i)&&t.push([s,n.nrows-1-e,i])}return t}function cr(n){const t=new Map;for(const e of[...n?.top??[],...n?.right??[]]){const s=t.get(e.name)??{lo:Number.POSITIVE_INFINITY,hi:Number.NEGATIVE_INFINITY};for(const i of e.values)Number.isFinite(i)&&(i<s.lo&&(s.lo=i),i>s.hi&&(s.hi=i));t.set(e.name,s)}return t}function Ue(n,t,e,s,i,o,r){return n.map((a,l)=>{const c=Math.max(0,o.indexOf(a.name)),u=t.series[c%t.series.length],d=r.get(a.name),f=d===void 0?0:d.hi-d.lo,m=[];for(const[h,y]of a.values.entries()){if(!Number.isFinite(y))continue;const g=f>0&&d!==void 0?(y-d.lo)/f:0,w=i?a.values.length-1-h:h;m.push(i?[g,w]:[w,g])}return{type:"line",name:a.name,id:`margin-${i?"right":"top"}-${l}`,xAxisIndex:s,yAxisIndex:s,data:m,showSymbol:!1,lineStyle:{color:u,width:Math.max(1,e.lineWidth*.8)},itemStyle:{color:u},areaStyle:{color:u,opacity:.18},silent:!0,tooltip:{show:!1},z:3}})}function Ze(n,t,e){const s={type:"value",gridIndex:n,min:-.5,max:t-.5,show:!1},i={type:"value",gridIndex:n,min:0,max:1,show:!1};return e?[i,s]:[s,i]}function ur(n,t,e,s){const i=ar(n,t),o=t.fontSize,r=(n.margins?.top??[]).filter(E=>E.values.length>0),a=(n.margins?.right??[]).filter(E=>E.values.length>0),l=o*3.5,c=o*.8,u=[...new Set([...r,...a].map(E=>E.name))],d=cr(n.margins),f=t.title!==null&&t.title!=="",m=u.length>0?o*1.8:0,h=(f?o+14:4)+m+(r.length>0?l+c:0),g=o*5.5+(a.length>0?l+c:0),w=n.stats??[],b=(n.xLabel===""?0:o*1.6)+(w.length>0?o*1.8:0),S={left:n.yLabel===""?o*3.5:o*5,right:g,top:h,bottom:o*2.6+b},A=Math.max(1,s.width-S.left-S.right),v=Math.max(1,s.height-S.top-S.bottom),k=Math.max(1,n.ncols),M=Math.max(1,n.nrows),x=n.aspect==="fill"?{width:A/k,height:v/M}:(()=>{const E=Math.min(A/k,v/M);return{width:E,height:E}})(),$={left:S.left+(A-x.width*k)/2,top:S.top+(v-x.height*M)/2,width:x.width*k,height:x.height*M,containLabel:!1,...Qn(e)},T=[$],C=[],O=[],F=[],P=(E,q)=>({axisLine:{lineStyle:{color:e.ink}},axisTick:{lineStyle:{color:e.ink}},axisLabel:{color:e.muted,fontSize:o,fontFamily:e.fontFamily,...E.length>0&&E.length!==q?{interval:0}:{}},nameTextStyle:{color:e.ink,fontSize:o,fontFamily:e.fontFamily},splitLine:{show:!1},splitArea:{show:!1}});if(C.push({type:"category",gridIndex:0,data:Wt(n.xTicks,n.ncols),name:n.xLabel,nameLocation:"middle",nameGap:o*2.2,...P(n.xTicks,n.ncols)}),O.push({type:"category",gridIndex:0,data:[...Wt(n.yTicks,n.nrows)].reverse(),name:n.yLabel,nameLocation:"middle",nameGap:o*3.4,...P(n.yTicks,n.nrows)}),F.push({type:"heatmap",id:"matrix",name:n.label,data:lr(n),xAxisIndex:0,yAxisIndex:0,itemStyle:{borderWidth:0},emphasis:{itemStyle:{borderColor:e.ink,borderWidth:1}},progressive:0}),r.length>0){T.push({left:$.left,width:$.width,top:$.top-l-c,height:l});const E=T.length-1,[q,mt]=Ze(E,n.ncols,!1);C.push(q),O.push(mt),F.push(...Ue(r,e,t,E,!1,u,d))}if(a.length>0){T.push({left:$.left+$.width+c,width:l,top:$.top,height:$.height});const E=T.length-1,[q,mt]=Ze(E,n.nrows,!0);C.push(q),O.push(mt),F.push(...Ue(a,e,t,E,!0,u,d))}const H=$.left+$.width+c+(a.length>0?l+c:0),G=Math.max(o*6,$.height-o*2),V=[0,...r.length>0?[1]:[]],W=[0,...a.length>0?[T.length-1]:[]],at=(E,q)=>E===null?{start:0,end:100}:{startValue:Math.max(0,Math.round(E[0])),endValue:Math.min(q-1,Math.round(E[1]))},U=w.map(E=>`${E.label} ${E.value.toFixed(E.digits??2)}`).join(" · ");return{backgroundColor:e.background,animation:!1,textStyle:{fontFamily:e.fontFamily,fontSize:o,color:e.ink},...f||U!==""?{title:[...f?[{text:t.title,left:"center",top:4,textStyle:{color:e.ink,fontSize:o+4,fontFamily:e.fontFamily}}]:[],...U===""?[]:[{text:U,left:"center",bottom:2,textStyle:{color:e.muted,fontSize:o,fontFamily:e.fontFamily}}]]}:{},grid:T,xAxis:C,yAxis:O,...u.length===0?{}:{legend:{data:u.map(E=>({name:E,icon:"roundRect"})),left:o*.5,top:f?o+10:2,selectedMode:!1,itemWidth:Math.round(o*.9),itemHeight:Math.max(2,Math.round(o*.22)),itemGap:Math.round(o),textStyle:{color:e.muted,fontSize:o,fontFamily:e.fontFamily},formatter:E=>{const q=d.get(E);return q===void 0||!(q.lo<=q.hi)?E:`${E} ${qt(q.lo)}–${qt(q.hi)}`}}},...i===null?{}:{visualMap:{type:"continuous",min:i.vmin,max:i.vmax,calculable:!0,realtime:!0,orient:"vertical",left:H,top:$.top+($.height-G)/2,itemWidth:Math.round(o*.9),itemHeight:Math.round(G),formatter:E=>qt(E),inRange:{color:rr(t.colormap??n.colormap)},textStyle:{color:e.muted,fontSize:o,fontFamily:e.fontFamily},seriesIndex:0}},dataZoom:[{id:xe,type:"inside",xAxisIndex:V,zoomOnMouseWheel:!0,moveOnMouseMove:!0,filterMode:"none",...at(t.x.domain,n.ncols)},{id:Se,type:"inside",yAxisIndex:W,zoomOnMouseWheel:"shift",moveOnMouseMove:!1,filterMode:"none",...at(t.y.domain,n.nrows)}],tooltip:t.tooltip?{trigger:"item",backgroundColor:e.background,borderColor:e.grid,textStyle:{color:e.ink,fontSize:o},formatter:dr(n)}:{show:!1},series:F}}function dr(n){const t=Wt(n.xTicks,n.ncols),e=Wt(n.yTicks,n.nrows);return s=>{const i=s.value;if(!Array.isArray(i)||i.length<3)return"";const[o,r,a]=i,l=n.nrows-1-r,c=t[o]!==""?t[o]:`column ${o+1}`,u=e[l]!==""?e[l]:`row ${l+1}`,d=Math.abs(a)>=.001&&Math.abs(a)<1e6?a.toFixed(3):a.toExponential(2);return`${dt(u)} · ${dt(c)}<br/><b>${dt(d)}</b>`}}const hr={fill:"#000000",fillGradient:null,stroke:null,strokeWidth:1,opacity:1,fillOpacity:1,strokeOpacity:1,lineCap:"butt",lineJoin:"miter",dash:[],fontSize:12,fontFamily:"sans-serif",fontWeight:"normal",fontStyle:"normal",anchor:"left",baseline:"alphabetic",strokeFirst:!1};function B(n,t,e){const s=t.get(e);if(s!==void 0&&s!=="")return s;const i=n.getAttribute(e);return i===null||i===""?null:i}function Ut(n){const t=new Map,e=n.getAttribute("style");if(e===null)return t;for(const s of e.split(";")){const i=s.indexOf(":");i<0||t.set(s.slice(0,i).trim().toLowerCase(),s.slice(i+1).trim())}return t}function L(n,t){if(n===null)return t;const e=Number.parseFloat(n);return Number.isFinite(e)?e:t}function fr(n,t){return n==="middle"?"center":n==="end"?"right":n==="start"?"left":t}function mr(n,t){switch(n){case"central":case"middle":return"middle";case"hanging":case"text-before-edge":return"top";case"text-after-edge":case"ideographic":return"bottom";case"alphabetic":case"auto":return"alphabetic";default:return t}}function pr(n){if(n===null||n==="none")return null;const t=n.split(/[\s,]+/).filter(e=>e!=="").map(e=>Number.parseFloat(e));return t.length===0||t.some(e=>!Number.isFinite(e)||e<0)?[]:t}function ss(n,t,e){const s=Ut(n),i={...t},o=B(n,s,"fill");o!==null&&(i.fill=Xe(o,t.fill,e),i.fillGradient=gr(o,t.fillGradient,e));const r=B(n,s,"stroke");r!==null&&(i.stroke=Xe(r,t.stroke,e));const a=B(n,s,"stroke-width");a!==null&&(i.strokeWidth=L(a,t.strokeWidth));const l=B(n,s,"opacity");l!==null&&(i.opacity=t.opacity*yt(L(l,1)));const c=B(n,s,"fill-opacity");c!==null&&(i.fillOpacity=yt(L(c,1)));const u=B(n,s,"stroke-opacity");u!==null&&(i.strokeOpacity=yt(L(u,1)));const d=B(n,s,"stroke-linecap");(d==="round"||d==="square"||d==="butt")&&(i.lineCap=d);const f=B(n,s,"stroke-linejoin");(f==="round"||f==="bevel"||f==="miter")&&(i.lineJoin=f);const m=pr(B(n,s,"stroke-dasharray"));m!==null&&(i.dash=m);const h=B(n,s,"font-size");h!==null&&(i.fontSize=L(h,t.fontSize));const y=B(n,s,"font-family");y!==null&&(i.fontFamily=y);const g=B(n,s,"font-weight");g!==null&&(i.fontWeight=g);const w=B(n,s,"font-style");w!==null&&(i.fontStyle=w),i.anchor=fr(B(n,s,"text-anchor"),t.anchor),i.baseline=mr(B(n,s,"dominant-baseline")??B(n,s,"alignment-baseline"),t.baseline);const b=B(n,s,"paint-order");return b!==null&&(i.strokeFirst=b.trim().split(/\s+/)[0]==="stroke"),i}function yt(n){return n<0?0:n>1?1:n}function is(n){return/^url\(\s*['"]?#([^)'"]+)['"]?\s*\)$/.exec(n.trim())?.[1]??null}function Xe(n,t,e){const s=n.trim();if(s==="none"||s==="transparent")return null;if(s==="currentColor"||s==="inherit")return t;const i=is(s);return i!==null?e.get(i)?.flat??null:s}function gr(n,t,e){const s=n.trim();if(s==="inherit")return t;const i=is(s);return i===null?null:e.get(i)?.linear??null}function br(n){const t=new Map,e=n.querySelectorAll("linearGradient, radialGradient");for(const s of Array.from(e)){const i=s.getAttribute("id");if(i===null)continue;const o=Array.from(s.querySelectorAll("stop"));if(o.length===0)continue;const r=o[Math.floor((o.length-1)/2)],a=B(r,Ut(r),"stop-color")??"#000000";t.set(i,{flat:a,linear:s.tagName.toLowerCase()==="lineargradient"?yr(s,o):null})}return t}function yr(n,t){const e=(i,o)=>{if(i===null||i.trim()==="")return o;const r=Number.parseFloat(i);return Number.isFinite(r)?i.trim().endsWith("%")?r/100:r:o};let s=0;return{units:n.getAttribute("gradientUnits")==="userSpaceOnUse"?"userSpaceOnUse":"objectBoundingBox",x1:e(n.getAttribute("x1"),0),y1:e(n.getAttribute("y1"),0),x2:e(n.getAttribute("x2"),1),y2:e(n.getAttribute("y2"),0),stops:t.map(i=>{const o=Ut(i);return s=Math.max(s,yt(e(i.getAttribute("offset"),0))),{offset:s,rgb:Hs(B(i,o,"stop-color")??"#000000"),opacity:yt(L(B(i,o,"stop-opacity"),1))}})}}function vr(n){let t=[1,0,0,1,0,0];const e=/(matrix|translate|scale|rotate|skewX|skewY)\s*\(([^)]*)\)/g;let s;for(;(s=e.exec(n))!==null;){const i=s[2].split(/[\s,]+/).filter(o=>o!=="").map(o=>Number.parseFloat(o)).map(o=>Number.isFinite(o)?o:0);t=de(t,wr(s[1],i))}return t}function wr(n,t){switch(n){case"matrix":return[t[0]??1,t[1]??0,t[2]??0,t[3]??1,t[4]??0,t[5]??0];case"translate":return[1,0,0,1,t[0]??0,t[1]??0];case"scale":{const e=t[0]??1;return[e,0,0,t[1]??e,0,0]}case"rotate":{const e=(t[0]??0)*Math.PI/180,s=Math.cos(e),i=Math.sin(e),o=[s,i,-i,s,0,0];if(t.length<3)return o;const r=t[1],a=t[2];return de(de([1,0,0,1,r,a],o),[1,0,0,1,-r,-a])}case"skewX":return[1,0,Math.tan((t[0]??0)*Math.PI/180),1,0,0];case"skewY":return[1,Math.tan((t[0]??0)*Math.PI/180),0,1,0,0];default:return[1,0,0,1,0,0]}}function de(n,t){return[n[0]*t[0]+n[2]*t[1],n[1]*t[0]+n[3]*t[1],n[0]*t[2]+n[2]*t[3],n[1]*t[2]+n[3]*t[3],n[0]*t[4]+n[2]*t[5]+n[4],n[1]*t[4]+n[3]*t[5]+n[5]]}const kr=[1,0,0,1,0,0];function he(n){return n[0]===1&&n[1]===0&&n[2]===0&&n[3]===1&&n[4]===0&&n[5]===0}function xr(n,t){let e=0;const s=()=>{for(;e<t.length&&(t[e]===" "||t[e]===","||t[e]===`
|
|
8
|
+
`||t[e]===" "||t[e]==="\r");)e+=1},i=()=>{s();const b=e;for((t[e]==="+"||t[e]==="-")&&(e+=1);e<t.length&&t[e]>="0"&&t[e]<="9";)e+=1;if(t[e]===".")for(e+=1;e<t.length&&t[e]>="0"&&t[e]<="9";)e+=1;if(t[e]==="e"||t[e]==="E")for(e+=1,(t[e]==="+"||t[e]==="-")&&(e+=1);e<t.length&&t[e]>="0"&&t[e]<="9";)e+=1;const S=Number.parseFloat(t.slice(b,e));return Number.isFinite(S)?S:Number.NaN},o=()=>{s();const b=t[e];return b==="0"||b==="1"?(e+=1,b==="1"?1:0):Number.NaN},r=()=>{s();const b=t[e];return b!==void 0&&(b==="+"||b==="-"||b==="."||b>="0"&&b<="9")};let a=0,l=0,c=0,u=0,d=null,f=null,m=!1;const h=(b,S)=>{n.moveTo(b,S),a=b,l=S,c=b,u=S,m=!0},y=(b,S)=>{m?(n.lineTo(b,S),a=b,l=S):h(b,S)},g=(b,S,A,v,k,M)=>{m||h(a,l),n.bezierCurveTo(b,S,A,v,k,M),a=k,l=M};let w="";for(s();e<t.length;){const b=t[e];if(/[MmLlHhVvCcSsQqTtAaZz]/.test(b))w=b,e+=1;else{if(w==="")return;w==="M"?w="L":w==="m"&&(w="l")}const S=w===w.toLowerCase(),A=S?a:0,v=S?l:0;switch(w.toUpperCase()){case"Z":{n.closePath(),a=c,l=u,d=null,f=null,w="",s();continue}case"M":{h(A+i(),v+i()),d=null,f=null;break}case"L":{y(A+i(),v+i()),d=null,f=null;break}case"H":{y(A+i(),l),d=null,f=null;break}case"V":{y(a,v+i()),d=null,f=null;break}case"C":{const k=A+i(),M=v+i(),x=A+i(),$=v+i(),T=A+i(),C=v+i();g(k,M,x,$,T,C),d={x,y:$},f=null;break}case"S":{const k=d===null?a:2*a-d.x,M=d===null?l:2*l-d.y,x=A+i(),$=v+i(),T=A+i(),C=v+i();g(k,M,x,$,T,C),d={x,y:$},f=null;break}case"Q":{const k=A+i(),M=v+i(),x=A+i(),$=v+i();m||h(a,l),n.quadraticCurveTo(k,M,x,$),a=x,l=$,f={x:k,y:M},d=null;break}case"T":{const k=f===null?a:2*a-f.x,M=f===null?l:2*l-f.y,x=A+i(),$=v+i();m||h(a,l),n.quadraticCurveTo(k,M,x,$),a=x,l=$,f={x:k,y:M},d=null;break}case"A":{const k=i(),M=i(),x=i(),$=o(),T=o(),C=A+i(),O=v+i();if(Number.isNaN($)||Number.isNaN(T)||Number.isNaN(C)||Number.isNaN(O))return;m||h(a,l);for(const F of fe(a,l,k,M,x,$===1,T===1,C,O))n.bezierCurveTo(F[0],F[1],F[2],F[3],F[4],F[5]);a=C,l=O,d=null,f=null;break}default:return}if(Number.isNaN(a)||Number.isNaN(l)||(s(),!r()&&e<t.length&&!/[MmLlHhVvCcSsQqTtAaZz]/.test(t[e])))return}}function fe(n,t,e,s,i,o,r,a,l){let c=Math.abs(e),u=Math.abs(s);if(c===0||u===0)return[[n,t,a,l,a,l]];const d=i*Math.PI/180,f=Math.cos(d),m=Math.sin(d),h=(n-a)/2,y=(t-l)/2,g=f*h+m*y,w=-m*h+f*y,b=g*g/(c*c)+w*w/(u*u);if(b>1){const E=Math.sqrt(b);c*=E,u*=E}const S=o===r?-1:1,A=c*c*u*u-c*c*w*w-u*u*g*g,v=c*c*w*w+u*u*g*g,k=v===0?0:S*Math.sqrt(Math.max(0,A/v)),M=k*c*w/u,x=-k*u*g/c,$=f*M-m*x+(n+a)/2,T=m*M+f*x+(t+l)/2,C=(E,q)=>Math.atan2(q,E),O=C((g-M)/c,(w-x)/u);let P=C((-g-M)/c,(-w-x)/u)-O;!r&&P>0&&(P-=2*Math.PI),r&&P<0&&(P+=2*Math.PI);const H=Math.max(1,Math.ceil(Math.abs(P)/(Math.PI/2))),G=P/H,V=4/3*Math.tan(G/4),W=[],at=E=>[$+c*Math.cos(E)*f-u*Math.sin(E)*m,T+c*Math.cos(E)*m+u*Math.sin(E)*f],U=E=>[-c*Math.sin(E)*f-u*Math.cos(E)*m,-c*Math.sin(E)*m+u*Math.cos(E)*f];for(let E=0;E<H;E++){const q=O+E*G,mt=q+G,[Ms,Es]=at(q),[Me,Ee]=at(mt),[Ts,Cs]=U(q),[As,Ns]=U(mt);W.push([Ms+V*Ts,Es+V*Cs,Me-V*As,Ee-V*Ns,Me,Ee])}return W}function Sr(n,t,e){const i=new DOMParser().parseFromString(n,"image/svg+xml").documentElement;i===null||i.nodeName==="parsererror"||$r(i,t,e)}function $r(n,t,e){const s=Mr(n),i=br(n),o=Er(n);if(t.save(),e!==void 0&&s!==null&&s.width>0&&s.height>0){const r=e.width/s.width,a=e.height/s.height;(r!==1||a!==1)&&t.transform(r,0,0,a,0,0)}s!==null&&(s.x!==0||s.y!==0)&&t.transform(1,0,0,1,-s.x,-s.y),os(n,t,hr,i,o),t.restore()}function Mr(n){const t=n.getAttribute("viewBox");if(t!==null){const i=t.split(/[\s,]+/).filter(o=>o!=="").map(o=>Number.parseFloat(o));if(i.length===4&&i.every(o=>Number.isFinite(o)))return{x:i[0],y:i[1],width:i[2],height:i[3]}}const e=L(n.getAttribute("width"),Number.NaN),s=L(n.getAttribute("height"),Number.NaN);return!Number.isFinite(e)||!Number.isFinite(s)?null:{x:0,y:0,width:e,height:s}}function Er(n){const t=new Map;for(const e of Array.from(n.querySelectorAll("clipPath"))){const s=e.getAttribute("id");s!==null&&t.set(s,e)}return t}const Tr=new Set(["defs","style","clippath","lineargradient","radialgradient","title","desc","metadata","filter","mask","pattern","marker","symbol"]);function os(n,t,e,s,i){for(const o of Array.from(n.children)){const r=o.tagName.toLowerCase();if(Tr.has(r))continue;const a=ss(o,e,s),l=rs(o),c=as(o,i),u=!he(l)||c!==null;u&&t.save(),he(l)||t.transform(...l),c!==null&&ls(t,c,i),r==="g"||r==="a"||r==="svg"?os(o,t,a,s,i):Ar(o,r,t,a),u&&t.restore()}}function rs(n){const t=n.getAttribute("transform");return t===null||t===""?kr:vr(t)}function as(n,t){const e=n.getAttribute("clip-path")??Ut(n).get("clip-path")??null;if(e===null)return null;const s=/^url\(\s*['"]?#([^)'"]+)['"]?\s*\)$/.exec(e.trim());return s===null?null:t.get(s[1])??null}function ls(n,t,e){n.beginPath();let s=!1;for(const o of Array.from(t.children)){const r=rs(o);he(r)&&Et(o,o.tagName.toLowerCase(),n)&&(s=!0)}const i=as(t,e);i!==null&&ls(n,i,e),s&&n.clip()}function Et(n,t,e){switch(t){case"path":{const s=n.getAttribute("d");return s===null||s===""?!1:(xr(e,s),!0)}case"rect":{const s=L(n.getAttribute("x"),0),i=L(n.getAttribute("y"),0),o=L(n.getAttribute("width"),0),r=L(n.getAttribute("height"),0);if(!(o>0)||!(r>0))return!1;const a=Math.min(L(n.getAttribute("rx"),0),o/2),l=Math.min(L(n.getAttribute("ry"),a),r/2);return a>0&&l>0?Cr(e,s,i,o,r,a,l):e.rect(s,i,o,r),!0}case"circle":{const s=L(n.getAttribute("r"),0);return s>0?(e.moveTo(L(n.getAttribute("cx"),0)+s,L(n.getAttribute("cy"),0)),e.arc(L(n.getAttribute("cx"),0),L(n.getAttribute("cy"),0),s,0,Math.PI*2),!0):!1}case"ellipse":{const s=L(n.getAttribute("rx"),0),i=L(n.getAttribute("ry"),0);if(!(s>0)||!(i>0))return!1;const o=L(n.getAttribute("cx"),0),r=L(n.getAttribute("cy"),0);e.moveTo(o+s,r);for(const a of fe(o+s,r,s,i,0,!0,!0,o-s,r))e.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5]);for(const a of fe(o-s,r,s,i,0,!0,!0,o+s,r))e.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5]);return e.closePath(),!0}case"line":return e.moveTo(L(n.getAttribute("x1"),0),L(n.getAttribute("y1"),0)),e.lineTo(L(n.getAttribute("x2"),0),L(n.getAttribute("y2"),0)),!0;case"polyline":case"polygon":{const s=(n.getAttribute("points")??"").split(/[\s,]+/).filter(i=>i!=="").map(i=>Number.parseFloat(i));if(s.length<4)return!1;e.moveTo(s[0],s[1]);for(let i=2;i+1<s.length;i+=2)e.lineTo(s[i],s[i+1]);return t==="polygon"&&e.closePath(),!0}default:return!1}}function Cr(n,t,e,s,i,o,r){n.moveTo(t+o,e),n.lineTo(t+s-o,e),n.quadraticCurveTo(t+s,e,t+s,e+r),n.lineTo(t+s,e+i-r),n.quadraticCurveTo(t+s,e+i,t+s-o,e+i),n.lineTo(t+o,e+i),n.quadraticCurveTo(t,e+i,t,e+i-r),n.lineTo(t,e+r),n.quadraticCurveTo(t,e,t+o,e),n.closePath()}function Ar(n,t,e,s){if(t==="text"||t==="tspan"){cs(n,e,s);return}if(t==="image"||t==="use"||t==="foreignobject"||(e.beginPath(),!Et(n,t,e)))return;const i=s.fill===null?null:s.fillGradient;if(i===null){je(e,s);return}const o=()=>Lr(n,t,e,s,i),r=()=>{e.beginPath(),Et(n,t,e),je(e,{...s,fill:null})};s.strokeFirst?(r(),o()):(o(),r())}const Nr=100;function Lr(n,t,e,s,i){const o=Ir(n,t);if(o===null||i.stops.length===0)return;const r=i.units==="objectBoundingBox",a=(w,b)=>r?[o.x+w*o.width,o.y+b*o.height]:[w,b],l=r?[[0,0],[1,0],[1,1],[0,1]]:[[o.x,o.y],[o.x+o.width,o.y],[o.x+o.width,o.y+o.height],[o.x,o.y+o.height]],c=i.x2-i.x1,u=i.y2-i.y1,d=c*c+u*u,f=i.stops,m=f[0],h=f[f.length-1],y=s.opacity*s.fillOpacity,g=(w,b,S,A)=>{const v=P=>[i.x1+c*P,i.y1+u*P],k=-u/Math.sqrt(d),M=c/Math.sqrt(d);let x=0;for(const[P,H]of l)x=Math.max(x,Math.abs((P-i.x1)*k+(H-i.y1)*M));x+=1;const[$,T]=v(w),[C,O]=v(b),F=[a($+k*x,T+M*x),a(C+k*x,O+M*x),a(C-k*x,O-M*x),a($-k*x,T-M*x)];e.globalAlpha=y*A,e.fillStyle=`rgb(${S.map(P=>Math.round(yt(P)*255)).join(", ")})`,e.beginPath(),e.moveTo(F[0][0],F[0][1]);for(const[P,H]of F.slice(1))e.lineTo(P,H);e.closePath(),e.fill()};if(e.save(),e.beginPath(),Et(n,t,e),e.clip(),!(d>0))g(-1,1,h.rgb,h.opacity);else{let w=0,b=1;for(const[v,k]of l){const M=((v-i.x1)*c+(k-i.y1)*u)/d;w=Math.min(w,M),b=Math.max(b,M)}const S=[],A=v=>{const k=S[S.length-1];k!==void 0&&k.opacity===v.opacity&&k.rgb.every((x,$)=>x===v.rgb[$])?k.to=v.to:S.push(v)};w<m.offset&&A({from:w-.01,to:m.offset,rgb:m.rgb,opacity:m.opacity});for(let v=0;v+1<f.length;v++){const k=f[v],M=f[v+1],x=M.offset-k.offset;if(!(x>0))continue;const T=k.opacity===M.opacity&&k.rgb.every((C,O)=>C===M.rgb[O])?1:Math.max(1,Math.round(x*Nr));for(let C=0;C<T;C++){const O=(C+.5)/T;A({from:k.offset+x*C/T,to:k.offset+x*(C+1)/T,rgb:[0,1,2].map(F=>k.rgb[F]+(M.rgb[F]-k.rgb[F])*O),opacity:k.opacity+(M.opacity-k.opacity)*O})}}b>h.offset&&A({from:h.offset,to:b+.01,rgb:h.rgb,opacity:h.opacity}),S.forEach((v,k)=>{const M=y*v.opacity>=1&&k+1<S.length;g(v.from,M?v.to+(v.to-v.from)/2:v.to,v.rgb,v.opacity)})}e.restore(),e.globalAlpha=1}function Ir(n,t){let e=1/0,s=1/0,i=-1/0,o=-1/0;const r=(c,u)=>{e=Math.min(e,c),s=Math.min(s,u),i=Math.max(i,c),o=Math.max(o,u)},a=()=>{};return!Et(n,t,{beginPath:a,closePath:a,moveTo:r,lineTo:r,rect:(c,u,d,f)=>{r(c,u),r(c+d,u+f)},arc:(c,u,d)=>{r(c-d,u-d),r(c+d,u+d)},bezierCurveTo:(c,u,d,f,m,h)=>{r(c,u),r(d,f),r(m,h)},quadraticCurveTo:(c,u,d,f)=>{r(c,u),r(d,f)}})||!(i>e)||!(o>s)?null:{x:e,y:s,width:i-e,height:o-s}}function je(n,t,e){const s=t.stroke!==null&&t.strokeWidth>0,i=()=>{t.fill!==null&&(n.globalAlpha=t.opacity*t.fillOpacity,n.fillStyle=t.fill,n.fill())},o=()=>{s&&(n.globalAlpha=t.opacity*t.strokeOpacity,n.strokeStyle=t.stroke,n.lineWidth=t.strokeWidth,n.lineJoin=t.lineJoin,n.lineCap=t.lineCap,n.setLineDash(t.dash),n.stroke())};t.strokeFirst?(o(),i()):(i(),o()),n.globalAlpha=1,n.setLineDash([])}function cs(n,t,e){const s=Array.from(n.children).filter(o=>o.tagName.toLowerCase()==="tspan"),i=s.length>0?"":n.textContent??"";if(i.trim()!==""){const o=L(n.getAttribute("x"),0)+L(n.getAttribute("dx"),0),r=L(n.getAttribute("y"),0)+L(n.getAttribute("dy"),0);t.font=Or(e),t.textAlign=e.anchor,t.textBaseline=e.baseline;const a=e.stroke!==null&&e.strokeWidth>0,l=()=>{e.fill!==null&&(t.globalAlpha=e.opacity*e.fillOpacity,t.fillStyle=e.fill,t.fillText(i,o,r))},c=()=>{a&&(t.globalAlpha=e.opacity*e.strokeOpacity,t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.lineJoin=e.lineJoin,t.setLineDash([]),t.strokeText(i,o,r))};e.strokeFirst?(c(),l()):(l(),c()),t.globalAlpha=1}for(const o of s)cs(o,t,ss(o,e,new Map))}function Or(n){const t=n.fontStyle!=="normal"?`${n.fontStyle} `:"",e=n.fontWeight!=="normal"?`${n.fontWeight} `:"";return`${t}${e}${n.fontSize}px ${n.fontFamily}`}const Qe=1/12;function Fr(n,t){return{x:n.right-n.left>=Math.max(1,t.width)*Qe,y:n.bottom-n.top>=Math.max(1,t.height)*Qe}}function Pr(n){return n.metaKey||n.ctrlKey}function Br(n){const{host:t}=n;if(typeof window>"u")return{destroy:()=>{}};const e=p("div",{class:"figure-marquee hidden"});t.appendChild(e);let s=null,i=null;const o=h=>{const y=t.getBoundingClientRect();return{x:h.clientX-y.left,y:h.clientY-y.top}},r=h=>({left:Math.min(s?.x??h.x,h.x),right:Math.max(s?.x??h.x,h.x),top:Math.min(s?.y??h.y,h.y),bottom:Math.max(s?.y??h.y,h.y)}),a=h=>{e.classList.remove("hidden"),e.style.left=`${h.left}px`,e.style.top=`${h.top}px`,e.style.width=`${Math.max(0,h.right-h.left)}px`,e.style.height=`${Math.max(0,h.bottom-h.top)}px`},l=()=>{e.classList.add("hidden"),s=null,i=null},c=h=>{!Pr(h)||h.button!==0||n.chart()!==null&&(h.preventDefault(),h.stopPropagation(),s=o(h),i=h.pointerId,t.setPointerCapture?.(h.pointerId))},u=h=>{s===null||h.pointerId!==i||(h.preventDefault(),h.stopPropagation(),a(r(o(h))))},d=h=>{if(s===null||h.pointerId!==i)return;h.preventDefault(),h.stopPropagation();const y=r(o(h));l(),t.hasPointerCapture?.(h.pointerId)===!0&&t.releasePointerCapture?.(h.pointerId);const g=Fr(y,{width:t.clientWidth,height:t.clientHeight});!g.x&&!g.y||n.onZoom(y,g)},f=h=>{h.pointerId===i&&l()},m=()=>n.onReset();return t.addEventListener("pointerdown",c,!0),t.addEventListener("pointermove",u,!0),t.addEventListener("pointerup",d,!0),t.addEventListener("pointercancel",f,!0),t.addEventListener("dblclick",m),{destroy(){t.removeEventListener("pointerdown",c,!0),t.removeEventListener("pointermove",u,!0),t.removeEventListener("pointerup",d,!0),t.removeEventListener("pointercancel",f,!0),t.removeEventListener("dblclick",m),e.remove()}}}function Je(n,t,e,s,i){const o=u=>{const d=i?[n.getWidth()/2,u]:[u,n.getHeight()/2],f=n.convertFromPixel({gridIndex:0},d),m=Array.isArray(f)?f[i?1:0]:null;if(typeof m=="number"&&Number.isFinite(m))return m;const h=n.convertFromPixel(t,u),y=Array.isArray(h)?h[i?1:0]:h;return typeof y=="number"&&Number.isFinite(y)?y:null},r=o(e),a=o(s);if(r===null||a===null)return null;const[l,c]=r<=a?[r,a]:[a,r];return l<c?[l,c]:null}let bt=null,tn=null;async function qr(){bt===null&&(tn??=Ys(()=>import("./echartsBundle-Dqa1ruUg.js"),[],import.meta.url).then(n=>{bt=n.echarts}),await tn)}function me(n){const t=Us(n),e=/\d+(?:\.\d+)?px\s+(.*)$/.exec(t.font)?.[1]??"system-ui, sans-serif";return{ink:t.ink,muted:t.muted,grid:t.grid,background:t.background,series:t.series,fontFamily:e,measure:(s,i)=>{const o=Rr();return o===null?s.length*i*.6:(o.font=`${i}px ${e}`,o.measureText(s).width)}}}function zr(n){const t=n??{},e=[t,...t.batch??[]].map(s=>s.dataZoomId).filter(s=>typeof s=="string");return e.length===0?null:new Set(e)}let Qt;function Rr(){return Qt===void 0&&(Qt=document.createElement("canvas").getContext("2d")),Qt}function _r(n){return Math.max(260,Math.min(520,Math.round(n*.78)))}function Jt(n){const t=p("div",{class:n.fill===!0?"figure-chart figure-chart-fill":"figure-chart"});let e=n.style,s=null,i=n.fill===!0,o=0,r=0,a=!1,l=!1,c=null,u={x:n.style.x.domain,y:n.style.y.domain};const d=(x,$=t)=>n.spec.kind==="matrix"?ur(n.spec.output,e,me($),x):jo(n.spec,e,me($),x),f=()=>i?t.clientHeight:_r(o),m=()=>{s!==null||o<=0||bt===null||(r=f(),!(r<=0)&&(s=bt.init(t,null,{renderer:"svg",width:o,height:r}),s.on("legendselectchanged",x=>{const $=n.spec;if($.kind==="matrix")return;const T=x.selected;if(T===void 0)return;const C=$.series.filter(O=>T[O.name]===!1).map(O=>O.id);e={...e,hidden:C},n.onStyle?.(e)}),s.on("dataZoom",x=>{if(l||s===null)return;const $=s.getOption().dataZoom;if($===void 0)return;const T=G=>{if(G===void 0)return null;const V=G.startValue,W=G.endValue;return typeof V!="number"||typeof W!="number"||!Number.isFinite(V)||!Number.isFinite(W)||V>=W?null:[V,W]},C=zr(x),O=C===null||C.has(xe),F=C===null||C.has(Se),P=e.x.domain;e={...e,x:O?{...e.x,domain:T($[0])??e.x.domain}:e.x,y:F?{...e.y,domain:T($[1])??e.y.domain}:e.y};const H=n.spec;if(H.kind!=="matrix"){const G=U=>({showMinLabel:U.labels.showMinLabel??null,showMaxLabel:U.labels.showMaxLabel??null,customValues:U.ticks??null}),V=Dt(H,e,"x"),W=Dt(H,e,"y"),at=e.y.domain===null&&e.x.domain!==P;l=!0,s.setOption({xAxis:{axisLabel:G(V),axisTick:{customValues:V.ticks??null}},yAxis:{...at?{min:W.bounds.min??null,max:W.bounds.max??null}:{},axisLabel:G(W),axisTick:{customValues:W.ticks??null}}}),l=!1}n.onStyle?.(e)}),g()))},h=(x,$)=>{if(s===null)return;const T={...e};if($.x){const C=Je(s,{xAxisIndex:0},x.left,x.right,!1);C!==null&&(T.x={...T.x,domain:C})}if($.y){const C=Je(s,{yAxisIndex:0},x.top,x.bottom,!0);C!==null&&(T.y={...T.y,domain:C})}T.x.domain===e.x.domain&&T.y.domain===e.y.domain||(e=T,g(),n.onStyle?.(e))},y=()=>{e.x.domain===u.x&&e.y.domain===u.y||(e={...e,x:{...e.x,domain:u.x},y:{...e.y,domain:u.y}},g(),n.onStyle?.(e))},g=()=>{s!==null&&(l=!0,s.setOption(d({width:o,height:r}),!0),l=!1)},w=()=>{if(o<=0)return;if(s===null){m();return}const x=f();x<=0||(r=x,s.resize({width:o,height:r}),(n.spec.kind==="matrix"||e.legend==="right")&&g())},b=typeof ResizeObserver>"u"?null:new ResizeObserver(x=>{const $=x[0]?.contentRect,T=$?.width??0;Math.abs(T-o)<.5&&(!i||Math.abs(($?.height??0)-r)<.5)&&s!==null||(o=T,w())});b?.observe(t);const S=window.matchMedia?.("(prefers-color-scheme: dark)"),A=()=>g(),v=typeof MutationObserver>"u"?null:new MutationObserver(A);v?.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),S?.addEventListener?.("change",A);const k=Ks(()=>g()),M=qr().then(()=>{a||typeof document>"u"||(o>0&&m(),c??=Br({host:t,chart:()=>s,onZoom:h,onReset:y}))},()=>{a||typeof document>"u"||t.replaceChildren(p("p",{class:"hint",text:"The chart library did not load. Check the connection and reopen this result."}))});return{el:t,ready:M,draw(x,$){if(bt===null)throw new Error("the chart library has not arrived yet");const T=document.createElement("div");T.style.cssText=`position:absolute;left:-10000px;top:0;width:${$.width}px;height:${$.height}px`,t.appendChild(T);const C=bt.init(T,null,{renderer:"svg",width:$.width,height:$.height});try{C.setOption(Ko(d($,Zs())),!0),Sr(C.renderToSVGString(),x,$)}finally{C.dispose(),T.remove()}},update(x){e=x,u={x:x.x.domain,y:x.y.domain},g()},setFill(x){i!==x&&(i=x,t.classList.toggle("figure-chart-fill",x),w())},current(){return e},destroy(){a=!0,c?.destroy(),c=null,b?.disconnect(),v?.disconnect(),S?.removeEventListener?.("change",A),k(),s?.dispose(),s=null}}}const en=24;function Dr(n){const t=p("div",{class:"controls-card figure-settings"}),e=i=>{n.onChange({...n.style(),...i})},s=()=>{const i=n.style(),o=n.spec.kind==="xy"?[Gr(n.spec,i,e),ds(n.spec,i,e),Yr(n.spec,i,e,n.theme()),Ot(i,e)]:n.spec.kind==="matrix"?n.spec.output.streaks!==void 0?[Ot(i,e,Vt(n.spec.output))]:[Zr(i,e),Ot(i,e,Vt(n.spec.output))]:[Xr(n.spec,i,e),...Kr(n.spec,i,e),Ot(i,e)];t.replaceChildren(Mn("Figure","chart-line","controls-title"),p("div",{class:"panel-controls"},...o,p("div",{class:"figure-actions"},I("reset",()=>n.onReset(),{class:"btn btn-quiet",title:"Back to the figure the task returned, and forget what was set here"}),...n.exports??[])))};return s(),{el:t,refresh:s}}function vt(n,...t){return p("div",{class:"figure-group"},p("h4",{class:"figure-group-head",text:n}),...t.filter(e=>e!==!1))}function ot(n,t,e,s){const i=p("select",{class:"select"});for(const o of n){const r=p("option",{value:o,text:o}),a=s?.[o];a!==void 0&&(r.title=a),i.appendChild(r)}return i.value=t,i.addEventListener("change",()=>e(i.value)),i}function rt(n,t,e,s){const i=`figure-toggle-${Wr+=1}`,o=I(t?"on":"off",()=>e(!t),{class:"btn btn-toggle",title:s});return o.setAttribute("aria-pressed",String(t)),o.setAttribute("aria-labelledby",i),p("div",{class:"field ann-field figure-check"},p("span",{class:"field-label",text:n,id:i,title:s}),o)}function Vr(n,t,e,s){const i=I(n,()=>e(!t),{class:"btn btn-toggle",title:s});return i.setAttribute("aria-pressed",String(t)),i}let Wr=0;function ht(n,t,e,s){const i=p("input",{class:"input input-num",type:"number",title:e,placeholder:"auto"});i.value=n===null?"":qt(n,6),s!==void 0&&(i.step=String(s));const o=()=>{const r=i.value.trim();if(r===""){t(null);return}const a=Number(r);t(Number.isFinite(a)?a:null)};return i.addEventListener("change",o),i}function $e(n,t,e,s){const i=p("input",{class:"input",type:"text",title:e,placeholder:s});return i.value=n,i.addEventListener("change",()=>t(i.value)),i}const us={line:"Joined samples — a claim that something is between them",area:"A line with the space under it filled",step:"Held between samples, for a quantity that changes at them",points:"One mark per sample and nothing between, for an x that is not an ordering",bars:"One bar per sample",histogram:"The y values counted into bins; x is ignored",box:"Quartiles and Tukey whiskers per series; x is ignored",violin:"A kernel density per series, every violin to one scale; x is ignored"};function Gr(n,t,e){const s=[...Tn,...En],i=n.series.some(r=>r.low!==void 0),o=t.mark==="line"||t.mark==="area"||t.mark==="step";return vt("chart",_("mark",ot(s,t.mark,r=>e({mark:r}),us)),o&&_("line width",ht(t.lineWidth,r=>e({lineWidth:r??1.8}),"In CSS pixels",.25)),(t.mark==="points"||t.jitter||t.mark==="box")&&_("point size",ht(t.pointSize,r=>e({pointSize:r??6}),"In CSS pixels",1)),o&&rt("smooth",t.smooth,r=>e({smooth:r}),"A curve through the samples rather than straight segments — a claim about what is between them"),o&&rt("fill under",t.fillArea,r=>e({fillArea:r}),"Shade the space between the line and the axis"),i&&rt("band",t.bands,r=>e({bands:r}),"The spread the task computed, drawn around each line"),t.mark==="histogram"&&_("bins",ht(t.bins===0?null:t.bins,r=>e({bins:r===null?0:Math.round(r)}),"Empty chooses the width from the data (Freedman–Diaconis)",1)),(t.mark==="box"||t.mark==="violin")&&rt("points",t.jitter,r=>e({jitter:r}),"Every observation beside the summary, so a summary of six points does not read like one of six thousand"))}function Hr(n,t,e,s){const i=ke(n,t,e);if(i!==null)return i[s];const o=t[e].scale==="log",r=t.mark==="histogram";let a=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY;for(const c of n.series){if(t.hidden.includes(c.id))continue;const u=r?Yt(c.y,t.bins):null,d=u!==null?e==="x"?u.edges:[0,...u.counts]:e==="x"?c.y.map((f,m)=>c.x[m]??m):c.y;for(const f of d)!Number.isFinite(f)||o&&f<=0||(f<a&&(a=f),f>l&&(l=f))}return a>l?null:s===0?a:l}function nn(n,t,e,s){const i=e[n],o=l=>s({[n]:{...i,...l}}),r=i.domain,a=l=>ht(r===null?null:r[l],c=>{if(c===null){o({domain:null});return}const u=r===null?Hr(t,e,n,l===0?1:0):r[l===0?1:0];if(u===null)return;const d=l===0?[c,u]:[u,c];o({domain:d[0]<d[1]?d:null})},l===0?"The low end of the window; empty fits the data":"The high end of the window; empty fits the data");return[_(`${n} scale`,ot(["linear","log"],i.scale,l=>o({scale:l}),{log:"A log axis has no place for a zero: values at or below it become gaps"})),_(`${n} name`,$e(i.label??"",l=>o({label:l===""?null:l}),"What the axis is called; empty is the task’s own name",n==="x"?t.xLabel:t.yLabel)),p("div",{class:"field ann-field figure-range"},p("span",{class:"field-label",text:`${n} from`}),a(0),p("span",{class:"field-label",text:"to"}),a(1)),rt(`${n} grid`,i.grid,l=>o({grid:l}),"Rules across the plot at the ticks")]}function Kr(n,t,e){const s=t.plot;return s===null||s.x===null?[]:[ds(Cn(n,s.x,s.y,s.mark,s.fit,t.x.domain),t,e)]}function ds(n,t,e){return vt("axes",...nn("x",n,t,e),...nn("y",n,t,e),p("div",{class:"figure-actions"},I("fit",()=>e({x:{...t.x,domain:null},y:{...t.y,domain:null}}),{class:"btn btn-quiet",title:"Both axes back to the whole of the data"})))}function Yr(n,t,e,s){const i=n.series.slice(0,en).map((r,a)=>{const l=t.hidden.includes(r.id),c=et(l?"eye-off":"eye",l?`Show ${r.name}`:`Hide ${r.name}`,()=>e({hidden:l?t.hidden.filter(d=>d!==r.id):[...t.hidden,r.id]}),{class:"btn btn-icon btn-toggle ann-eye",size:13});c.setAttribute("aria-pressed",String(!l));const u=p("input",{class:"figure-swatch",type:"color"});return u.value=jr(Zn(r,a,t,s)),u.title=`The colour of ${r.name}`,u.addEventListener("change",()=>e({colours:{...t.colours,[r.id]:u.value}})),p("div",{class:"figure-series-row"},c,u,p("span",{class:"figure-series-name",text:r.name,title:r.name}),r.n===void 0||!Number.isFinite(r.n)?p("span"):p("span",{class:"figure-series-n",text:`n = ${r.n}`}))}),o=n.series.length-i.length;return vt("series",p("div",{class:"figure-series"},...i),o>0&&p("p",{class:"hint",text:`…and ${o} more, all of them drawn. Only the first ${en} are listed.`}),p("div",{class:"figure-actions"},I("show all",()=>e({hidden:[]}),{class:"btn btn-quiet",title:"Every series back on the picture"}),I("reset colours",()=>e({colours:{}}),{class:"btn btn-quiet",title:"Back to the task’s own colours and the palette"})))}const Ur=["right","top","bottom","none"];function Ot(n,t,e=!0){return vt("text",_("title",$e(n.title??"",s=>t({title:s===""?null:s}),"Printed on the figure itself, so it survives the export; empty is no title","none")),_("type size",ht(n.fontSize,s=>t({fontSize:s??11}),"In CSS pixels, for every word on the figure",1)),_("legend",ot(Ur,n.legend,s=>t({legend:s}))),...e?[rt("tooltip",n.tooltip,s=>t({tooltip:s}),"The readout that follows the pointer")]:[])}function Zr(n,t){const e=["auto",...Xs];return vt("colour",_("colormap",ot(e,n.colormap??"auto",s=>t({colormap:s==="auto"?null:s}))),p("div",{class:"field ann-field figure-range"},p("span",{class:"field-label",text:"scale"}),ht(n.vmin,s=>t({vmin:s}),"The value the lowest colour means; empty fits the data"),p("span",{class:"field-label",text:"to"}),ht(n.vmax,s=>t({vmax:s}),"The value the highest colour means; empty fits the data")))}function Xr(n,t,e){const s=js(n),i=[...s,...Qs(n)],o=t.plot,r=n.columns.map(l=>l.key),a=t.columns??r;return vt("rows",_("filter",$e(t.filter,l=>e({filter:l}),"Rows whose text contains this, anywhere","every row")),_("sort by",ot(["—",...r],t.sortKey??"—",l=>e({sortKey:l==="—"?null:l}))),t.sortKey!==null&&rt("descending",t.sortDown,l=>e({sortDown:l}),"Largest or last first"),p("div",{class:"figure-columns"},...n.columns.map(l=>{const c=a.includes(l.key);return Vr(l.label,c,u=>e({columns:u?r.filter(d=>a.includes(d)||d===l.key):a.filter(d=>d!==l.key)}),l.hint??`Show the ${l.label} column`)})),s.length>0&&_("plot",ot(["table",...s.map(l=>l.key)],o===null?"table":o.y,l=>e({plot:l==="table"?null:{x:o?.x??null,y:l,mark:o?.mark??"histogram",fit:o?.fit??!1}})),"A column drawn instead of the rows: its distribution on its own, or against another column"),o!==null&&_("against",ot(["—",...i.map(l=>l.key)],o.x??"—",l=>e({plot:{...o,x:l==="—"?null:l,mark:l==="—"?"histogram":"points"}})),"The abscissa; on its own the column is drawn as a distribution. A column of names is read at the first number in each, and a row whose name has none is left out"),o!==null&&o.x!==null&&rt("least squares",o.fit,l=>e({plot:{...o,fit:l}}),"The straight line fitted through the points, its equation, r² and n in the legend"),o!==null&&_("as",ot(o.x===null?En:Tn,o.mark,l=>e({plot:{...o,mark:l}}),us)))}function jr(n){const t=n.trim();if(/^#[0-9a-f]{6}$/i.test(t))return t;const e=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(t);if(e!==null)return`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`;const s=/^#([0-9a-f]{6})[0-9a-f]{2}$/i.exec(t);if(s!==null)return`#${s[1]}`;const i=/^rgba?\(([^)]+)\)$/i.exec(t);if(i!==null){const o=i[1].split(/[,/\s]+/).filter(a=>a!==""),r=a=>{const l=Math.round(Number.parseFloat(o[a]??"0"));return(Number.isFinite(l)?Math.max(0,Math.min(255,l)):0).toString(16).padStart(2,"0")};return`#${r(0)}${r(1)}${r(2)}`}return"#000000"}const Qr="figure:side";function sn(n){const t=Js(n.output);if(t===null)throw new Error("this output is not a figure");return Jr(t,n)}function Jr(n,t){let e=ti(t.uri,t.task,n),s=null,i=null,o=d(n,e);const r=p("div",{class:"figure-body"},o.el),a=p("div",{class:"figure-strip"}),l=p("div",{class:"analysis-figure-head"}),c=p("div",{class:"analysis-figure figure-block"},l,a,r),u=()=>"update"in o?o:null;function d(v,k){const M=s!==null;if(v.kind==="matrix"&&v.output.streaks!==void 0){const x=ei(v.output.streaks);return x.setFill?.(M),x}if(v.kind==="matrix"){const x=Vt(v.output)?v.output:na(v,k);return Vt(x)?Jt({spec:{...v,output:x},style:rn(v,k),onStyle:$=>f($),fill:M}):ni(x)}if(v.kind==="table"){const x=hs(v,k);return x===null?Wi(v,k,($,T)=>m({sortKey:$,sortDown:T})):Jt({spec:x.spec,style:x.style,onStyle:$=>f($),fill:M})}return Jt({spec:v,style:k,onStyle:x=>f(x),fill:M})}function f(v){const k=e;e=v,Ae(t.uri,t.task,n.id,e),i?.refresh(),g(),fs(n,k,e)&&setTimeout(()=>{h(),w()},0)}function m(v){const k=e;e={...e,...v},Ae(t.uri,t.task,n.id,e);const M=u();M!==null&&ta(n,k,e)?M.update(rn(n,e)):n.kind==="matrix"&&n.output.streaks!==void 0||h(),i?.refresh(),g(),w()}function h(){const v=d(n,e);(o.el.parentElement??r).replaceChild(v.el,o.el),o.destroy(),o=v}function y(){oi(t.uri,t.task,n.id),e=ri(n),h(),i?.refresh(),g(),w()}function g(){const v=[];if(n.kind==="xy"){const k=p("select",{class:"select select-tight"});for(const M of["line","area","step","points","bars","histogram","box","violin"])k.appendChild(p("option",{value:M,text:M}));k.value=e.mark,k.title="How the series are drawn",k.addEventListener("change",()=>m({mark:k.value})),v.push(k),v.push(an("x",e,m),an("y",e,m),ea("list",e.legend!=="none","legend",()=>m({legend:e.legend==="none"?"right":"none"})),I("fit",()=>m({x:{...e.x,domain:null},y:{...e.y,domain:null}}),{class:"btn btn-quiet",title:"Both axes back to the whole of the data — the wheel zooms, this undoes it"}))}else if(!(n.kind==="matrix"&&n.output.streaks!==void 0))if(n.kind==="matrix"){const k=p("select",{class:"select select-tight"});k.appendChild(p("option",{value:"",text:"auto"}));const M=te.includes(e.colormap??"")?te:[...e.colormap===null?[]:[e.colormap],...te];for(const x of M)k.appendChild(p("option",{value:x,text:x}));k.value=e.colormap??"",k.title="The colours the values are drawn in",k.addEventListener("change",()=>m({colormap:k.value===""?null:k.value})),v.push(k)}else{const k=p("input",{class:"input input-tight",type:"search",placeholder:"filter rows",value:e.filter});k.title="Rows whose text contains this, anywhere",k.addEventListener("change",()=>m({filter:k.value})),v.push(k)}a.replaceChildren(...v)}function w(){const v=on(o);l.replaceChildren(p("span",{class:"analysis-figure-title",text:e.title??t.output.label}),...t.extras??[],...v===null||t.onPng===void 0?[]:[I("PNG",()=>t.onPng?.(v),{class:"btn",title:"The figure as a raster, redrawn at 300 dpi"})],...v===null||t.onPdf===void 0?[]:[I("PDF",()=>t.onPdf?.(v),{class:"btn",title:"The figure as a true vector page — restylable, recolourable, scalable"})],...v===null||t.onCopy===void 0?[]:[I("Copy",()=>t.onCopy?.(v),{class:"btn",title:"The figure as a raster at 300 dpi, onto the clipboard — the PNG, to paste"})],et("sliders-horizontal","Customise this figure",()=>b(),{class:"btn btn-icon figure-enlarge",size:14}))}function b(){if(s!==null)return;const v=A();s=ii({title:e.title??t.output.label,stage:o.el,side:v.el,memoryKey:()=>t.uri,scope:Qr,onResize:()=>S(!0),onClose:()=>{s=null,S(!1),r.replaceChildren(o.el),w()}}),S(!0)}function S(v){u()?.setFill(v),o.setFill?.(v)}function A(){return i===null&&(i=Dr({spec:n,style:()=>e,onChange:v=>m(v),onReset:()=>y(),theme:()=>me(c)})),i.refresh(),i}return g(),w(),{el:c,drawable:()=>on(o),ready:()=>"ready"in o?o.ready:Promise.resolve(),destroy(){s?.close(),o.destroy()}}}function on(n){return"draw"in n?n:null}function ta(n,t,e){return n.kind==="matrix"?!0:n.kind==="table"?t.plot===null||e.plot===null?t.plot===e.plot:t.plot.x===e.plot.x&&t.plot.y===e.plot.y&&t.plot.fit===e.plot.fit&&!fs(n,t,e):!0}function hs(n,t){const e=t.plot;if(e===null)return null;const s=e.x===null?si(n,e.y,e.mark):Cn(n,e.x,e.y,e.mark,e.fit,t.x.domain);return{spec:s,style:{...t,mark:e.mark,legend:s.series.length>1?t.legend==="none"?"none":"top":"none"}}}function rn(n,t){return n.kind==="table"?hs(n,t)?.style??t:n.kind==="matrix"?{...t,legend:"none"}:t}function fs(n,t,e){if(n.kind!=="table"||e.plot===null||!e.plot.fit||e.plot.x===null)return!1;const s=t.x.domain,i=e.x.domain;return s===null||i===null?s!==i:s[0]!==i[0]||s[1]!==i[1]}const te=["fall","viridis","magma","seismic","coolwarm","bwr"];function an(n,t,e){const s=t[n],i=s.scale==="log",o=I(`log ${n}`,()=>e({[n]:{...s,scale:i?"linear":"log"}}),{class:"btn btn-toggle",title:i?`A linear ${n} axis`:`A log ${n} axis — values at or below zero become gaps`});return o.setAttribute("aria-pressed",String(i)),o}function ea(n,t,e,s){const i=et(n,t?`Hide the ${e}`:`Show the ${e}`,s,{class:"btn btn-icon btn-toggle",size:13});return i.setAttribute("aria-pressed",String(t)),i}function na(n,t){const e={...n.output};if(t.colormap!==null&&(e.colormap=t.colormap),t.vmin===null&&t.vmax===null)return e;let s=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const a of n.output.values)Number.isFinite(a)&&(a<s&&(s=a),a>i&&(i=a));const o=t.vmin??(Number.isFinite(s)?s:0),r=t.vmax??(Number.isFinite(i)?i:1);return o<r&&(e.range=[o,r]),e}const ln="10.1093/bioinformatics/btae088",Ft="10.1371/journal.pcbi.1012067",cn="10.1093/nar/gkw257",sa={coverage:{method:"Coverage as cooltools computes it (Open2C 2024).",doi:Ft,agreement:"identical",section:9},cistrans:{method:"Cis and trans sums as cooltools’ expected_cis and expected_trans make them (Open2C 2024).",doi:Ft,agreement:"identical",section:20},cellqc:{method:"The near and mitotic contact shares of Nagano et al. 2017.",doi:"10.1038/nature23001",agreement:"untested"},expected:{method:"The expected contact by separation, as cooltools’ expected_cis computes it (Open2C 2024).",doi:Ft,agreement:"identical",section:4},pairsqc:{method:"The pairs’ statistics and fragments, as pairtools’ stats and restrict count them (Open2C 2024).",doi:"10.1371/journal.pcbi.1012164",agreement:"identical",section:27},scalogram:{method:"The scalogram of Lioy et al. 2018.",doi:"10.1016/j.cell.2017.12.027",agreement:"untested"},fourc:{method:"Virtual 4C as cooltools’ virtual4c computes it (Open2C 2024).",doi:Ft,agreement:"identical",section:10},insulation:{method:"Diamond insulation (Crane et al. 2015), as cooltools computes it.",doi:"10.1038/nature14450",agreement:"identical",section:1},di:{method:"The directionality index of Dixon et al. 2012, as domaincaller computes it.",doi:"10.1038/nature11082",agreement:"identical",section:2},hicscore:{method:"The HiC score of Bignaud et al. 2024, after their R script.",doi:"10.1038/s41594-023-01178-2",agreement:"untested"},compartments:{method:"The first eigenvector (Lieberman-Aiden et al. 2009), as cooltools’ eigs_cis takes it.",doi:"10.1126/science.1181369",agreement:"equivalent",section:3},loops:{method:"HiCCUPS (Rao et al. 2014), as cooltools.dots computes it.",doi:"10.1016/j.cell.2014.11.021",agreement:"identical",section:19},chromosight:{method:"Chromosight’s template matching (Matthey-Doret et al. 2020).",doi:"10.1038/s41467-020-19562-7",agreement:"identical",section:6},hicrep:{method:"HiCRep’s stratum-adjusted correlation (Yang et al. 2017).",doi:"10.1101/gr.220640.117",agreement:"identical",section:7},apa:{method:"Coolpup.py’s pile-ups (Flyamer et al. 2020), and chromosight’s score.",doi:"10.1093/bioinformatics/btaa073",agreement:"identical",section:11},reconstruct3d:{method:"pastis-NB, a negative binomial fit (Varoquaux et al. 2023).",doi:"10.1093/bioinformatics/btac838",agreement:"equivalent",section:8},motif:{method:"A motif scan as seqkit locate makes it (Shen et al. 2016).",doi:"10.1371/journal.pone.0163962",agreement:"identical",section:17},restriction:{method:"Restriction sites as bioframe’s digest finds them, each 2 bp earlier (Open2C 2024).",doi:ln,agreement:"identical",section:26},peaks:{method:"yapc’s concave regions (Jänes et al. 2018), with IDR across replicates.",doi:"10.7554/eLife.37344",agreement:"identical",section:5},composition:{method:"GC content and skews, as bioframe and Biopython compute them (Open2C 2024).",doi:ln,agreement:"identical",section:16},metaplot:{method:"deepTools’ computeMatrix and plotProfile (Ramírez et al. 2016).",doi:cn,agreement:"identical",section:14},trackcorr:{method:"deepTools’ multiBigwigSummary and plotCorrelation (Ramírez et al. 2016), on exact window means.",doi:cn,agreement:"equivalent",section:18},frip:{method:"FRiP, as the ENCODE guidelines define it (Landt et al. 2012).",doi:"10.1101/gr.136184.111",agreement:"identical",section:22},groupsignal:{method:"Mann–Whitney and Kruskal–Wallis tests as SciPy computes them (Virtanen et al. 2020).",doi:"10.1038/s41592-019-0686-2",agreement:"identical",section:23},overlap:{method:"bedtools’ intersect and jaccard, with a shuffle null (Quinlan and Hall 2010).",doi:"10.1093/bioinformatics/btq033",agreement:"identical",section:15}};function ia(n){return sa[n]??null}function oa(n){return n.agreement!=="untested"}const ra=180,ee=4,un=8,aa=16,ms={identical:"Identical in the validation",equivalent:"Equivalent in the validation",untested:"Not validated yet"};let Z=null,Tt=null,nt=null;function zt(){nt!==null&&clearTimeout(nt),nt=null,Tt=null,Z?.classList.add("hidden")}function ps(){nt!==null&&clearTimeout(nt),nt=setTimeout(zt,ra)}function gs(){nt!==null&&clearTimeout(nt),nt=null}function la(){return Z!==null&&Z.isConnected||(Z=p("div",{class:"task-ref-tip hidden",attrs:{role:"tooltip"}}),Z.addEventListener("pointerenter",gs),Z.addEventListener("pointerleave",ps),document.body.appendChild(Z),document.addEventListener("pointerdown",n=>{const t=n.target;Z?.contains(t)===!0||Tt?.contains(t)===!0||zt()},!0),document.addEventListener("scroll",()=>zt(),!0),document.addEventListener("keydown",n=>{n.key==="Escape"&&Tt!==null&&zt()})),Z}function ca(n,t){n.replaceChildren(p("p",{class:"task-ref-method",text:t.method}),p("p",{class:"task-ref-status"},`${ms[t.agreement]} · `,p("a",{text:`doi:${t.doi}`,attrs:{href:`https://doi.org/${t.doi}`,target:"_blank",rel:"noopener noreferrer"}})))}function ua(n,t){const e=t.getBoundingClientRect(),s=document.documentElement.clientWidth;n.style.right=`${Math.max(un,s-e.right)}px`,n.style.left="auto";const i=window.innerHeight-e.bottom;i>=n.offsetHeight+ee+un||i>=e.top?(n.style.top=`${e.bottom+ee}px`,n.style.bottom="auto"):(n.style.top="auto",n.style.bottom=`${window.innerHeight-e.top+ee}px`)}function dn(n,t){gs();const e=la();Tt!==n&&ca(e,t),Tt=n,e.classList.remove("hidden"),ua(e,n)}function da(n){const t=`${n.method} ${ms[n.agreement]}.`,e=p("span",{class:`task-ref${oa(n)?" is-validated":""}`,title:"",attrs:{role:"img","aria-label":t}},ie("circle-question-mark",{size:aa}));return e.addEventListener("pointerenter",()=>dn(e,n)),e.addEventListener("pointerleave",ps),e.addEventListener("mousedown",s=>s.preventDefault()),e.addEventListener("click",s=>{s.stopPropagation(),dn(e,n)}),e}const ha={"2d":"grid-2x2","3d":"box","1d":"chart-line",metagenome:"library"};function fa(n){switch(n.status){case"idle":return{text:"never run",tone:"",spinner:!1,detail:"",batch:""};case"queued":return{text:"queued",tone:"is-running",spinner:!1,detail:"",batch:""};case"running":return{text:n.total>0?z.pct(Math.min(1,n.done/n.total),0):"running",tone:"is-running",spinner:!0,batch:n.batch===void 0?"":`${n.batch.at+1} of ${n.batch.of}`,detail:n.batch===void 0?n.note:`${n.batch.label}${n.note===""?"":` — ${n.note}`}`};case"done":return{text:`done in ${In(n.ms)}`,tone:"is-done",spinner:!1,detail:"",batch:""};case"failed":return{text:"failed",tone:"is-failed",spinner:!1,detail:n.message,batch:""};case"cancelled":return{text:"cancelled",tone:"",spinner:!1,detail:"",batch:""}}}function ma(n){return n.status==="running"||n.status==="queued"}function bs(n){return n==="annotations"?"It stops at its next read; a pass with no read in it runs on, and its answer is discarded.":"The worker checks between chunks, so it stops at the next one."}class pa{constructor(t){this.options=t,this.el=p("div",{class:"analysis-tasks"},this.blockedEl,this.filterEl,this.noMatchEl,this.cardsEl),this.filterEl.addEventListener("input",()=>this.applyFilter()),this.filterEl.addEventListener("keydown",e=>{if(e.key==="Escape"&&this.filterEl.value!=="")e.preventDefault(),e.stopPropagation(),this.filterEl.value="",this.applyFilter();else if(e.key==="Enter"){e.preventDefault();const s=this.rows.find(i=>!i.el.classList.contains("is-filtered-out")&&!i.el.classList.contains("is-waiting"));s!==void 0&&this.options.onOpen(s.task)}}),this.unsubscribe=t.runner.subscribe(()=>this.refresh()),this.refresh()}el;unsubscribe;blockedEl=p("p",{class:"inline-error analysis-blocked hidden",attrs:{role:"status"}});cardsEl=p("div",{class:"analysis-cards"});filterEl=p("input",{class:"input input-tiny analysis-filter",type:"search",attrs:{"aria-label":"filter the tasks",spellcheck:"false",autocomplete:"off"}});noMatchEl=p("p",{class:"analysis-empty analysis-no-match hidden",attrs:{role:"status"}});rows=[];groupNotes=[];cards=[];built=null;refresh(){const t=this.options.context(),e=t===null?[]:An(t),s=e.map(i=>i.id).join(`
|
|
9
|
+
`);s!==this.built&&(this.built=s,this.rebuild(e)),this.paint()}destroy(){this.unsubscribe(),this.rows.length=0,this.el.remove()}groups(t){const e=[];for(const s of t)e.includes(s.group)||e.push(s.group);return e}rebuild(t){if(this.rows.length=0,this.groupNotes.length=0,this.cards.length=0,this.filterEl.placeholder=`filter ${z.int(t.length)} task${t.length===1?"":"s"}…`,this.filterEl.classList.toggle("hidden",t.length===0),t.length===0){this.noMatchEl.classList.add("hidden"),this.cardsEl.replaceChildren(p("p",{class:"analysis-empty",text:"This file offers no analyses. A task that could never mean anything here is absent "+(Nn("metacool")?"rather than greyed — a metagenome task on a plain cooler, say. ":"rather than greyed. ")+"Everything that is one file away is listed, waiting, with a line saying what to load."}));return}const e=[];for(const s of this.groups(t)){const i=[],o=p("p",{class:"analysis-group-needs hidden"});this.groupNotes.push({group:s,needs:o}),i.push(o);for(const a of t.filter(l=>l.group===s)){const l=this.row(a);this.rows.push(l),i.push(l.el,l.needs)}const r=p("section",{class:"card analysis-card"},Mn(Ln[s],ha[s]),...i);this.cards.push({group:s,el:r}),e.push(r)}this.cardsEl.replaceChildren(...e),this.applyFilter()}applyFilter(){const t=this.filterEl.value.toLowerCase().split(/\s+/).filter(i=>i!=="");let e=0;for(const i of this.rows){const o=ga(i.task),r=t.every(a=>o.includes(a));i.el.classList.toggle("is-filtered-out",!r),i.needs.classList.toggle("is-filtered-out",!r),r&&e++}for(const i of this.cards){const o=this.rows.some(r=>r.group===i.group&&!r.el.classList.contains("is-filtered-out"));i.el.classList.toggle("is-filtered-out",!o)}const s=t.length>0&&e===0&&this.rows.length>0;this.noMatchEl.textContent=s?`No task matches “${this.filterEl.value.trim()}”.`:"",this.noMatchEl.classList.toggle("hidden",!s)}row(t){const e=p("span",{class:"analysis-chip"}),s=p("span",{class:"analysis-chip analysis-batch hidden"}),i=et("circle-stop",`Stop ${t.title}. ${bs(t.venue)}`,()=>this.options.runner.cancel(t.id),{class:"btn btn-icon",size:14});i.addEventListener("click",f=>f.stopPropagation());const o=ia(t.id),r=o===null?p("span",{class:"task-ref-blank",attrs:{"aria-hidden":"true"}}):da(o),a=p("div",{class:"plot-icon-row"},e,s,r),l=p("span",{class:"analysis-row-blurb",text:t.blurb}),c=p("p",{class:"analysis-row-needs hidden"}),u=p("div",{class:"analysis-row",attrs:{role:"button",tabindex:"0"}},p("span",{class:"analysis-row-title",text:t.title}),a,l),d=()=>{u.classList.contains("is-waiting")||this.options.onOpen(t)};return u.addEventListener("click",d),u.addEventListener("keydown",f=>{f.key!=="Enter"&&f.key!==" "||(f.preventDefault(),d())}),{task:t,el:u,chip:e,blurb:l,needs:c,stop:i,batch:s,cell:a,mark:r,group:t.group}}sharedNeeds(t){return t.length<2?"":t.every(e=>e===t[0])?t[0]:""}paint(){const t=this.options.active(),e=this.options.context(),s=this.options.blocked?.()??null;this.blockedEl.textContent=s??"",this.blockedEl.classList.toggle("hidden",s===null);const i=this.rows.map(l=>s!==null&&st(l.task)),o=this.rows.map((l,c)=>s!==null&&i[c]?{state:"waiting",needs:s}:e===null?{state:"waiting",needs:"Open a file."}:l.task.availability(e)),r=new Map;this.rows.forEach((l,c)=>{const u=o[c];if(u.state!=="waiting"||i[c])return;const d=r.get(l.group)??[];d.push(u.needs),r.set(l.group,d)});const a=new Map;for(const[l,c]of r)a.set(l,this.sharedNeeds(c));for(const l of this.groupNotes){const c=a.get(l.group)??"";l.needs.textContent=c,l.needs.classList.toggle("hidden",c==="")}for(const[l,c]of this.rows.entries()){const u=o[l],d=u.state==="waiting";c.el.classList.toggle("is-waiting",d),d?c.el.setAttribute("aria-disabled","true"):c.el.removeAttribute("aria-disabled"),c.el.tabIndex=d?-1:0;const f=d&&!i[l]&&u.needs!==a.get(c.group)?u.needs:"";c.needs.textContent=f,c.needs.classList.toggle("hidden",f==="");const m=this.options.runner.stateOf(c.task.id),h=fa(m);c.chip.className=h.tone===""?"analysis-chip":`analysis-chip ${h.tone}`,c.chip.replaceChildren(...h.spinner?[p("span",{class:"analysis-spinner",attrs:{"aria-hidden":"true"}})]:[],h.text),c.batch.textContent=h.batch,c.batch.classList.toggle("hidden",h.batch===""),c.blurb.textContent=h.detail===""?c.task.blurb:h.detail,c.el.title=d?u.needs:h.detail;const y=ma(m);y&&c.stop.parentNode===null?c.cell.insertBefore(c.stop,c.mark):!y&&c.stop.parentNode!==null&&c.stop.remove();const g=t===c.task.id;c.el.classList.toggle("is-active",g),g?c.el.setAttribute("aria-current","true"):c.el.removeAttribute("aria-current")}}}function ga(n){return[n.title,n.blurb,...n.keywords??[],Ln[n.group],n.id].join(`
|
|
10
|
+
`).toLowerCase()}function ba(n){let t=(Number.isFinite(n)?Math.trunc(n):0)>>>0;return function(){t=t+1831565813>>>0;let s=t;return s=Math.imul(s^s>>>15,s|1),s^=s+Math.imul(s^s>>>7,s|61),((s^s>>>14)>>>0)/4294967296}}function ys(n,t){return n.options.filter(e=>e.needsGenomes===!0&&!t.hasGenomes?!1:e.needsKinds===void 0?!0:t.entries.some(s=>s.status!=="error"&&e.needsKinds.includes(s.kind)))}function ya(n,t,e){const s={...e};for(const i of n){if(i.kind!=="choice")continue;const o=ys(i,t);if(o.length===0)continue;const r=X(s[i.key],i.default);o.some(a=>a.value===r)||(s[i.key]=o[0].value)}return s}function va(n,t){return t.hasGenomes?n.label:n.coolLabel??n.label}const wa=400,ka="score";let xa=0;function Sa(){const n=new Map;return{get:t=>n.get(t),set:(t,e)=>{e===null?n.delete(t):n.set(t,e)}}}function hn(n,t){const e=t.toLowerCase();return n.accept.some(s=>e.endsWith(s))}const $a=bi.filter(yi);function Ma(n){switch(n.kind){case"featureSet":return $a;case"pairSet":return["pairs"];case"track":return["track"];case"sequence":return["sequence"]}}function Gt(n,t){const e=Ma(n);return t.entries.filter(s=>e.includes(s.kind)&&s.status!=="error")}function Ht(n){return(n.find(e=>e.primary===!0)??n[0])?.id??null}function Ea(n){return n.kind==="featureSet"||n.kind==="pairSet"||n.kind==="track"||n.kind==="sequence"}function Ta(n,t,e){const s=Gt(n,t),i=typeof e=="string"&&e!=="";return i&&s.some(o=>o.id===e)?e:n.optional===!0?i||e===""?"":Ht(vs(s))??"":Ht(s)}function vs(n){return n.filter(t=>t.source.kind!=="computed"&&t.source.kind!=="derived")}function Ca(n,t,e){const s=Gt(n,t),i=new Set(s.map(a=>a.id)),o=Array.isArray(e)?e.filter(a=>typeof a=="string"&&i.has(a)):[];if(n.optional===!0){if(Array.isArray(e))return o;const a=Ht(vs(s));return a===null?null:[a]}if(o.length>0)return o;const r=Ht(s);return r===null?[]:[r]}function Aa(n){const e=/^\s*(.*?)\s*[=:]\s*(\S+)\s*$/.exec(n)??/^\s*(.*\S)\s+(\S+)\s*$/.exec(n);if(e===null)return null;const s=e[1];return s===""||!Number.isFinite(Number(e[2]))?null:s}function ws(n){const t=[ka],e=n?.payload;if(e===void 0)return t;const s=e.data.detail,i=new Set(t),o=Math.min(s.length,wa);for(let r=0;r<o;r++)for(const a of s[r].split(gi)){const l=Aa(a);l===null||i.has(l)||(i.add(l),t.push(l))}return t}function ks(n,t,e){const s=e[n.from],i=typeof s=="string"?s:Array.isArray(s)?s[0]??"":"";return i===""?void 0:t.entries.find(o=>o.id===i)}function Na(n,t,e){return ws(ks(n,t,e))}function La(n,t){const e=n.contigs.map(i=>i.name);if(!Array.isArray(t))return e;const s=new Set(e);return t.filter(i=>typeof i=="string"&&s.has(i))}function xs(n,t,e){const s=Na(n,t,e),i=e[n.key],o=typeof i=="string"&&i!=="";return o&&s.includes(i)?i:n.optional===!0?o||i===""?"":s[0]??"":s[0]??null}function ne(n,t,e){const s=new Set(n.map(o=>o.key)),i={};for(const[o,r]of Object.entries(e))s.has(o)&&(i[o]=r);for(const o of n)Ea(o)&&(i[o.key]=o.multiple===!0?Ca(o,t,i[o.key]):Ta(o,t,i[o.key]));for(const o of n)o.kind==="column"&&(i[o.key]=xs(o,t,i));for(const o of n)o.kind==="sequences"&&(i[o.key]=La(t,i[o.key]));for(const o of n)o.kind==="toggle"&&o.derive!==void 0&&(i[o.key]=o.derive(t));for(const o of n)o.settled!==void 0&&(mi(o,t)||(i[o.key]=o.settled));return ya(n,t,i)}function fn(n,t){return typeof n=="number"&&Number.isFinite(n)?n:t}function X(n,t){return typeof n=="string"?n:t}function mn(n,t=!1){const e=n.framing;if(e===null||e.level==="genome")return"";const[s,i]=e.rows,o=c=>n.contigs.filter(u=>u.startBin<c[1]&&u.startBin+u.bins>c[0]);if(t){const c=[...new Set([...o(e.rows),...o(e.cols)])];if(c.length===0||c.length===n.contigs.length)return"";if(c.length>1)return n.contigs.filter(u=>c.includes(u)).map(u=>u.name).join(", ")}const r=n.contigs.find(c=>s>=c.startBin&&s<c.startBin+c.bins);if(r===void 0)return"";if(i>r.startBin+r.bins)return r.name;const a=(s-r.startBin)*e.binsize,l=Math.min(r.length,(i-r.startBin)*e.binsize);return ve({contig:r.name,start:Math.max(0,Math.round(a)),end:Math.round(l)})}function Ia(n){const t=Math.floor(ba(n)()*4294967296);return t===n?n+1>>>0:t}function pe(n,t){return Array.isArray(n)&&Array.isArray(t)?n.length===t.length&&n.every((e,s)=>e===t[s]):n===t}function Oa(n,t){for(const e of new Set([...Object.keys(n),...Object.keys(t)]))if(!pe(n[e],t[e]))return!1;return!0}class Fa{constructor(t){this.options=t,this.specs=t.specs,this.context=t.context,this.shelf=t.files??Sa(),this.params={...ne(t.specs,t.context,t.value)},this.fillRegions(),this.forgetUnheld(),this.el=p("div",{class:"param-form"});for(const e of this.sections())this.el.appendChild(this.group(e));for(const e of this.specs){if(Rt(e)||e.retired===!0)continue;const s=this.build(e);this.controls.push(s),this.groups.get(e.section??"")?.appendChild(s.wrapper),s.shown=!0}this.syncVisibility()}el;context;params;specs;controls=[];groups=new Map;teardown=[];id=`pf${xa++}`;shelf;get value(){return{...this.params}}setContext(t){this.context=t;const e={...this.params};this.params={...ne(this.specs,t,this.params)},this.fillRegions();for(const s of this.controls)s.refill?.(),s.sync();this.syncVisibility(),Oa(e,this.params)||this.options.onChange(this.value)}setValue(t){this.params={...ne(this.specs,this.context,t)},this.fillRegions(),this.forgetUnheld();for(const e of this.controls)e.refill?.(),e.sync();this.syncVisibility()}destroy(){for(const t of this.teardown)t();this.teardown.length=0,this.el.remove(),this.controls.length=0,this.groups.clear()}sections(){const t=this.specs.filter(s=>!Rt(s)&&s.retired!==!0),e=[""];for(const s of t){const i=s.section??"";e.includes(i)||e.push(i)}return e.filter(s=>t.some(i=>(i.section??"")===s))}group(t){const e=p("div",{class:"panel-controls"});return this.groups.set(t,e),p("div",{class:"controls-card param-group"},t===""?null:p("h3",{class:"controls-title",text:t}),e)}wrap(t,e,s){return p("div",{class:"param-row"},e,s,t.hint===void 0?null:p("div",{class:"hint",text:t.hint}))}labelled(t,e,s){return p("label",{class:"field param-field",attrs:{for:s}},p("span",{class:"field-label",text:t.label}),e)}named(t,e,s){return p("div",{class:"field param-field"},p("span",{class:"field-label",text:t.label,id:s}),e)}blocked(t,e,s){return e.setAttribute("role","group"),e.setAttribute("aria-labelledby",s),p("div",{class:"field field-block param-field"},p("span",{class:"field-label",text:t.label,id:s}),e)}commit(t,e){if(!pe(this.params[t],e)){this.params[t]=e;for(const s of this.controls)s.spec.kind==="column"&&s.refill?.(),s.sync();this.syncVisibility(),this.options.onChange(this.value)}}syncVisibility(){const t=new Map;for(let e=this.controls.length-1;e>=0;e--){const s=this.controls[e],i=s.spec.section??"",o=this.groups.get(i);if(o===void 0)continue;const r=ai(s.spec,this.params,this.context),a=t.get(i)??null;r&&!s.shown?o.insertBefore(s.wrapper,a):!r&&s.shown&&s.wrapper.remove(),s.shown=r,r&&t.set(i,s.wrapper)}for(const[e,s]of this.groups)s.parentElement?.classList.toggle("hidden",!t.has(e))}fillRegions(){for(const t of this.specs){if(t.kind!=="region"||X(this.params[t.key],"")!=="")continue;const e=t.default??mn(this.context,t.many===!0);e!==""&&(this.params[t.key]=e)}}forgetUnheld(){for(const t of this.specs){if(t.kind!=="file")continue;const e=X(this.params[t.key],"").trim();e===""||At(e)||this.shelf.get(t.key)?.value!==e&&(this.params[t.key]="")}}build(t){switch(t.kind){case"number":return this.numberControl(t);case"choice":return this.choiceControl(t);case"toggle":return this.toggleControl(t);case"featureSet":case"pairSet":case"track":case"sequence":return t.multiple===!0?this.entryList(t):this.entrySelect(t);case"column":return this.columnControl(t);case"sequences":return this.sequenceList(t);case"region":return this.locusControl(t);case"text":return this.textControl(t);case"file":return this.fileControl(t);case"seed":return this.seedControl(t)}}numberControl(t){const e=`${this.id}-${t.key}`,s=t.min!==void 0&&t.max!==void 0,i=t.slider===!0&&s,o=t.step??(t.integer===!0?1:void 0),r=p("input",{class:i?"input input-num input-step":"input input-num",type:"number",attrs:{id:e,size:"1",step:o===void 0?"any":String(o)}});t.min!==void 0&&(r.min=String(t.min)),t.max!==void 0&&(r.max=String(t.max));const a=i?p("input",{class:"ann-range",type:"range"}):null;a!==null&&t.min!==void 0&&t.max!==void 0&&(a.min=String(t.min),a.max=String(t.max),a.step=String(o??(t.max-t.min)/100),a.setAttribute("aria-labelledby",`${e}-label`));const l=g=>{let w=t.integer===!0?Math.round(g):g;return t.min!==void 0&&(w=Math.max(t.min,w)),t.max!==void 0&&(w=Math.min(t.max,w)),w},c=()=>fn(this.params[t.key],t.seed?.(this.context)??t.default),u=g=>{r.value=Number.isFinite(g)?String(g):"",a!==null&&Number.isFinite(g)&&(a.value=String(g))},d=()=>{const g=r.value.trim(),w=g===""?Number.NaN:Number(g);if(!Number.isFinite(w)){u(c());return}const b=l(w);u(b),this.commit(t.key,b)};r.addEventListener("change",d),r.addEventListener("keydown",g=>{g.key==="Enter"&&d()}),a!==null&&(a.addEventListener("input",()=>{r.value=String(l(Number(a.value)))}),a.addEventListener("change",()=>this.commit(t.key,l(Number(a.value)))));const f=t.unit===void 0||t.unit===""?null:p("span",{class:"field-label",text:t.unit}),m=p("div",{class:"plot-icon-row"},r,f,a);i&&r.setAttribute("aria-labelledby",`${e}-label`);const h=i?this.blocked(t,m,`${e}-label`):this.labelled(t,m,e),y=()=>{document.activeElement!==r&&u(c())};return y(),{spec:t,wrapper:this.wrap(t,h),shown:!1,sync:y}}choiceControl(t){const e=`${this.id}-${t.key}`,s=()=>X(this.params[t.key],t.default),i=p("select",{class:"select",attrs:{id:e}}),o=()=>{const a=ys(t,this.context);i.replaceChildren();for(const c of a)i.appendChild(p("option",{value:c.value,text:va(c,this.context),...c.hint===void 0?{}:{title:c.hint}}));const l=s();a.some(c=>c.value===l)||i.appendChild(p("option",{value:l,text:`${l} — not available on this file`,attrs:{disabled:""}}))};i.addEventListener("change",()=>this.commit(t.key,i.value));const r=()=>{i.value=s()};return o(),r(),{spec:t,wrapper:this.wrap(t,this.labelled(t,i,e)),shown:!1,sync:r,refill:o}}toggleControl(t){const e=`${this.id}-${t.key}-label`,s=p("button",{class:"btn btn-toggle",type:"button",text:"on",title:t.hint??t.label});s.setAttribute("aria-labelledby",e),s.addEventListener("click",()=>{const o=this.params[t.key];this.commit(t.key,!(typeof o=="boolean"?o:t.default))});const i=()=>{const o=typeof this.params[t.key]=="boolean"?this.params[t.key]:t.default;s.setAttribute("aria-pressed",String(o)),s.textContent=o===!0?"on":"off"};return i(),{spec:t,wrapper:this.wrap(t,this.named(t,p("div",{class:"plot-icon-row"},s),e)),shown:!1,sync:i}}entrySelect(t){const e=`${this.id}-${t.key}`,s=p("select",{class:"select",attrs:{id:e}}),i=()=>{const r=Gt(t,this.context);s.replaceChildren(),t.optional===!0&&s.appendChild(p("option",{value:"",text:t.noneLabel??"none"}));for(const a of r)s.appendChild(p("option",{value:a.id,text:a.label}));r.length===0&&t.optional!==!0&&s.appendChild(p("option",{value:"",text:"nothing loaded"})),s.disabled=r.length===0};s.addEventListener("change",()=>this.commit(t.key,s.value===""?t.optional===!0?"":null:s.value));const o=()=>{s.value=X(this.params[t.key],"")};return i(),o(),{spec:t,wrapper:this.wrap(t,this.labelled(t,s,e)),shown:!1,sync:o,refill:i}}entryList(t){const e=`${this.id}-${t.key}-label`,s=p("div",{class:"ann-list param-checks"});let i=[];const o=()=>{const l=this.params[t.key];return Array.isArray(l)?l.filter(c=>typeof c=="string"):[]},r=()=>{const l=Gt(t,this.context);s.replaceChildren(),i=l.map(c=>{const u=p("input",{class:"checkbox",type:"checkbox"});return u.addEventListener("change",()=>this.commit(t.key,i.filter(d=>d.input.checked).map(d=>d.id))),s.appendChild(p("label",{class:"ann-head param-check"},u,p("span",{text:c.label}))),{id:c.id,input:u}}),l.length===0&&s.appendChild(p("div",{class:"hint",text:"nothing loaded"}))},a=()=>{const l=new Set(o());for(const c of i)c.input.checked=l.has(c.id)};return r(),a(),{spec:t,wrapper:this.wrap(t,this.blocked(t,s,e)),shown:!1,sync:a,refill:r}}sequenceList(t){const e=`${this.id}-${t.key}-label`,s=p("div",{class:"ann-list param-checks param-sequences"}),i=p("span",{class:"hint param-check-count"});let o=[];const r=()=>{const d=this.params[t.key];return Array.isArray(d)?d.filter(f=>typeof f=="string"):[]},a=()=>{this.commit(t.key,o.filter(d=>d.input.checked).map(d=>d.name))},l=()=>{s.replaceChildren(),o=this.context.contigs.map(d=>{const f=p("input",{class:"checkbox",type:"checkbox"});return f.addEventListener("change",a),s.appendChild(p("label",{class:"ann-head param-check"},f,p("span",{text:d.name}),p("span",{class:"hint param-check-note",text:z.bp(d.length)}))),{name:d.name,input:f}}),o.length===0&&s.appendChild(p("div",{class:"hint",text:"this file has no sequences"}))},c=()=>{const d=new Set(r());for(const f of o)f.input.checked=d.has(f.name);i.textContent=o.length===0?"":`${z.int(d.size)} of ${z.int(o.length)} ticked`},u=p("div",{class:"param-check-actions"},I("all",()=>this.commit(t.key,this.context.contigs.map(d=>d.name)),{class:"btn btn-quiet",title:"Tick every sequence"}),I("none",()=>this.commit(t.key,[]),{class:"btn btn-quiet",title:"Untick every sequence"}),i);return l(),c(),{spec:t,wrapper:this.wrap(t,this.blocked(t,p("div",{},u,s),e)),shown:!1,sync:c,refill:()=>{l(),c()}}}columnControl(t){const e=`${this.id}-${t.key}`,s=p("select",{class:"select",attrs:{id:e}});let i=null;const o=()=>{const a=ks(t,this.context,this.params),l=`${a?.id??""}:${a?.payload?.data.length??0}`;if(l===i)return;i=l;const c=ws(a);s.replaceChildren(),t.optional===!0&&s.appendChild(p("option",{value:"",text:t.noneLabel??"none"}));for(const u of c)s.appendChild(p("option",{value:u,text:u}));this.params[t.key]=xs(t,this.context,this.params),s.value=X(this.params[t.key],"")};s.addEventListener("change",()=>this.commit(t.key,s.value===""?t.optional===!0?"":null:s.value));const r=()=>{s.value=X(this.params[t.key],"")};return o(),r(),{spec:t,wrapper:this.wrap(t,this.labelled(t,s,e)),shown:!1,sync:r,refill:o}}locusControl(t){const e=`${this.id}-${t.key}`,s=`${e}-sequences`,i=p("datalist",{attrs:{id:s}}),o=p("input",{class:"input input-region param-region",type:"text",attrs:{id:e,list:s},placeholder:mn(this.context),title:Nn("metacool")?"A contig, or a contig and a span. Coordinates are 1-based and inclusive, as IGV and samtools write them. On a metagenome a genome name is one too, and means the whole of it.":"A sequence, or a sequence and a span. Coordinates are 1-based and inclusive, as IGV and samtools write them."}),r=p("p",{class:"hint param-map-note hidden"}),a=t.pickable===!0&&this.context.hasMap,l=a?I("pick on map",()=>Le()?pi():li(),{class:"btn btn-toggle param-pick",title:"Then Shift-drag along either axis of the map. That gesture normally zooms; while this is lit it names this locus instead, once."}):null,c=()=>{i.replaceChildren(...(this.context.genomes??[]).map(f=>p("option",{value:f.name})),...this.context.contigs.map(f=>p("option",{value:f.name})))},u=()=>this.commit(t.key,o.value.trim());o.addEventListener("change",u),o.addEventListener("keydown",f=>{f.key==="Enter"&&u()});const d=()=>{if(l!==null){const f=Le();l.setAttribute("aria-pressed",String(f)),l.textContent=f?"pointing…":"pick on map",r.classList.toggle("hidden",!f),r.textContent=f?"Shift-drag along either axis of the map. Escape to stop.":""}document.activeElement!==o&&(o.value=X(this.params[t.key],""))};if(a){let f=Ie();this.teardown.push(ci(()=>{const m=Ie();m!==null&&m!==f&&(f=m,this.commit(t.key,m.whole===!0?m.contig:ve(m))),d()}))}return c(),d(),{spec:t,wrapper:this.wrap(t,this.labelled(t,p("div",{class:"param-locus"},o,i,...l===null?[]:[l]),e),r),shown:!1,sync:d,refill:()=>{c(),d()}}}fileControl(t){const e=`${this.id}-${t.key}-label`,s=`${this.id}-${t.key}`,i=p("span",{class:"ann-drop-label"}),o=p("span",{class:"ann-drop-hint"}),r=p("div",{class:"ann-drop param-drop",attrs:{tabindex:"0",role:"button","aria-labelledby":e}},i,o),a=et("x","Forget this file",()=>this.chooseFile(t,null),{class:"btn btn-icon param-drop-forget"}),l=p("input",{class:"input param-address",type:"text",attrs:{id:s,"aria-label":`${t.label}: address`},...t.placeholder===void 0?{}:{placeholder:t.placeholder}}),c=p("p",{class:"hint param-file-note hidden"}),u=g=>{c.textContent=g,c.classList.toggle("hidden",g==="")},d=g=>{if(!hn(t,g.name)){u(`${g.name} is not a ${t.accept.join(" or ")} file.`);return}u(""),this.chooseFile(t,{value:g.name,source:{kind:"local",file:g},size:g.size})},f=()=>{fi({multiple:!1}).then(g=>{g.length>0&&d(g[0])})};r.addEventListener("click",f),r.addEventListener("keydown",g=>{g.key!=="Enter"&&g.key!==" "||(g.preventDefault(),f())}),r.addEventListener("dragover",g=>{!ui(g)&&!Ne(g)||(g.preventDefault(),r.classList.add("over"))}),r.addEventListener("dragleave",g=>{g.relatedTarget instanceof Node&&r.contains(g.relatedTarget)||r.classList.remove("over")}),r.addEventListener("drop",g=>{if(g.preventDefault(),g.stopPropagation(),r.classList.remove("over"),Ne(g)){di(g).then(b=>{if(b===null)return;const S=b.name??b.uri.split(/[\\/]/).pop()??b.uri;if(!hn(t,S)){u(`${S} is not a ${t.accept.join(" or ")} file.`);return}u(""),this.chooseFile(t,{value:b.source.kind==="local"?b.source.file.name:b.uri,source:b.source,name:S,...b.source.kind==="local"?{size:b.source.file.size}:{}})});return}const w=hi(g.dataTransfer);w.length>0&&d(w[0])});const m=()=>{const g=l.value.trim();if(g!==""&&!At(g)){u("An address starts with https:// or s3:// — a file on this computer is dropped above.");return}u(""),this.shelf.set(t.key,null),this.commit(t.key,g)};l.addEventListener("change",m),l.addEventListener("keydown",g=>{g.key==="Enter"&&(g.preventDefault(),m())});const h=()=>{const g=X(this.params[t.key],"").trim(),w=this.shelf.get(t.key),b=w!==void 0&&w.value===g&&g!==""&&!At(g),S=w!==void 0&&w.value===g&&At(g);r.classList.toggle("is-held",b||S),b||S?(i.textContent=w.name??(b?g:g.split(/[\\/]/).pop()??g),o.textContent=w.size===void 0?"drop or click to choose another":`${z.bytes(w.size)} · drop or click to choose another`):(i.textContent=t.prompt,o.textContent=t.accept.join(" or ")),a.classList.toggle("hidden",!(b||S)),document.activeElement!==l&&(l.value=b||S?"":g)};h();const y=p("div",{class:"param-file"},p("div",{class:"param-file-row"},r,a),l);return{spec:t,wrapper:this.wrap(t,this.named(t,y,e),c),shown:!1,sync:h}}chooseFile(t,e){this.shelf.set(t.key,e);const s=e?.value??"";if(pe(this.params[t.key],s)){for(const i of this.controls)i.sync();this.options.onChange(this.value);return}this.commit(t.key,s)}textControl(t){const e=`${this.id}-${t.key}`,s=p("input",{class:"input",type:"text",attrs:{id:e},...t.placeholder===void 0?{}:{placeholder:t.placeholder},style:{width:"100%"}}),i=()=>this.commit(t.key,s.value.trim());s.addEventListener("change",i),s.addEventListener("keydown",r=>{r.key==="Enter"&&(r.preventDefault(),i())});const o=()=>{document.activeElement!==s&&(s.value=X(this.params[t.key],""))};return o(),{spec:t,wrapper:this.wrap(t,this.labelled(t,s,e)),shown:!1,sync:o}}seedControl(t){const e=`${this.id}-${t.key}`,s=p("input",{class:"input input-num input-step",type:"number",attrs:{id:e,size:"1",step:"1",min:"0"}}),i=()=>fn(this.params[t.key],t.default),o=()=>{const l=Number(s.value);if(!Number.isFinite(l)){s.value=String(i());return}const c=Math.max(0,Math.trunc(l));s.value=String(c),this.commit(t.key,c)};s.addEventListener("change",o),s.addEventListener("keydown",l=>{l.key==="Enter"&&o()});const r=et("rotate-cw","Roll a new seed — the same seed gives the same numbers, a new one resamples",()=>{const l=Ia(i());s.value=String(l),this.commit(t.key,l)},{class:"btn btn-icon",size:14}),a=()=>{document.activeElement!==s&&(s.value=String(i()))};return a(),{spec:t,wrapper:this.wrap(t,this.labelled(t,p("div",{class:"plot-icon-row"},s,r),e)),shown:!1,sync:a}}}const kt="\0all-maps",ge="chromosomix:analysis-drawer:width",Pa=380,Ba=.75,qa=.95,za=300;let Ra=0;function _a(){try{const n=window.localStorage.getItem(ge);if(n===null)return null;const t=Number(n);return Number.isFinite(t)&&t>0?t:null}catch{return null}}function pn(n){try{n===null?window.localStorage.removeItem(ge):window.localStorage.setItem(ge,String(Math.round(n)))}catch{}}function Da(n){if(n===null)return!0;const t=typeof n;return t==="number"||t==="string"||t==="boolean"?!0:Array.isArray(n)&&n.every(e=>typeof e=="string")}function xt(n){return n===null?"":n.memoryKey??n.uri}function Va(n,t){const e={...Kt(n.params)},s=Fn(t,n.id);if(s===null)return e;for(const i of n.params){const o=s[i.key];Da(o)&&(e[i.key]=o)}return e}function Wa(n){const t=[n.note.replace(/\.\s*$/,"")];return n.requests!==null&&n.requests>0&&t.push(`${z.int(n.requests)} request${n.requests===1?"":"s"}`),n.bytes!==null&&n.bytes>0&&t.push(z.bytes(n.bytes)),t.join(" · ")}function Ga(n,t){return Yn(n,{params:n.params,framing:t})}function Ha(n){return n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement?!0:n instanceof HTMLInputElement?!["button","checkbox","radio","range","submit","reset"].includes(n.type):n.isContentEditable}function be(n){return Mi(n.provenance.createdAt)}function Ka(n,t,e){if(n===t)return"The run on screen";const s=[];for(const o of e.params){const r=n.provenance.params[o.key],a=t.provenance.params[o.key];Pt(r)!==Pt(a)&&s.push(`${o.label}: ${Pt(r)} (latest: ${Pt(a)})`)}const i=`Finished ${be(n)}.`;return s.length===0?`${i} The same parameters as the latest run.`:`${i} ${s.join(" · ")}`}function Pt(n){return n==null||n===""?"—":Array.isArray(n)?n.length===0?"—":n.join(", "):String(n)}function gn(n){return n.mapless===!0?"the sequences chosen":"the loaded tracks"}function Ya(n){switch(n.status){case"running":return[p("span",{class:"analysis-spinner",attrs:{"aria-hidden":"true"}}),n.note===""?"working":n.note];case"queued":return["waiting for the job in front of it"];case"failed":return[p("span",{class:"inline-error",text:n.message})];default:return[]}}function ye(n){const t=n.getBoundingClientRect();return{width:Math.max(1,Math.round(t.width)),height:Math.max(1,Math.round(t.height))}}function se(n){const t=ye(n.el),e=Ti(za),s=document.createElement("canvas");s.width=Math.max(1,Math.round(t.width*e)),s.height=Math.max(1,Math.round(t.height*e));const i=s.getContext("2d");if(i===null)throw new Error("The browser would not give this page a canvas.");return i.setTransform(e,0,0,e,0,0),n.draw(i,t),s}function bn(n){return n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"figure"}function Bt(n,t,e,s){return Mt(t.task,n,e).replace(/\.tsv$/,`.${s}`)}class Ua{constructor(t){this.options=t;const e=`analysis-drawer-${Ra++}`;this.titleEl.id=`${e}-title`,this.recomputeButton=I("recompute here",()=>this.run(),{class:"btn btn-quiet",title:"Take a new snapshot of the framing and run again. The result on screen is a record of the view it was computed from, so it is left as it is until this finishes."}),this.runButton=I("run",()=>this.run(),{class:"btn"}),this.runAllButton=I("run on all maps",()=>this.runAll(),{class:"btn hidden",title:"Run this task once per map on screen, one after another. Each result is filed against the map it was measured from, so a batch leaves a row per panel."}),this.cancelButton=I("cancel",()=>this.cancel(),{class:"btn"}),this.cliButton=I("copy CLI command",()=>this.copyCliCommand(),{class:"btn"}),this.progressEl=p("div",{class:"analysis-progress"},this.progressFill),this.recordEl=p("div",{class:"plot-icon-row hidden"},this.recordNote,I("copy provenance",()=>this.copyProvenance(),{class:"btn",title:"The task, its version, every parameter, the framing, the file and the build — the same lines every export carries at its head."}),this.cliButton),this.el=p("div",{class:"analysis-drawer collapsed",attrs:{role:"region","aria-labelledby":this.titleEl.id}},p("div",{class:"analysis-drawer-head"},this.titleEl,this.framingEl,this.recomputeButton,et("x","Close the drawer. Anything running keeps running — the panel row says so.",()=>this.close(),{class:"btn-close",size:14})),p("div",{class:"analysis-drawer-body"},this.formSlot,p("div",{class:"analysis-run"},this.runButton,this.runAllButton,this.cancelButton,this.costEl,this.progressEl),this.noteEl,this.recordEl,this.notesEl,this.mapsEl,this.runsEl,this.outputsEl,this.statusEl),this.handle()),this.unsubscribe=t.runner.subscribe(()=>this.refresh()),window.addEventListener("keydown",this.onKeyDown)}el;titleEl=p("h2",{class:"analysis-drawer-title"});framingEl=p("span",{class:"analysis-framing"});recomputeButton;formSlot=p("div",{class:"analysis-form"});runButton;runAllButton;cancelButton;costEl=p("span",{class:"analysis-cost"});progressFill=p("div",{class:"analysis-progress-fill"});progressEl;noteEl=p("div",{class:"analysis-note hidden"});recordEl;recordNote=p("span",{class:"analysis-note"});notesEl=p("ul",{class:"analysis-notes hidden"});outputsEl=p("div",{style:{display:"flex",flexDirection:"column",gap:"0.8rem"}});mapsEl=p("div",{class:"analysis-maps hidden"});runsEl=p("div",{class:"analysis-runs hidden"});statusEl=p("div",{class:"analysis-note hidden"});unsubscribe;current=null;form=null;params={};figures=[];surfaceSlots=[];drawn=null;cliButton;chosenMap=new Map;chosenRun=new Map;combined=!1;across=null;width=_a();show(t){if(t!==null&&this.current!==null&&t.id===this.current.id){this.refresh();return}if(this.teardown(),this.current=t,t===null){this.el.classList.add("collapsed");return}this.params=Kt(t.params),this.el.classList.remove("collapsed"),this.paintWidth(),this.refresh()}get task(){return this.current}get isOpen(){return this.current!==null}context(){return this.options.context(this.current??void 0)}paintRun(t,e){if(!st(t)){this.runButton.replaceChildren("run"),this.runButton.title=`Run ${t.title} on ${gn(t)}`+(e<2?".":" — it reads no map, so it runs once, whichever map is starred.");return}const s=e<2?null:this.options.runner.target();if(s===null){this.runButton.replaceChildren("run"),this.runButton.title=`Run ${t.title} on the open map.`;return}this.runButton.replaceChildren("run on ",ie("star",{size:12,class:"run-star"})),this.runButton.title=`Run ${t.title} on ${s.label} — the starred map, which is the one every task measures. Move the star in a panel’s heading to measure another, or run on all of them.`}refresh(){const t=this.current;if(t===null)return;const e=this.context();this.titleEl.textContent=t.title,this.syncForm(t,e);const s=this.options.runner.resultsFor(t.id);this.syncMaps(t,s);const i=this.chosenMap.get(t.id),o=i===kt&&s.length>1,r=i===void 0||i===kt?void 0:i,a=r===void 0?[]:this.options.runner.runsOf(t.id,r),l=o?[]:a.length>0?a:this.options.runner.runsOf(t.id),c=Math.min(Math.max(0,this.chosenRun.get(t.id)??0),Math.max(0,l.length-1)),u=o?null:l[c]??null;this.syncRuns(t,l,c),o?this.syncCombined(s):this.syncOutputs(u),this.syncFraming(u??s[0]?.result??null),this.syncRun(t,e)}relayout(){this.current!==null&&this.paintWidth()}destroy(){this.unsubscribe(),window.removeEventListener("keydown",this.onKeyDown),this.teardown(),this.el.remove()}onKeyDown=t=>{if(t.key!=="Escape"||t.defaultPrevented||this.current===null)return;const e=document.activeElement;e instanceof HTMLElement&&this.el.contains(e)&&Ha(e)||(t.preventDefault(),this.close())};close(){this.show(null),this.options.onClose()}teardown(){this.form?.destroy(),this.form=null,this.clearFigures(),this.outputsEl.replaceChildren(),this.notesEl.replaceChildren(),this.notesEl.classList.add("hidden"),this.recordEl.classList.add("hidden"),this.formSlot.replaceChildren(),this.setStatus(""),this.drawn=null,this.params={}}setStatus(t){this.statusEl.textContent=t,this.statusEl.classList.toggle("hidden",t==="")}clearFigures(){for(const t of this.figures)t.destroy();this.figures=[]}handle(){return vi({side:"right",what:"Analysis drawer",width:()=>this.widthNow(),resize:t=>{this.width=t,this.paintWidth()},commit:()=>pn(this.widthNow()),reset:()=>{this.width=null,pn(null),this.paintWidth()}})}bodyWidth(){const e=(this.el.closest(".app-body")??this.el.parentElement)?.getBoundingClientRect().width??0;return e>0?e:window.innerWidth}widthNow(){const t=this.bodyWidth(),e=Math.round(t*qa),s=Math.min(Pa,e);return Math.max(s,Math.min(e,this.width??Math.round(t*Ba)))}paintWidth(){this.el.style.width=`${this.widthNow()}px`}syncForm(t,e){if(e===null)return;if(this.form!==null){this.form.setContext(e);return}this.params=Va(t,xt(e));const s=this.options.runner,i=new Fa({specs:t.params,context:e,value:this.params,onChange:o=>this.onParams(o),files:{get:o=>s.heldFile(t.id,o),set:(o,r)=>s.holdFile(t.id,o,r)}});this.form=i,this.params=i.value,this.formSlot.replaceChildren(i.el)}onParams(t){this.params=t;const e=this.current,s=this.context();e===null||s===null||(oe(xt(s),e.id,t),this.syncRun(e,s))}blockedFor(t){return st(t)?this.options.blocked?.()??null:null}run(){const t=this.current;t!==null&&this.blockedFor(t)===null&&(this.setStatus(""),this.chosenRun.delete(t.id),this.options.runner.run(t,this.seeded(t)),this.refresh())}seeded(t){const e=this.context();return e===null?this.params:(oe(xt(e),t.id,this.params),wi(t.params,e,this.params))}runAll(){const t=this.current;t!==null&&this.blockedFor(t)===null&&(this.setStatus(""),this.chosenRun.delete(t.id),this.runAllButton.disabled=!0,this.options.runner.readyTargets().then(e=>{this.current===t&&this.options.runner.runAll(t,this.seeded(t),e)}).finally(()=>this.refresh()))}cancel(){this.current!==null&&this.options.runner.cancel(this.current.id)}syncRun(t,e){const s=this.options.runner.stateOf(t.id),i=s.status==="running"||s.status==="queued",o=e===null?null:t.estimate(e,this.params),r=this.blockedFor(t),a=r!==null?r:e===null?"This view has no contact map to run against.":o!==null&&o.refusal!==void 0&&o.refusal!==""?o.refusal:null;this.runButton.disabled=i||a!==null;const l=this.options.runner.targetCount();this.paintRun(t,l),this.runAllButton.classList.toggle("hidden",l<2||!st(t)),this.runAllButton.disabled=i||a!==null,this.runAllButton.textContent=`run on all ${l} maps`,a!==null?(this.costEl.className="analysis-refusal",this.costEl.textContent=a):(this.costEl.className=o!==null&&o.class==="scan"?"analysis-cost is-scan":"analysis-cost",this.costEl.textContent=o===null?"":Wa(o)),this.cancelButton.classList.toggle("hidden",!i),this.cancelButton.title=`Stop this job. ${bs(t.venue)}`;const c=s.status==="running"&&s.total>0;this.progressEl.classList.toggle("hidden",!c),c&&s.status==="running"&&(this.progressFill.style.width=`${Math.min(100,s.done/s.total*100).toFixed(1)}%`);const u=Ya(s);this.noteEl.replaceChildren(...u),this.noteEl.classList.toggle("hidden",u.length===0)}syncMaps(t,e){if(e.length<2){this.mapsEl.classList.add("hidden"),this.mapsEl.replaceChildren(),this.chosenMap.delete(t.id);return}const s=[...e.map(a=>a.target.map),kt],i=this.chosenMap.get(t.id)??s[0],o=a=>{this.chosenMap.set(t.id,a),this.chosenRun.delete(t.id),this.drawn=null,this.refresh()},r=a=>{const l=s.indexOf(i);o(s[(l+a+s.length)%s.length])};this.mapsEl.classList.remove("hidden"),this.mapsEl.replaceChildren(et("chevron-left","The previous map",()=>r(-1),{class:"btn-quiet"}),...e.map(a=>I(a.target.label,()=>o(a.target.map),{class:`btn btn-quiet analysis-map${a.target.map===i?" is-on":""}`,title:`The result measured on ${a.target.label}`})),I("all maps",()=>o(kt),{class:`btn btn-quiet analysis-map${i===kt?" is-on":""}`,title:"Every map’s curves on one axis and every map’s tables as one — the comparison the deck was opened for"}),et("chevron-right","The next map",()=>r(1),{class:"btn-quiet"}))}syncRuns(t,e,s){if(e.length<2){this.runsEl.classList.add("hidden"),this.runsEl.replaceChildren();return}const i=l=>{this.chosenRun.set(t.id,Math.max(0,Math.min(e.length-1,l))),this.drawn=null,this.refresh()},o=I("older",()=>i(s+1),{class:"btn btn-quiet",title:"The run before this one, with the figures it produced"});o.disabled=s>=e.length-1;const r=I("newer",()=>i(s-1),{class:"btn btn-quiet",title:"Back towards the most recent run"});r.disabled=s<=0;const a=I("latest",()=>i(0),{class:"btn btn-quiet",title:"The most recent run of this task"});a.disabled=s===0,this.runsEl.classList.remove("hidden"),this.runsEl.replaceChildren(ie("rotate-cw",{size:13,class:"analysis-runs-mark"}),o,p("span",{class:"analysis-run-at",text:s===0?`latest of ${e.length} runs`:`run ${e.length-s} of ${e.length} · ${be(e[s])}`,title:Ka(e[s],e[0],t)}),r,a)}syncCombined(t){this.drawn=null,this.combined=!0,this.clearFigures(),this.setStatus(""),this.notesEl.classList.add("hidden"),this.recordEl.classList.remove("hidden"),this.recordNote.textContent=`${t.length} maps, together`;const{outputs:e,perMapOnly:s}=Io(t.map(a=>({label:a.target.label,result:a.result})),a=>a.kind==="curve"?a:a.kind==="profile"?Ei(a):null),i=t.map(a=>({label:a.target.label,provenance:a.target.uri===""||a.target.uri===a.result.provenance.framing.uri?a.result.provenance:{...a.result.provenance,framing:{...a.result.provenance.framing,uri:a.target.uri}}}));this.across=i;const o=i[0];o!==void 0&&this.paintCli(o.provenance);const r=e.map(a=>this.combinedBlock(a,i));s.length>0&&r.push(p("p",{class:"analysis-elsewhere",text:`${s.join(", ")} ${s.length===1?"is":"are"} one picture per map rather than one across them — a pileup averaged over four libraries would be a fifth thing nobody asked for. They are on the tabs above.`})),r.length===0&&r.push(p("p",{class:"analysis-elsewhere",text:"Nothing this task produces can be drawn across maps. Its tabs are above."})),this.outputsEl.replaceChildren(...r),this.paintWidth()}combinedBlock(t,e){const s=sn({output:t,task:`${this.current?.id??"task"}:combined`,uri:xt(this.context()),extras:[I("TSV",()=>this.saveCombinedTsv(t,e),{class:"btn",title:"The numbers of every map as one table, with each map’s provenance above them — the file, the framing and the settings every row was measured with."})],onPng:i=>void this.savePngPlain(i,t.label),onPdf:i=>void this.savePdfPlain(i,t.label),onCopy:i=>this.copyPng(i,t.label)});return this.figures.push(s),s.el}saveCombinedTsv(t,e){const s=j(new Date),i=new Blob([...po(t,e)],{type:"text/tab-separated-values"});it(i,Mt(this.current?.id??"task",t,s))}syncFraming(t){const e=this.options.framing();if(this.current!==null&&!st(this.current)){const s=gn(this.current);this.framingEl.className="analysis-framing",this.framingEl.textContent=t===null?`reads ${s}, not the map`:`from ${s}, not the map`,this.framingEl.title="",this.recomputeButton.classList.add("hidden");return}if(t!==null){const s=t.provenance,i=e!==null&&!Ga(s,e);this.framingEl.className=i?"analysis-framing is-stale":"analysis-framing",this.framingEl.textContent=i?`from ${s.framing.label} — the view has moved since`:`from ${s.framing.label}`,this.framingEl.title=s.framing.label,this.recomputeButton.classList.toggle("hidden",!i);return}this.framingEl.className="analysis-framing",this.framingEl.textContent=e===null?"no contact map in this view":`will run on ${e.label}`,this.framingEl.title=e?.label??"",this.recomputeButton.classList.add("hidden")}syncOutputs(t){if(t===this.drawn&&!this.combined)return;if(this.combined=!1,this.across=null,this.drawn=t,this.clearFigures(),this.setStatus(""),t===null){this.outputsEl.replaceChildren(),this.notesEl.replaceChildren(),this.notesEl.classList.add("hidden"),this.recordEl.classList.add("hidden");return}const e=t.provenance;this.recordEl.classList.remove("hidden"),this.recordNote.textContent=`computed in ${In(t.ms)} at ${be(t)}`,this.recordNote.title=e.createdAt,this.paintCli(e),this.notesEl.replaceChildren(...t.notes.map(s=>p("li",{text:s}))),this.notesEl.classList.toggle("hidden",t.notes.length===0),this.outputsEl.replaceChildren(...t.outputs.length===0?[p("p",{class:"analysis-elsewhere",text:t.notes.length===0?"This run produced no output, and said nothing about why. That is a bug — please report it.":"No output was produced. The reason is above."})]:this.outputBlocks(t.outputs,e))}outputBlocks(t,e){const s=[];let i=null;const o=()=>{i!==null&&(s.push(this.elsewhere(i.where,i.items,e)),i=null)};for(const r of t){const a=this.elsewhereOf(r);a===null?(o(),s.push(this.block(r,e))):i!==null&&i.where===a?i.items.push(r):(o(),i={where:a,items:[r]})}return o(),s}elsewhereOf(t){return t.kind==="intervals"?t.entryKind==="structure"?"structure":this.options.hasLanes()?"overlay":"loose":t.kind==="profile"&&this.options.hasLanes()?"lane":null}block(t,e){const s=sn({output:t,task:this.current?.id??"task",uri:xt(this.context()),extras:[...t.kind==="profile"?this.profileButtons(t,e):[],this.tsvButton(t,e)],onPng:i=>void this.savePng(i,t,e),onPdf:i=>void this.savePdf(i,t,e),onCopy:i=>this.copyPng(i,t.label)});return this.figures.push(s),s.el}profileButtons(t,e){const s=i=>{this.options.writeProfile(t,e,i).catch(o=>{this.setStatus(o instanceof Error?o.message:String(o))})};return[I("bigWig",()=>s("bigwig"),{class:"btn",title:"Written here, byte for byte — no bedGraphToBigWig step. What IGV, deepTools and pyBigWig open."}),I("bedGraph",()=>s("bedgraph"),{class:"btn",title:"One line per bin that has a value; bins with none are omitted, never written as 0."})]}elsewhere(t,e,s){const i=e.length>1,o=t==="lane"?i?`${z.int(e.length)} tracks added to the Tracks card in the Annotations panel, marked *.`:"Added to the Tracks card in the Annotations panel, marked *.":t==="structure"?"Added to the Structures card in the Annotations panel, and shown in the deck’s structure cell (add one from the deck’s bar if none is open).":t==="overlay"&&this.context()?.hasMap===!1?i?`${z.int(e.length)} sets added to the Tracks card in the Annotations panel as 1D tracks, marked *.`:"Added to the Tracks card in the Annotations panel as a 1D track, marked *.":t==="overlay"?i?`${z.int(e.length)} sets added to the Tracks card in the Annotations panel, marked *.`:"Added to the Tracks card in the Annotations panel, marked *.":"This file carries no annotation layer, so there is no overlay to draw these on. Take them as a BED, which this app reads back on any file that has one.";return p("div",{class:"analysis-elsewhere"},p("span",{text:o}),...e.map(r=>p("div",{class:"plot-icon-row"},p("span",{class:"analysis-elsewhere-name",text:r.label,title:r.label}),...r.kind==="intervals"?[this.bedButton(r,s)]:[],...r.kind==="intervals"&&r.entryKind==="structure"?[this.pdbButton(r,s)]:[],this.tsvButton(r,s))).flatMap((r,a)=>{const l=e[a];if(l.kind!=="intervals"||l.entryKind==="structure")return[r];const c=p("div",{class:"analysis-surfaces"});return this.surfaceSlots.push({slot:c,output:l}),this.fillSurface(c,l),[r,c]}))}fillSurfaces(){this.surfaceSlots=this.surfaceSlots.filter(({slot:t})=>t.isConnected);for(const{slot:t,output:e}of this.surfaceSlots)t.contains(document.activeElement)||this.fillSurface(t,e)}fillSurface(t,e){const s=this.options.surfaces?.(e)??null;t.replaceChildren(...s===null?[]:[s])}bedButton(t,e){const s=t.entryKind==="structure",i=s?"bed3d":t.payload.kind==="pairs"?"BEDPE":"BED";return I(i,()=>this.saveIntervals(t,e),{class:"btn",title:s?"The model as a bed3d — chrom, start, end, x, y, z — which this app and g3dtools read back":`The called intervals as a ${i} — what bedtools reads, and what this app reads back`})}saveIntervals(t,e){const s=j(new Date),i={label:t.label,file:e.framing.label,created:e.createdAt},o=t.payload,r=t.entryKind==="structure"&&o.kind==="features",a=r&&o.kind==="features"?On(o.data,i):re(o,i),l=r?"bed3d":o.kind==="pairs"?"bedpe":"bed";it(new Blob([a],{type:"text/plain"}),Bt(t,e,s,l))}pdbButton(t,e){const s=t.payload,i=s.kind==="features"?ki(s.data):"This output holds no model.",o=I("PDB",()=>this.savePdb(t,e),{class:"btn",title:i??"The model as a PDB — an atom per bead, a chain per sequence, bonds along the fibre — which PyMOL and ChimeraX open and this app reads back"});return o.disabled=i!==null,o}savePdb(t,e){const s=t.payload;if(s.kind!=="features")return;const i=xi(s.data,{label:t.label,file:e.framing.label,created:e.createdAt});it(new Blob([i],{type:"text/plain"}),Bt(t,e,j(new Date),"pdb"))}tsvButton(t,e){return I("TSV",()=>this.saveTsv(t,e),{class:"btn",title:"The numbers as a table, with the provenance above them — what makes a figure checkable by the person reading it."})}saveTsv(t,e){const s=j(new Date),i=new Blob([...ae(t,e)],{type:"text/tab-separated-values"});it(i,Mt(e.task,t,s))}copyPng(t,e){let s;try{s=se(t)}catch(i){this.setStatus(i instanceof Error?i.message:String(i));return}Si(Zt(s)).then(()=>{this.setStatus(""),$i(`Copied ${e} · ${s.width} × ${s.height} px`)},i=>this.setStatus(`${e} could not be copied: ${i instanceof Error?i.message:String(i)}`))}async savePngPlain(t,e){const s=await gt(`${bn(e)}-${j(new Date)}.png`,"image/png");if(s!==null)try{await s.write(await Zt(se(t))),this.setStatus("")}catch(i){this.setStatus(i instanceof Error?i.message:String(i))}}async savePdfPlain(t,e){const s=new Date,i=await gt(`${bn(e)}-${j(s)}.pdf`,"application/pdf");if(i!==null)try{const o=ye(t.el),r=new Oe(o.width,o.height);t.draw(r.ctx,o);const a=await r.toBlob({title:e,created:s});await i.write(a),this.setStatus("")}catch(o){this.setStatus(o instanceof Error?o.message:String(o))}}async savePng(t,e,s){const i=await gt(Bt(e,s,j(new Date),"png"),"image/png");if(i!==null)try{await i.write(await Zt(se(t))),this.setStatus("")}catch(o){this.setStatus(o instanceof Error?o.message:String(o))}}async savePdf(t,e,s){const i=new Date,o=await gt(Bt(e,s,j(i),"pdf"),"application/pdf");if(o!==null)try{const r=ye(t.el),a=new Oe(r.width,r.height);t.draw(a.ctx,r);const l=await a.toBlob({title:e.label,created:i});await o.write(l),this.setStatus("")}catch(r){this.setStatus(r instanceof Error?r.message:String(r))}}paintCli(t){const e=$t(t.task)===void 0;this.cliButton.disabled=e,this.cliButton.title=e?`This build does not have the task ${t.task}, so it cannot write its flags.`:"The same run as a chromosomix command line — the file, the window, the balancing and every parameter — for the other two hundred files."}shownProvenances(){return this.drawn!==null?[{label:null,provenance:this.drawn.provenance}]:(this.across??[]).map(t=>({label:t.label,provenance:t.provenance}))}copyCliCommand(){const t=this.shownProvenances(),e=t[0];if(e===void 0)return;const s=$t(e.provenance.task);if(s===void 0)return;const o=t.map(({label:a,provenance:l})=>{const c=qn({task:s,provenance:l,context:this.options.context(s)}).text;return a===null?c:`# ${a}
|
|
11
|
+
${c}`}).join(`
|
|
12
|
+
|
|
13
|
+
`),r=t.length>1?0:o.split(`
|
|
14
|
+
`).filter(a=>a.startsWith("#")).length;Fe(o).then(()=>{this.setStatus(t.length>1?`${t.length} CLI commands copied, one per map.`:r===0?"CLI command copied.":`CLI command copied, with ${r} note${r===1?"":"s"} on what a shell cannot be told.`)},a=>{this.setStatus(a instanceof Error?a.message:String(a))})}copyProvenance(){const t=this.shownProvenances();if(t.length===0)return;const e=(this.drawn===null?Hn(t.map(({label:s,provenance:i})=>({label:s??"",provenance:i}))):ft(t[0].provenance)).join(`
|
|
15
|
+
`);Fe(e).then(()=>{this.setStatus("Provenance copied.")},s=>{this.setStatus(s instanceof Error?s.message:String(s))})}}function Ss(n){return Number.isInteger(n)?String(n):String(Number(n.toPrecision(7)))}function $s(n){return n!==void 0&&Number.isFinite(n)}function*Za(n,t,e){yield*tt(ft(e));const{values:s,extent:i,binsize:o}=n,r=new Gn;for(const l of t)for(let c=0;c<l.bins;c++){const u=l.startBin+c;if(u<i[0]||u>=i[1])continue;const d=s[u-i[0]];if(!$s(d))continue;const f=c*o,m=Math.min(l.length,f+o);if(!(m>f))continue;const h=r.push(`${l.name} ${f} ${m} ${Ss(d)}`);h!==void 0&&(yield h)}const a=r.flush();a!==void 0&&(yield a)}function Xa(n,t,e){const s=ft(e),i=new Map;for(const o of n){const r=i.get(o.contig);r===void 0?i.set(o.contig,[o]):r.push(o)}for(const o of t){const r=i.get(o.name);if(r===void 0)continue;const a=[];for(const l of r)for(let c=0;c<l.starts.length;c+=1){const u=l.values[c];if(!$s(u))continue;const d=Math.max(0,l.starts[c]),f=Math.min(o.length,l.ends[c]);f>d&&a.push([d,f,u])}a.sort((l,c)=>l[0]-c[0]);for(const[l,c,u]of a)s.push(`${o.name} ${l} ${c} ${Ss(u)}`)}return tt(s)}class tl{constructor(t){this.host=t;const e={context:a=>this.host.context(a),source:a=>this.host.source(a),block:()=>this.host.block(),payload:a=>this.host.store()?.byId(a)?.payload,label:a=>this.host.store()?.byId(a)?.label,vector:a=>this.binVector(a),annotations:()=>this.host.annotations(),contigLengths:a=>{const l={};for(const c of this.host.contigs(a))l[c.name]=c.length;return l},...this.host.targetMap===void 0?{}:{targetMap:()=>this.host.targetMap?.()??J},allTargets:()=>this.host.allTargets?.()??[],...this.host.allTargetsReady===void 0?{}:{allTargetsReady:()=>this.host.allTargetsReady?.()??Promise.resolve([])},...this.host.targetCount===void 0?{}:{targetCount:()=>this.host.targetCount?.()??0},finished:(a,l,c)=>this.adopt(a,l,c)};this.runner=new To(e),this.panel=new pa({runner:this.runner,context:()=>this.host.context(),blocked:()=>this.host.blocked?.()??null,onOpen:a=>this.show(a),active:()=>this.open?.id??null}),this.panelEl=this.panel.el,this.drawer=new Ua({runner:this.runner,context:a=>this.host.context(a),blocked:()=>this.host.blocked?.()??null,framing:()=>this.host.framing(),onClose:()=>this.show(null),hasLanes:()=>this.laneable(),surfaces:a=>{const l=this.host.store();if(l===null)return null;for(const[c,u]of this.intervals){if(u.output!==a)continue;const d=l.byId(c);if(d!==void 0){const f=Pe.find(m=>m.id===u.task);return Ci(l,d,{map:this.host.context(f)?.hasMap??!0})}}return null},writeProfile:(a,l,c)=>this.writeProfile(a,l,c,this.gridFor(a.binsize))}),this.drawerEl=this.drawer.el;const s=t.store(),i=this.runner.subscribe(()=>{this.panel.refresh(),this.drawer.refresh()});let o=s===null?"":wn(s);const r=s===null?()=>{}:s.subscribe(()=>{const a=wn(s);a!==o&&(o=a,this.drawer.fillSurfaces());const l=vn(s);l!==this.entries&&(this.entries=l,this.refresh())});s!==null&&(this.entries=vn(s)),this.unsubscribe=()=>{i(),r()},this.adoptCarried(t.carried?.()??[])}panelEl;drawerEl;runner;panel;drawer;profiles=new Map;intervals=new Map;open=null;entries="";unsubscribe;get hasTasks(){const t=this.host.context();return t!==null&&An(t).length>0}get isDrawerOpen(){return this.drawer.isOpen}get openTask(){return this.drawer.task?.id??null}runsOf(t){return this.runner.runsOf(t)}isRunning(t){const e=this.runner.stateOf(t).status;return e==="running"||e==="queued"}show(t){this.open=t,this.drawer.show(t),this.panel.refresh(),this.host.changed()}refresh(){this.panel.refresh(),this.drawer.refresh()}relayout(){this.drawer.relayout()}destroy(){this.unsubscribe(),this.panel.destroy(),this.drawer.destroy(),this.runner.destroy(),this.profiles.clear()}adopt(t,e,s){const i=s.map,o=e.provenance.framing.uri,r=this.host.context(t),a=this.host.memoryKey?.(o)??o;if(oe(a,t.id,Ai(t,e.provenance.params,Fn(a,t.id),r?.uri===o?r:null)),t.id==="cellqc"){const h=e.outputs.find(y=>y.kind==="table"&&y.id==="cellqc");h!==void 0&&this.host.cellMeasurements?.(e.provenance.framing.uri,h)}if(t.id==="oriter"){const h=Ni(e.outputs);Object.keys(h).length>0&&this.host.originsFound?.(e.provenance.framing.uri,h)}const l=this.host.store(),c=e.outputs.filter(h=>h.kind==="profile"),u=e.outputs.filter(h=>h.kind==="intervals");if(c.length===0&&u.length===0)return;if(l!==null&&!this.laneable()){for(const h of u)this.adoptIntervals(t,e,h,l,s,null,!1);for(const h of c)this.profiles.set(wt(h.id),{output:h,provenance:e.provenance,task:t.id,grid:this.gridFor(h.binsize,t)});this.drawer.refresh(),this.host.changed();return}if(l===null){for(const h of u)this.intervals.set(`analysis:${t.id}:${h.id}`,{output:h,provenance:e.provenance,task:t.id});for(const h of c)this.profiles.set(wt(h.id),{output:h,provenance:e.provenance,task:t.id,grid:this.gridFor(h.binsize,t)});this.drawer.refresh();return}const f=[...c.map(h=>wt(h.id,i)),...u.map(h=>kn(t.id,h.id,i))].map(h=>l.byId(h)?.style.colour).find(h=>h!==void 0)??l.nextColour();for(const h of c){const y={kind:"computed",name:h.label,task:t.id,recipe:{taskVersion:e.provenance.taskVersion,params:e.provenance.params,framing:e.provenance.framing},framing:e.provenance.framing.label},g=Li(h,y,h.colour??f,s),w=l.byId(g.id)?.revision??0;if(h.group!==void 0&&h.groupMode!==void 0){const S=this.host.groups?.()??null,A=Ii(h.group,s);S!==null&&!S.knowsMode(A)&&S.setMode(A,h.groupMode)}l.begin({card:"synthetic",kind:"track",id:g.id,label:g.label,source:y,placement:g.placement,style:g.style}),this.placeOnTarget(l,g.id,g.placement,i);const b=this.gridFor(h.binsize,t);this.profiles.set(g.id,{output:h,provenance:e.provenance,task:t.id,grid:b}),this.register(g.id,h,b),l.update(g.id,{status:"ready",...g.fileExtent===void 0?{}:{fileExtent:g.fileExtent},revision:w+1})}let m=c.length===0?null:wt(c[c.length-1].id,i);for(const h of u){const y=h.lane?.under,g=this.adoptIntervals(t,e,h,l,s,y===void 0?m:"output"in y?wt(y.output,i):y.entry,!0,f);y===void 0&&g!==null&&(m=g)}u.length>0&&this.drawer.fillSurfaces(),this.host.changed()}adoptIntervals(t,e,s,i,o,r,a=!0,l){const c=o.map,u={kind:"computed",name:s.label,task:t.id,recipe:{taskVersion:e.provenance.taskVersion,params:e.provenance.params,framing:e.provenance.framing},framing:e.provenance.framing.label},d=s.entryKind==="structure",f=kn(t.id,s.id,c),m=c===J?s.label:`${s.label} · ${o.label}`,h={output:s,provenance:e.provenance,task:t.id};if(!d){const b=Oi(i,{id:f,label:m,source:u,payload:s.payload,summary:yn(s),colour:i.byId(f)?.style.colour??l??i.nextColour(),map:c,display:a?s.display??(s.payload.kind==="pairs"?"overlay":"lane"):"overlay",look:s.look??"corner",overlay:this.host.context(t)?.hasMap??!0,under:r});return this.intervals.set(b,h),b}const y=ja(i,f),g=y===f?1:Number(y.slice(f.length+1)),w=i.nextColour();return i.begin({card:"structure",kind:"structure",id:y,label:g>1?`${m} (${g})`:m,source:u,placement:Pi(),style:Fi("structure",w)}),i.update(y,{status:"ready",payload:s.payload,summary:s.payload.kind==="features"?Bi(s.payload.data):yn(s)}),this.intervals.set(y,h),null}carry(){const t=this.host.store();if(t===null)return[];const e=[];for(const s of t.entries){if(s.source.kind!=="computed")continue;const i=this.profiles.get(s.id),o=this.intervals.get(s.id);e.push({entry:s,...i===void 0?{}:{profile:i},...o===void 0?{}:{intervals:o}})}return e}placeOnTarget(t,e,s,i){i!==J&&(t.placeOn(e,i,s),t.unplaceFrom(e,J))}adoptCarried(t){const e=this.host.store();if(!(e===null||t.length===0)){for(const{entry:s,profile:i,intervals:o}of t){const r=s.source;r.kind==="computed"&&(e.begin({card:s.card,kind:s.kind,id:s.id,label:s.label,source:r,placement:s.placement,style:s.style,visible:s.visible,...s.partner===void 0?{}:{partner:s.partner}}),i!==void 0&&(this.profiles.set(s.id,i),this.register(s.id,i.output,i.grid)),o!==void 0&&this.intervals.set(s.id,o),e.update(s.id,{status:s.status,...s.summary===void 0?{}:{summary:s.summary},...s.payload===void 0?{}:{payload:s.payload},...s.fileExtent===void 0?{}:{fileExtent:s.fileExtent}}))}this.host.changed()}}grid(t){return this.host.contigs(t).map(e=>({name:e.name,startBin:e.startBin,bins:e.bins,length:e.length}))}gridFor(t,e){return this.host.context(e)?.binsize===t?this.grid(e):qi(this.host.contigs(e),t)}gridBins(){let t=0;for(const e of this.host.contigs())t=Math.max(t,e.startBin+e.bins);return t}async binVector(t){const e=this.host.annotations(),s=this.host.context();if(e===null||s===null)return;const i=this.host.contigs();if(i.length===0)return;const o=s.binsize,r=this.gridBins();if(!(o>0)||r===0)return;const a=i.filter(m=>m.length>0).map(m=>({contig:m.name,start:0,end:m.length}));let l;try{l=await e.request({kind:"sample",entry:t,regions:a,basesPerPixel:o})}catch{return}const c=new Map(i.map(m=>[m.name,m.startBin])),u=new Float32Array(r).fill(Number.NaN),d=new Float64Array(r),f=new Float64Array(r);for(const m of l.regions){const h=c.get(m.contig);if(h!==void 0)for(let y=0;y<m.values.length;y++){const g=m.values[y];if(!Number.isFinite(g))continue;const w=m.starts[y],b=m.ends[y];if(!(b>w))continue;const S=Math.floor(w/o),A=Math.floor((b-1)/o);for(let v=S;v<=A;v++){const k=h+v;if(k<0||k>=u.length)continue;const M=Math.min(b,(v+1)*o)-Math.max(w,v*o);M>0&&(f[k]+=g*M,d[k]+=M)}}}for(let m=0;m<u.length;m++)d[m]>0&&(u[m]=f[m]/d[m]);return u}laneable(){return this.host.store()!==null&&this.host.annotations()!==null}register(t,e,s){const i=this.host.annotations();if(i===null)return;const o={binsize:e.binsize,firstBin:e.extent[0],values:e.values.slice(),contigs:s};i.request({kind:"register",entry:t,vector:o}).catch(()=>{})}recompute(t){const e=t.source;if(e.kind!=="computed")return;const s=Pe.find(i=>i.id===e.task);s!==void 0&&this.show(s)}createdAt(t){return this.intervals.get(t)?.provenance.createdAt}async exportEntry(t,e){const s=j(new Date),i=_t(t.label);if(e==="anchors"){const a=Be(t);if(a?.kind!=="pairs")return;const l=this.intervals.get(t.id),c=re({kind:"features",data:zi(a.data)},{label:`${t.label} anchors`,...l===void 0?{}:{file:l.provenance.framing.label,created:l.provenance.createdAt}});it(new Blob([c],{type:"text/plain"}),`${i}-anchors-${s}.bed`);return}if(e==="bed"){const a=Be(t);if(a===void 0)return;const l=this.intervals.get(t.id),c={label:t.label,...l===void 0?{}:{file:l.provenance.framing.label,created:l.provenance.createdAt}},u=t.kind==="structure"&&a.kind==="features",d=u?On(a.data,c):re(a,c),f=u?"bed3d":a.kind==="pairs"?"bedpe":"bed";it(new Blob([d],{type:"text/plain"}),`${i}-${s}.${f}`);return}const o=this.intervals.get(t.id);if(o!==void 0&&e==="tsv"){it(new Blob([...ae(o.output,o.provenance)],{type:"text/tab-separated-values"}),Mt(i,o.output,s));return}if(t.source.kind==="derived"){await this.exportDerived(t,e,i,s);return}const r=this.profiles.get(t.id);if(r!==void 0){if(e==="tsv"){it(new Blob([...ae(r.output,r.provenance)],{type:"text/tab-separated-values"}),Mt(i,r.output,s));return}await this.writeProfile(r.output,r.provenance,e,r.grid,i)}}async exportDerived(t,e,s,i){const o=t.derivedFrom,r=this.host.context();if(o===void 0||r===null||e==="bed")return;const a=await gt(`${s}-${i}.${e==="tsv"?"tsv":e==="bedgraph"?"bedGraph":"bw"}`,e==="tsv"?"text/tab-separated-values":e==="bedgraph"?"text/plain":"application/octet-stream");if(a===null)return;const[l,c]=await Promise.all([this.exactSamples(o.a),this.exactSamples(o.b)]),u=Ri(l,c,o.op,"drop");if(u===null)return;const d=u.regions.map(y=>({contig:y.contig,starts:y.starts,ends:y.ends,values:y.values})),f=Qa(t,o.op,r),m=this.host.contigs();if(e==="tsv"){await a.write(new Blob([...mo(t.label,Pn[o.op],d,m,f)],{type:"text/tab-separated-values"}));return}if(e==="bedgraph"){await a.write(new Blob([...Xa(d,m,f)],{type:"text/plain"}));return}const h=await qe({contigs:m.map(y=>({name:y.name,length:y.length})),spans:d});await a.write(h)}async exactSamples(t){const e=this.host.annotations();if(e===null)return null;const s=this.host.contigs().filter(i=>i.length>0);if(s.length===0)return null;try{return await e.request({kind:"sample",entry:t,regions:s.map(i=>({contig:i.name,start:0,end:i.length})),basesPerPixel:1,exact:!0})}catch{return null}}async writeProfile(t,e,s,i,o=_t(t.label)){const r=j(new Date),a=await gt(`${o}-${r}.${s==="bedgraph"?"bedGraph":"bw"}`,s==="bedgraph"?"text/plain":"application/octet-stream");if(a===null)return;if(s==="bedgraph"){await a.write(new Blob([...Za(t,i,e)],{type:"text/plain"}));return}const l=await qe({contigs:i.map(c=>({name:c.name,length:c.length})),values:t.values,firstBin:t.extent[0],binsize:t.binsize});await a.write(l)}}function ja(n,t){if(n.byId(t)===void 0)return t;for(let e=2;e<1e3;e++){const s=`${t}#${e}`;if(n.byId(s)===void 0)return s}return`${t}#${Date.now()}`}function yn(n){const t=n.payload,e=t.data.length,s=n.noun??(t.kind==="pairs"?{one:"pair",many:"pairs"}:{one:"interval",many:"intervals"});return`${z.int(e)} ${e===1?s.one:s.many}`}function Qa(n,t,e){const s=`${e.binsize.toLocaleString()} bp bins`;return{task:`track ${Pn[t]}`,taskVersion:1,params:{operation:t,of:n.label},framing:{uri:e.uri,label:e.hasMap?`two loaded tracks, read onto this file’s ${s}`:`two loaded tracks, read onto the assembly’s ${s}`,binsize:e.binsize,binsPerCell:1,rows:[0,e.nBins],cols:[0,e.nBins],balance:!1,value:"",normalise:null,level:"bin"},app:xn,createdAt:new Date().toISOString()}}function vn(n){return n.entries.map(t=>`${t.id}:${t.kind}:${t.status}:${t.label}`).join("|")}function wn(n){return n.entries.filter(_i).map(t=>`${t.id}:${t.card}:${t.style.shape}`).join("|")}function kn(n,t,e){return e===J?`analysis:${n}:${t}`:`analysis:${e}:${n}:${t}`}export{tl as AnalysisWorkspace,vn as entrySignature,ja as freshId};
|