chromosomix 0.18.0 → 0.19.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 +31 -6
- package/dist/THIRD-PARTY-NOTICES.txt +2 -2
- package/dist/assets/{ConnectCard-CNwlR_yV.js → ConnectCard-Cs0rIBEC.js} +1 -1
- package/dist/assets/{Tour-Dn4L7jES.js → Tour-B3qRVNiU.js} +1 -1
- package/dist/assets/analysis.worker-CC07Gv-8.js +8 -0
- package/dist/assets/{annotations.worker-Bd03nKdJ.js → annotations.worker-Dkfm4-Th.js} +26 -26
- package/dist/assets/index-CPxipgOR.js +579 -0
- package/dist/assets/index-D34Q3Ivo.css +1 -0
- package/dist/assets/{reader.worker-DKXrm0nO.js → reader.worker-BqZlpJND.js} +1 -1
- package/dist/assets/{three-BZagS2ne.js → three-Cfa_LIWm.js} +1 -1
- package/dist/assets/{tutorial-DOptkiKU.js → tutorial-DNkh-qGr.js} +1 -1
- package/dist/assets/workspace-8e1ZWdoH.js +12 -0
- package/dist/index.html +2 -2
- package/dist-cli/THIRD-PARTY-NOTICES.txt +2 -2
- package/dist-cli/chromosomix.mjs +4009 -1076
- package/package.json +5 -1
- package/dist/assets/analysis.worker-2Jx8_NWN.js +0 -8
- package/dist/assets/index-BZqg8J4S.js +0 -106
- package/dist/assets/index-Cxw-esX1.css +0 -1
- package/dist/assets/workspace-ZYKuBclx.js +0 -15
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import{E as Se,F as qe,L as Te,G as xe,H as Ae}from"./index-CPxipgOR.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,12 @@
|
|
|
1
|
+
import{e as p,I as hs,J as B,K as fs,N as pe,O as Nt,P as le,Q as qt,R as Bt,V as un,T as ms,U as ps,W as bt,X as J,L as Z,Y as gs,Z as bs,_ as ge,$ as ys,a0 as dn,a1 as vs,a2 as ws,a3 as hn,a4 as st,a5 as ks,a6 as At,a7 as xs,a8 as Ss,a9 as Ms,aa as $s,ab as Es,ac as Ts,ad as Cs,ae as As,af as fn,b as N,ag as z,ah as Q,ai as Ns,aj as Ls,ak as Os,al as mn,am as pn,an as gn,ao as Is,ap as Fs,aq as Ps,ar as qs,as as Bs,at as be,au as zs,av as Rs,aw as Ds,ax as _s,ay as bn,az as yn,aA as vn,aB as wn,aC as Vs,aD as kt,aE as Ws,aF as Gs,aG as Hs,aH as ye,aI as Ks,aJ as Ys,aK as Us,aL as Zs,aM as ve,aN as Xs,aO as Qs,aP as Js,aQ as js,aR as we,i as ke,aS as ti,aT as Ut,aU as ei,aV as W,aW as ni,aX as X,aY as yt,aZ as kn,a_ as Zt,a$ as si,b0 as ii,b1 as Xt,b2 as oi,b3 as Dt,b4 as ri,b5 as ct,b6 as xe,C as Se,b7 as ai,b8 as xn,b9 as li,ba as ci,bb as ui,bc as Sn,bd as di,be as Me,bf as hi,bg as fi,bh as mi,bi as ft,bj as pi,bk as gi,bl as bi,bm as yi,bn as vi,bo as wi,bp as ki,bq as $e,br as Ee,bs as xi,bt as Si,bu as Mi,bv as Mn,bw as Te,bx as $i}from"./index-CPxipgOR.js";function $n(s,t){if(t===void 0)return"—";if(s.kind!=="number")return String(t);const e=typeof t=="number"?t:Number(t);return Number.isFinite(e)?s.coordinate==="start"?hs(e):s.coordinate==="end"?B.pos(e):s.digits===void 0?B.int(e):s.scientific===!0&&e!==0&&Math.abs(e)<10**-s.digits?e.toExponential(2):e.toFixed(s.digits):"—"}function Ei(s,t){const e=t.filter.trim().toLowerCase();let n=s.rows;e!==""&&(n=n.filter(l=>s.columns.some(c=>$n(c,l[c.key]).toLowerCase().includes(e))));const i=t.sortKey;if(i===null)return n;const o=s.columns.find(l=>l.key===i);if(o===void 0)return n;const r=t.sortDown?-1:1,a=l=>l===void 0||o.kind==="number"&&!Number.isFinite(Number(l));return[...n].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 Ti(s,t){const e=t.columns;if(e===null)return s.columns;const n=s.columns.filter(i=>e.includes(i.key));return n.length===0?s.columns:n}function Ci(s,t,e){const n=Ti(s,t),i=Ei(s,t),o=p("thead",{class:"thead"},p("tr",{},...n.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)"}},...n.map(d=>p("td",{class:d.kind==="number"?"td num":"td",text:$n(d,u[d.key])}))));const a=p("table",{style:{borderCollapse:"collapse",width:"100%",fontVariantNumeric:"tabular-nums"}},o,r),l=s.rows.length===0?"This run produced no rows.":`No row matches “${t.filter}”. ${s.rows.length} were produced.`;return{el:p("div",{class:"analysis-figure-scroll"},i.length===0?p("div",{class:"tempty",text:l}):a),destroy(){}}}function Ai(s,t){const e=s[t];return Array.isArray(e)?e.filter(n=>typeof n=="string"):typeof e=="string"&&e!==""?[e]:[]}function Ni(s,t){let e=null;for(const n of s){if(n.kind!=="region")continue;const i=t[n.key];if(typeof i!="string"||i.trim()==="")continue;const o=n.many===!0?fs(i).map(pe).join(", "):pe(i);o!==i&&(e??={...t},e[n.key]=o)}return e??t}function Li(s,t){const e=s[t];return typeof e=="string"&&e!==""?e:null}function Ce(){const s=new Error("cancelled");return s.name="AbortError",s}function Oi(s){return s.rows[1]<=s.rows[0]&&s.cols[1]<=s.cols[0]}const Ii="chromosomix",Fi="count";function En(s){const t=[],e=[Ii,s.task.id],{framing:n,params:i}=s.provenance,o=Oi(n);o||(e.push(G(n.uri)),Vi(n.uri)&&n.binsize>0&&e.push("--bin-size",String(n.binsize)));const r=s.task.params.some(b=>b.key==="window");if(!o&&!r){const b=Di(n.rows,n.cols,s.context);b.locus!==null&&e.push("--window",G(b.locus)),b.note!==null&&t.push(b.note)}const a=s.task.params.find(b=>b.key==="balance"),l=a!==void 0&&Nt(a),c=l&&typeof i.balance=="boolean"?i.balance:n.balance;!o&&!c&&e.push("--no-balance"),!o&&l&&c!==n.balance&&t.push(`The map was drawn ${n.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=(n.circular??[]).filter(b=>b!=="");u.length>0&&e.push("--circular",G(u.join(",")));const d=Object.entries(n.origins??{}).filter(([b,S])=>b!==""&&Number.isFinite(S));if(d.length>0&&e.push("--origin",G(d.map(([b,S])=>`${b}:${S+1}`).join(","))),!o){n.value!==""&&n.value!==Fi&&e.push("--value",G(n.value)),n.contacts!==void 0&&e.push("--contacts",String(n.contacts)),n.coarsen!==void 0&&e.push("--coarsen",String(n.coarsen)),n.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=s.context?.selectedCells??[];b.length>0?e.push("--cell",G(b.join(","))):s.context!==null&&(s.context.cells??0)>0&&(s.context.activeCells??s.context.cells??0)<(s.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(s.task.needsPeers===!0){const b=s.context?.peers??[];for(const S of b)e.push("--against",G(S.uri));b.length===0&&t.push(`${s.task.id} compares this map with the others on screen, and the record does not name them. Add --against <file> for each.`)}const f=s.context?.entries??[],m=[],h=new Set,y=Pi(s.task);for(const b of s.task.params)if(Tn(b))for(const S of Cn(i[b.key])){const A=An(f,S);if(A===null){t.push(`--${b.key} named something with no file behind it${zi(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} ${G(A)}`;m.includes(k)||m.push(k)}for(const b of m)e.push(...b.split(" "));for(const b of s.task.params){if(b.key==="balance"&&Nt(b)||h.has(b.key)||b.retired===!0&&qi(b,i[b.key]))continue;const S=Bi(b,i[b.key],f);S!==null&&e.push(...S)}const g=e.join(" ");return{text:[...t.map(b=>`# ${b}`),g].join(`
|
|
2
|
+
`)}}function Pi(s){const t=s.params.filter(e=>e.kind==="sequence"&&e.multiple!==!0);return t.some(e=>e.key==="sequence")?"sequence":s.upstreamParams===void 0||(s.requires??[]).length===0?null:t.length===1?t[0].key:null}function qi(s,t){const e=qt([s])[s.key];return Array.isArray(e)||Array.isArray(t)?Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((n,i)=>n===t[i]):t===void 0||t===e}function Tn(s){return s.kind==="featureSet"||s.kind==="pairSet"||s.kind==="track"||s.kind==="sequence"}function Cn(s){return typeof s=="string"?s===""?[]:[s]:Array.isArray(s)?s.filter(t=>typeof t=="string"):[]}function Bi(s,t,e){if(t==null)return null;if(Tn(s)){const n=Cn(t).map(i=>An(e,i)).filter(i=>i!==null);return n.length===0?null:[`--${s.key}`,G(n.join(","))]}if(typeof t=="boolean")return[t?`--${s.key}`:`--${s.key}=false`];if(Array.isArray(t)){const n=t.filter(i=>i!=null).map(String);return n.length===0?null:[`--${s.key}`,G(n.join(","))]}return typeof t=="number"?Number.isFinite(t)?[`--${s.key}`,String(t)]:null:t===""?null:[`--${s.key}`,G(String(t))]}function An(s,t){const e=s.find(i=>i.id===t);if(e===void 0)return null;const n=e.source;return n.kind==="local"||n.kind==="detached"?n.name:n.kind==="remote"?Ri(n.url):null}function zi(s,t){const e=s.find(n=>n.id===t);return e===void 0?"":` (“${e.label}”)`}function Ri(s){const e=s.split(/[?#]/)[0].split("/").filter(n=>n!=="").pop();return e===void 0||e===""?s:e}function Di(s,t,e){if(e===null)return{locus:null,note:null};const n=e.nBins;if(s[0]===0&&s[1]>=n&&t[0]===0&&t[1]>=n||n===0)return{locus:null,note:null};if(s[0]!==t[0]||s[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]===s[0]&&c.extent[1]===s[1]);if(o!==void 0)return{locus:o.name,note:null};const r=_i(e.contigs,s);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(s[0]===r.startBin&&s[1]>=r.startBin+r.bins)return{locus:r.name,note:null};const a=(s[0]-r.startBin)*e.binsize,l=Math.min(r.length,(s[1]-r.startBin)*e.binsize);return{locus:le({contig:r.name,start:a,end:l}),note:null}}function _i(s,t){for(const e of s){if(e.bins===0)continue;const n=e.startBin,i=e.startBin+e.bins;if(t[0]>=n&&t[1]<=i)return e}return null}function G(s){return s===""?"''":/^[A-Za-z0-9_@%+=:,./-]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Vi(s){return/\.pairs(\.b?gz)?$/i.test(s.split("::")[0].split(/[?#]/)[0])}const Wi=[un,ms].filter(s=>s!=="").join(" ");function Gi(s,t,e){return{task:s.id,taskVersion:s.version,params:t,framing:e,app:Wi,createdAt:new Date().toISOString()}}function Ae(s){const{task:t,provenance:e,context:n,where:i}=s,o=En({task:t,provenance:e,context:n}),r=Bt(e),a=i===void 0?{}:{where:i},l=o.text.split(`
|
|
3
|
+
`);return{kind:"run",line:l[l.length-1],shell:!0,notes:l.slice(0,-1),detail:r,...a}}function Nn(s,t){return Hi(s.params,t.params)&&Yi(s.framing,t.framing)}function Hi(s,t){const e=Object.keys(s);if(e.length!==Object.keys(t).length)return!1;for(const n of e)if(!(n in t)||!Ki(s[n],t[n]))return!1;return!0}function Ki(s,t){return Array.isArray(s)||Array.isArray(t)?!Array.isArray(s)||!Array.isArray(t)||s.length!==t.length?!1:s.every((e,n)=>e===t[n]):Object.is(s,t)}function Yi(s,t){return s.uri===t.uri&&s.rows[0]===t.rows[0]&&s.rows[1]===t.rows[1]&&s.cols[0]===t.cols[0]&&s.cols[1]===t.cols[1]&&s.binsize===t.binsize&&s.binsPerCell===t.binsPerCell&&s.balance===t.balance&&s.value===t.value&&s.level===t.level&&(s.contacts??null)===(t.contacts??null)&&(s.edit??null)===(t.edit??null)&&(s.coarsen??null)===(t.coarsen??null)&&Ui(s.circular??[],t.circular??[])&&Zi(s.origins??{},t.origins??{})}function Ui(s,t){if(s.length!==t.length)return!1;const e=new Set(s);return t.every(n=>e.has(n))}function Zi(s,t){const e=Object.keys(s);return e.length===Object.keys(t).length&&e.every(n=>s[n]===t[n])}const Xi=100;function lt(s,t){return`${s}\0${t}`}const Qi=8;function _t(s,t){return`${s}\0${t}`}function Ji(s,t,e,n,i,o){const r=t===void 0||t.length===0?s:`${s}\0${t.join("\0")}`,a=e===void 0?r:`${r}\0${e.base}:${e.rungs}`,l=n===void 0?a:`${a}\0contacts:${n.contacts}:${n.seed??""}:${n.alpha??""}`,c=i===void 0?l:`${l}\0edit:${vs(i)}`;return o===void 0?c:`${c}\0coarsen:${o}`}function Ne(s){return dn(s.label)}function ji(s){return{line:s.line,notes:s.notes??[],detail:s.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 ps){this.host=t,this.makeClient=e}stateOf(t){return this.states.get(t)??{status:"idle"}}holdFile(t,e,n){const i=_t(t,e);n===null?this.held.delete(i):this.held.set(i,n)}heldFile(t,e){return this.held.get(_t(t,e))}resultOf(t,e){const n=e??this.homeOf(t);return this.results.get(lt(n,t))??null}homeOf(t){const e=this.host.task?.(t)??bt(t);return e!==void 0&&!J(e)?Z:this.host.targetMap?.()??Z}runsOf(t,e){const n=e??this.homeOf(t),i=lt(n,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?.()??[],n=new Set,i=[];for(const o of e){const r=this.results.get(lt(o.map,t));r!==void 0&&(n.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||n.has(a.map)||o===lt(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,n){if(!J(t)){this.queueOne(t,e,null);return}if(n.length!==0){if(n.length===1){this.queueOne(t,e,null,n[0]);return}this.cancel(t.id),n.forEach((i,o)=>{this.queueOne(t,e,{at:o,of:n.length},i)})}}queueOne(t,e,n,i){if(this.destroyed)return;const o=this.host.context(t);if(o===null){this.refuse(t,n,"nothing is open");return}const r=t.mapless===!0?Le(o,"sequences"):o.framing??(t.venue==="annotations"?Le(o):null);if(r===null){this.refuse(t,n,"this view has no contact map to run against");return}const a=J(t)?i??this.hostTarget(r,t):{...this.hostTarget(r,t),map:Z};if(n===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:n,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 n=this.host.source(e);return{map:this.host.targetMap?.()??Z,uri:n?.uri??t.uri,...n===null?{}:{source:n.source},...n?.cells===void 0?{}:{cells:n.cells},...n?.binning===void 0?{}:{binning:n.binning},...n?.orientation===void 0?{}:{orientation:n.orientation},...n?.pairsStats===void 0?{}:{pairsStats:n.pairsStats},...n?.resample===void 0?{}:{resample:n.resample},...n?.edit===void 0?{}:{edit:n.edit},label:n?.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 n=this.current;if(n===null||n.task.id!==t){e>0&&this.setState(t,{status:"cancelled"});return}n.cancelled=!0,n.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 n=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(n=r[c],t.cancelled)throw Ce();const u=n.task.id===t.task.id,d=this.results.get(lt(t.target.map,n.task.id));if(!u&&d!==void 0&&Nn(d.provenance,{params:n.params,framing:t.framing})){l[n.task.id]=d;continue}const f=await this.runStep(t,a,n,r,c,l,e);if(t.cancelled)throw Ce();const m=lt(t.target.map,n.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,Qi))}this.results.set(m,f),this.resultTargets.set(m,t.target),u?(this.setState(n.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,...ji(Ae({task:t.task,provenance:this.recordable(t,f.provenance),context:this.host.context(t.task),where:Ne(t.target)}))}):(l[n.task.id]=f,this.setState(n.task.id,{status:"done",result:f,ms:f.ms}))}}catch(r){const a=t.cancelled||gs(r),l=a?{status:"cancelled"}:{status:"failed",message:r instanceof Error?r.message:String(r)};n!==null&&n.task.id!==t.task.id&&this.setState(n.task.id,l),this.setState(t.task.id,l),o=a?{status:"cancelled"}:{status:"failed",error:r instanceof Error?r.message:String(r)}}finally{t.running=null,bs(i,o??{status:"cancelled"})}}refuse(t,e,n){this.setState(t.id,{status:"failed",message:n}),!(e!==null&&e.at>0)&&ge({kind:"run",line:`ran ${t.title}`,status:"failed",error:n})}recordStart(t){const e=Ae({task:t.task,provenance:this.recordable(t,Gi(t.task,t.params,t.framing)),context:this.host.context(t.task),where:Ne(t.target)});return ge({...e,status:"running"})}recordable(t,e){const n=t.target.uri;return n===""||n===e.framing.uri?e:{...e,framing:{...e.framing,uri:n}}}async mount(t,e,n){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=Ji(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:n,...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,n,i,o,r,a){const l=m=>{const h=m===void 0||m===""?"":m;if(i.length===1)return h===""?n.task.title:h;const y=`${n.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:n.task.id,params:Ni(n.task.params,n.params),framing:t.framing,inputs:await this.inputsFor(n,t,r)};let d;if(n.task.venue==="annotations"){const m=this.host.annotations?.();if(m==null)throw new Error(`${n.task.title} runs against the loaded tracks, and this session has no annotations worker.`);const h=m.cancellable(u,c);t.running={id:n.task.id,handle:h},d=await h.promise,t.running=null}else{const m=e.cancellable(u,c);t.running={id:n.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:n.params,taskVersion:n.task.version}}}ensureClient(){return this.client??=this.makeClient(),this.client}plan(t,e){const n=[],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)??bt(c);if(u===void 0)throw new Error(`${a.id} requires the task ${c}, which this session does not offer`);const d=ys(a,c,l);d!==null&&r(u,{...qt(u.params),...d})}o.delete(a.id),i.add(a.id),n.push({task:a,params:l})}};return r(t,e),n}async inputsFor(t,e,n){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 eo(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(_t(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(n).length>0&&(u.upstream={...n}),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)}t.task.id==="mapreport"&&e.target.source!==void 0&&e.target.binning===void 0&&(u.self={label:e.target.label,uri:e.target.uri,source:e.target.source,...e.target.cells===void 0?{}:{cells:e.target.cells},...e.target.resample===void 0?{}:{resample:e.target.resample}});const d=this.hostBlockFor(e),f=(i.contacts??null)===(e.target.resample?.contacts??null);return d!==null&&f&&no(d)&&so(d,i)&&(u.block=d),u}hostBlockFor(t){const e=this.host.targetMap?.()??Z;return t.framing.coarsen!==void 0?null:t.target.map===e?this.host.block():null}setState(t,e,n=!1){this.states.set(t,e),n?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=Xi-(performance.now()-this.lastNotifiedAt);if(t<=0){this.notifyNow();return}this.trailing===null&&(this.trailing=setTimeout(()=>{this.trailing=null,this.notifyNow()},t))}}function eo(s,t){if(s.multiple===!0)return Ai(t,s.key).map(n=>[`${s.key}:${n}`,n]);const e=Li(t,s.key);return e===null?[]:[[s.key,e]]}function no(s){return s.values.byteLength<=ws}function so(s,t){return s.rowExtent[0]===t.rows[0]&&s.rowExtent[1]===t.rows[1]&&s.colExtent[0]===t.cols[0]&&s.colExtent[1]===t.cols[1]&&s.binsPerCell===t.binsPerCell}function Le(s,t="loaded tracks"){return{uri:s.uri,rows:[0,0],cols:[0,0],binsize:s.binsize,binsPerCell:1,balance:!1,value:"count",normalise:null,level:"bin",label:`${dn(s.uri)} · ${t}, no contact map`,...s.circular===void 0?{}:{circular:[...s.circular]},...s.origins===void 0?{}:{origins:{...s.origins}}}}const io="map";function oo(s,t){const e=new Map,n=[];for(const r of s)for(const a of r.result.outputs)e.has(a.id)||(e.set(a.id,[]),n.push(a.id)),e.get(a.id)?.push({label:r.label,output:a});const i=[],o=[];for(const r of n){const a=e.get(r)??[];if(a.some(d=>ro(d.output))){i.push(ao(r,a));continue}const l=a.filter(d=>d.output.kind==="table");if(l.length>0&&l.length===a.length){i.push(lo(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(co(r,u))}return{outputs:i,perMapOnly:o}}function ro(s){return(s.kind==="curve"||s.kind==="matrix"||s.kind==="table")&&s.acrossMaps===!0}function ao(s,t){const e=i=>i.kind==="curve"?i.series.length:i.kind==="matrix"?i.nrows:i.kind==="table"?i.rows.length:0;let n=t[0].output;for(const i of t)e(i.output)>e(n)&&(n=i.output);return{...n,id:`${s}__all`,label:`${n.label} — all maps`}}function lo(s,t){const e=[],n=new Set;for(const a of t)for(const l of a.output.columns)n.has(l.key)||(n.add(l.key),e.push(l));let i=io;for(;n.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:`${s}__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 co(s,t){const e=t.every(a=>a.curve.series.length===1),n=[];for(const a of t)for(const l of a.curve.series)n.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:`${s}__all`,label:`${i.label} — all maps`,series:n,xLabel:i.xLabel,yLabel:i.yLabel,xScale:i.xScale,yScale:i.yScale,...r?{xTicks:[...o]}:{}}}function wt(s){return s.filter(t=>Number.isFinite(t)).sort((t,e)=>t-e)}function it(s,t){if(s.length===0)return Number.NaN;if(s.length===1)return s[0];const e=(s.length-1)*Math.min(1,Math.max(0,t)),n=Math.floor(e),i=Math.ceil(e);return n===i?s[n]:s[n]+(e-n)*(s[i]-s[n])}function Ln(s){const t=wt(s);if(t.length===0)return{low:Number.NaN,q1:Number.NaN,median:Number.NaN,q3:Number.NaN,high:Number.NaN,outliers:[]};const e=it(t,.25),n=it(t,.5),i=it(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=n),Number.isFinite(c)||(c=n),{low:l,q1:e,median:n,q3:i,high:c,outliers:u}}function zt(s,t=0){const e=wt(s);if(e.length===0)return{edges:[],counts:[]};const n=e[0],i=e[e.length-1];if(n===i)return{edges:[n,n+1],counts:[e.length]};let o=Math.round(t);if(!(o>0)){const c=it(e,.75)-it(e,.25),u=c>0?2*c/Math.cbrt(e.length):0;o=u>0?Math.ceil((i-n)/u):Math.ceil(Math.sqrt(e.length))}o=Math.max(1,Math.min(400,o));const r=(i-n)/o,a=[];for(let c=0;c<=o;c++)a.push(n+c*r);const l=new Array(o).fill(0);for(const c of e){const u=Math.floor((c-n)/r);l[u>=o?o-1:u<0?0:u]+=1}return{edges:a,counts:l}}function Oe(s,t=64){const e=wt(s);if(e.length<2)return{at:[],y:[]};const n=e.length,i=e.reduce((g,w)=>g+w,0)/n,o=e.reduce((g,w)=>g+(w-i)**2,0)/(n-1),r=Math.sqrt(Math.max(0,o)),a=it(e,.75)-it(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(n,-.2):0;if(!(c>0))return{at:[],y:[]};const u=e[0]-3*c,f=(e[n-1]+3*c-u)/Math.max(1,t-1),m=[],h=[],y=1/(n*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 uo={"&":"&","<":"<",">":">",'"':""","'":"'"};function ot(s){return s.replace(/[&<>"']/g,t=>uo[t]??t)}function Vt(s){return`<div class="figure-tip-head">${ot(s)}</div>`}function ho(s){return typeof s!="string"||s===""?"":`<svg class="figure-tip-swatch" viewBox="0 0 10 10" aria-hidden="true"><circle cx="5" cy="5" r="5" fill="${ot(s)}"/></svg>`}function xt(s,t,e){return`<div class="figure-tip-row">${ho(s)}<span class="figure-tip-name">${ot(t)}</span><span class="figure-tip-value">${ot(e)}</span></div>`}function fo(s,t,e){return s.measure?.(t,e)??t.length*e*.6}function On(s,t,e,n){const i=e.colours[s.id];return i!==void 0?i:s.colour!==void 0?s.colour:n.series[t%n.series.length]}function Qt(s,t){return ks(t.mark)?t.mark:s.mark??t.mark}function H(s,t){return!Number.isFinite(s)||t&&s<=0?null:s}function mo(s,t){const e=t.x.scale==="log",n=t.y.scale==="log",i=[];for(let o=0;o<s.y.length;o++){const r=H(s.x[o]??o,e),a=H(s.y[o],n);i.push(r===null||a===null?null:[r,a])}return i}function In(s){const t=s.binsize;if(t!==void 0)return n=>B.bp(n*t);if(/\(bp\)/i.test(s.xLabel??""))return n=>B.bp(n);const e=s.xTicks;if(e!==void 0)return n=>Number.isInteger(n)?e[n]??"":""}function Fn(s){if(/\(%\)/.test(s.yLabel??""))return t=>{const e=t*100;return B.pct(t,Math.abs(e-Math.round(e))<1e-9?0:1)}}const po=["high","upper quartile","median","lower quartile","low"];function gt(s){return typeof s=="number"&&Number.isFinite(s)}function go(s){const t=Array.isArray(s)?s[1]:s;return gt(t)?t:null}function bo(s,t){const e=t.mark==="histogram",n=t.x.scale==="log"?"log":"linear",i=t.y.scale==="log"?"log":"linear",o=e?void 0:In(s),r=e?void 0:Fn(s),a=c=>{const u=o?.(c)??"";return u!==""?u:st(c,n)},l=r??(c=>st(c,i));return c=>{if(Array.isArray(c)){const h=c[0];if(h===void 0)return"";const y=c.flatMap(g=>{const w=go(g.value);return w===null?[]:[xt(g.color,g.seriesName??"",l(w))]});return Vt(gt(h.axisValue)?a(h.axisValue):"")+y.join("")}if(c.seriesType==="boxplot"){const h=Array.isArray(c.value)?c.value.slice(-5):[],y=Vt(c.name??"");if(h.length!==5||!h.every(gt))return y;const g=[...h].reverse();return y+po.map((w,b)=>xt(null,w,st(g[b],i))).join("")}const u=Vt(c.seriesName??"");if(c.seriesType==="custom")return u;const d=Array.isArray(c.value)?c.value:[],[f,m]=d;return!gt(f)||!gt(m)?u:u+(e?xt(c.color,a(f),B.int(m)):xt(c.color,a(f),l(m)))}}function U(s,t,e){return{axisLine:{onZero:!1,lineStyle:{color:s.ink,width:Jt}},axisTick:{lineStyle:{color:s.ink,width:Jt}},axisLabel:{color:s.muted,fontSize:t.fontSize,fontFamily:s.fontFamily},nameTextStyle:{color:s.ink,fontSize:t.fontSize,fontFamily:s.fontFamily},splitLine:{show:e,showMinLine:!1,showMaxLine:!1,lineStyle:{color:s.grid,type:"solid",width:yo}}}}const Jt=1,yo=.5;function Pn(s){return{show:!0,backgroundColor:"transparent",borderColor:s.ink,borderWidth:Jt,z:3}}const St=.05;function Mt(s,t,e){let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of s)!Number.isFinite(r)||t&&r<=0||(r<n&&(n=r),r>i&&(i=r));if(!(n<i))return null;if(!(e>0))return[n,i];if(t){const r=Math.log10(n),a=Math.log10(i),l=(a-r)*e;return[10**(r-l),10**(a+l)]}const o=(i-n)*e;return[n-o,i+o]}function ce(s,t,e){const n=s.series.filter(c=>!t.hidden.includes(c.id));if(t.mark==="histogram"){if(e==="y")return null;const c=n.flatMap(u=>zt(u.y,t.bins).edges);return Mt(c,t.x.scale==="log",St)}if(hn(t.mark))return e==="x"?null:Mt(Lo(n,t),t.y.scale==="log",St);const i=n.map(c=>Qt(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 n){const d=t.bands&&u.low!==void 0&&u.high!==void 0;for(let f=0;f<u.y.length;f++){const m=H(u.x[f]??f,o);if(m===null)continue;(H(u.y[f],r)!==null||d&&H(u.low[f],r)!==null&&H(u.high[f],r)!==null)&&c.push(m)}}return Mt(c,o,i.includes("points")?St:0)}const a=t.x.domain,l=[];for(const c of n){const u=Qt(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)vo(c,f,a,u,o,r,l)}return Mt(l,r,St)}function vo(s,t,e,n,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=H(s.x[c]??c,i),d=H(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&&n&&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 qn(s,t){if(!(s>0)||!(t>s))return null;const e=Math.log10(s),n=Math.log10(t);if(n-e>=10){const u=Math.ceil((n-e)/6),d=[];for(let f=Math.ceil(e/u)*u;f<=n+1e-9;f+=u)d.push(10**f);return d}if(Math.floor(n+1e-9)-Math.ceil(e-1e-9)+1>=3)return null;const i=u=>u>=s*(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(n);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-s)/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(s/l);u*l<=t*(1+1e-12);u++)c.push(Number((u*l).toPrecision(12)));return c}function Lt(s,t,e){const n=t.mark==="histogram";if(n&&e==="y")return{bounds:{},labels:{}};const i=t[e].scale==="log",r=s.series.filter(d=>!t.hidden.includes(d.id)).flatMap(d=>n?zt(d.y,t.bins).edges:e==="x"?d.x:d.y),a=jt(t[e].domain,ce(s,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"?qn(l,c):null;return u===null?a:{...a,labels:Bn(a.labels,u,l,c),ticks:u}}function Bn(s,t,e,n){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={...s};return i(t[0],e)||delete o.showMinLabel,i(t[t.length-1],n)||delete o.showMaxLabel,o}function Ie(s){return s===null?{start:0,end:100}:{startValue:s[0],endValue:s[1]}}function wo(s){const t=s.legend;if(t===void 0||t.show===!1||!Array.isArray(t.data)||t.selected===void 0)return s;const e=t.selected;return{...s,legend:{...t,data:t.data.filter(n=>e[String(n)]!==!1)}}}const Fe=28,nt={right:8,padding:5,icon:25,iconGap:5},ko=.35,xo=72;function So(s,t,e){if(e(s)<=t)return[s];const n=[];let i="";for(const l of s)i+=l,".-_:/, ".includes(l)&&(n.push(i),i="");i!==""&&n.push(i);const o=[];let r="";const a=()=>{const l=r.trimEnd();l!==""&&o.push(l),r=""};for(const l of n){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 Mo(s,t,e,n){const i=u=>fo(e,u,t.fontSize),o=nt.right+2*nt.padding+nt.icon+nt.iconGap,r=t.fontSize,a=n===void 0?Number.POSITIVE_INFINITY:Math.max(xo,n.width*ko-o-r),l=new Map(s.map(u=>[u,So(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(`
|
|
4
|
+
`)}}function $o(s,t,e,n){const i=s.series.map((m,h)=>({series:m,index:h,colour:On(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=hn(t.mark),l=a?"none":t.legend,c=l==="right"?Mo(o,t,e,n):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:nt.right,top:"middle",padding:nt.padding,itemWidth:nt.icon,...c===null?{}:{formatter:c.formatter}}:t.legend==="top"?{orient:"horizontal",top:4,left:"center"}:{orient:"horizontal",bottom:4,left:"center"}},d={...Pn(e),left:8,right:c===null?16:c.room,top:l==="top"?Fe+8:16,bottom:l==="bottom"?Fe+8:8,outerBoundsMode:"same"},f=a?No(s,t,e,i):Eo(s,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:bo(s,t)}:{show:!1},...f}}function jt(s,t,e,n){const i=c=>{const u=c[1]-c[0];return{...Pe(c[0],u,n)?{}:{showMinLabel:!1},...Pe(c[1],u,n)?{}:{showMaxLabel:!1}}};if(s===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],s[0]),max:Math.max(t[1],s[1])},labels:i(s)};let o=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const c of e)!Number.isFinite(c)||n&&c<=0||(c<o&&(o=c),c>r&&(r=c));const a=o>r||s[0]<o,l=o>r||s[1]>r;return{bounds:{...a?{min:s[0]}:{},...l?{max:s[1]}:{}},labels:i(s)}}function Pe(s,t,e){if(e){if(!(s>0))return!1;const i=Math.log10(s);return Math.abs(i-Math.round(i))<1e-9}if(!Number.isFinite(s)||!(t>0))return!1;const n=s/10**(Math.floor(Math.log10(t))-1);return Math.abs(n-Math.round(n))<1e-6*Math.max(1,Math.abs(n))}function Eo(s,t,e,n){const i=t.mark==="histogram",o=[],r=Math.max(1,n.filter(h=>!h.hidden).length),a=Math.max(.07,.35/Math.sqrt(r));for(const h of n){if(i){o.push(...Ao(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(...Co(h,t)),o.push(To(h,t,a))}const l=t.x.label??(i?s.yLabel:s.xLabel),c=t.y.label??(i?"count":s.yLabel),u=i?void 0:In(s),d=i?void 0:Fn(s),f=Lt(s,t,"x"),m=Lt(s,t,"y");return{xAxis:{type:t.x.scale==="log"?"log":"value",name:l,nameLocation:"middle",nameGap:t.fontSize*2.4,scale:!0,...s.xTicks!==void 0&&!i?{minInterval:1}:{},...i?{containShape:!1}:{},...f.bounds,...U(e,t,t.x.grid),...f.ticks===void 0?{}:{axisTick:{...U(e,t,t.x.grid).axisTick,customValues:f.ticks}},axisLabel:{...U(e,t,t.x.grid).axisLabel,...f.ticks===void 0?{}:{customValues:f.ticks},...i?{}:{hideOverlap:!0},...f.labels,formatter:u??(h=>st(h,t.x.scale==="log"?"log":"linear"))},axisPointer:{label:{formatter:qe(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,...U(e,t,t.y.grid),...m.ticks===void 0?{}:{axisTick:{...U(e,t,t.y.grid).axisTick,customValues:m.ticks}},axisLabel:{...U(e,t,t.y.grid).axisLabel,...m.ticks===void 0?{}:{customValues:m.ticks},...i?{}:{hideOverlap:!0},...m.labels,formatter:d??(h=>st(h,t.y.scale==="log"?"log":"linear"))},axisPointer:{label:{formatter:qe(d,t.y.scale)}}},dataZoom:[{id:ue,type:"inside",xAxisIndex:0,zoomOnMouseWheel:!0,moveOnMouseMove:!0,filterMode:"none",...Ie(t.x.domain)},{id:de,type:"inside",yAxisIndex:0,zoomOnMouseWheel:"shift",moveOnMouseMove:!1,filterMode:"none",...Ie(t.y.domain)}],series:o}}const ue="zoom-x",de="zoom-y";function qe(s,t){return({value:e})=>{if(typeof e!="number"||!Number.isFinite(e))return"";const n=s?.(e)??"";return n!==""?n:st(e,t==="log"?"log":"linear")}}function To(s,t,e){const n=Qt(s.series,t),i=mo(s.series,t),o={id:s.series.id,name:s.series.name,data:i,color:s.colour,emphasis:{focus:"series"}};if(n==="points")return{...o,type:"scatter",symbolSize:t.pointSize,itemStyle:{color:s.colour,opacity:.85}};if(n==="bars")return{...o,type:"bar",itemStyle:{color:s.colour},barMaxWidth:24,...s.series.stack===void 0?{}:{stack:s.series.stack}};const r=n==="area"||t.fillArea;return{...o,type:"line",step:n==="step"?"middle":!1,smooth:t.smooth,symbol:"none",lineStyle:{width:t.lineWidth,color:s.colour},...r?{areaStyle:{color:s.colour,opacity:e,origin:"auto"}}:{},connectNulls:!1,sampling:"lttb"}}function Co(s,t){const e=s.series.low,n=s.series.high,i=t.y.scale==="log",o=t.x.scale==="log",r=[],a=[];for(let u=0;u<e.length;u++){const d=H(s.series.x[u]??u,o),f=H(e[u],i),m=H(n[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-${s.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:`${s.series.name} ${l}-low`,data:r},{...c,id:`${l}-high`,name:`${s.series.name} ${l}-high`,data:a,areaStyle:{color:s.colour,opacity:.18}}]}function Ao(s,t,e){const{edges:n,counts:i}=zt(s.series.y,t.bins);if(i.length===0)return[];const o=i.map((r,a)=>[(n[a]+n[a+1])/2,r]);return[{id:s.series.id,name:s.series.name,type:"bar",data:o,color:s.colour,barGap:"-100%",barCategoryGap:"1%",itemStyle:{color:s.colour,opacity:e}}]}function No(s,t,e,n){const i=n.filter(d=>!d.hidden),o=i.map(d=>d.series.name),r=t.y.label??s.yLabel,a=t.mark==="box"?zn(i,t,e):Oo(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)=>wt(d.series.y).map(m=>[f,m]))});const l=t.y.scale==="log",c=t.y.domain??ce(s,t,"y"),u=l&&c!==null?qn(c[0],c[1]):null;return{legend:{show:!1},xAxis:{type:"category",data:o,...U(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]},...U(e,t,t.y.grid),...u===null?{}:{axisTick:{...U(e,t,t.y.grid).axisTick,customValues:u}},axisLabel:{...U(e,t,t.y.grid).axisLabel,...c===null?{}:u===null?jt(c,null,[],l).labels:Bn(jt(c,null,[],l).labels,u,c[0],c[1]),...u===null?{}:{customValues:u},formatter:d=>st(d,l?"log":"linear")}},series:a}}function Lo(s,t){const e=t.mark==="violin"?s.map(o=>Rn(o.y,t.y.scale==="log")):[],n=e.some(o=>o.y.some(r=>r>0)),i=[];return s.forEach((o,r)=>{if(n)for(const a of e[r].at)i.push(a);else{const a=Ln(o.y);i.push(a.low,a.high,...a.outliers)}if(t.jitter)for(const a of o.y)i.push(a)}),i}function zn(s,t,e){const n=s.map(i=>Ln(i.series.y));return[{id:"box",name:"box",type:"boxplot",data:n.map((i,o)=>({value:[i.low,i.q1,i.median,i.q3,i.high],itemStyle:{color:s[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:n.flatMap((i,o)=>i.outliers.map(r=>[o,r]))}]}function Oo(s,t,e){const n=t.y.scale==="log",i=s.map(r=>Rn(r.series.y,n)),o=Math.max(0,...i.flatMap(r=>r.y));return o>0?s.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}})):zn(s,t,e)}function Rn(s,t){if(!t)return Oe(s);const e=wt(s).filter(i=>i>0).map(i=>Math.log10(i)),n=Oe(e);return{at:n.at.map(i=>10**i),y:n.y}}const Io=2e4;function Ot(s){const t=s.nrows*s.ncols;return t>0&&t<=Io&&s.large!==!0&&s.aspect!=="fill"}const Be=32;function Fo(s){const t=Ms(s)?s:Ss,e=[];for(let n=0;n<Be;n++)e.push(xs(t,n/(Be-1)));return e}function Po(s,t){let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(const o of s.values)Number.isFinite(o)&&(o<e&&(e=o),o>n&&(n=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(n)?n:1);if(o<r)return{vmin:o,vmax:r}}if(s.range!==void 0&&s.range[1]>s.range[0])return{vmin:s.range[0],vmax:s.range[1]};if(!(e<=n))return null;if(s.centre!==void 0){const o=s.centre,r=Math.max(Math.abs(n-o),Math.abs(e-o))||1;return{vmin:o-r,vmax:o+r}}return{vmin:e,vmax:n>e?n:e+1}}function It(s,t){const e=new Array(Math.max(0,t)).fill("");if(s.length===0||t<=0)return e;if(s.length===t){for(let n=0;n<t;n++)e[n]=s[n]??"";return e}return s.length===1?(e[Math.floor((t-1)/2)]=s[0],e):(s.forEach((n,i)=>{const o=Math.round(i*(t-1)/(s.length-1));(e[o]===""||i===s.length-1)&&(e[o]=n)}),e)}function qo(s){const t=[];for(let e=0;e<s.nrows;e++)for(let n=0;n<s.ncols;n++){const i=s.values[e*s.ncols+n];Number.isFinite(i)&&t.push([n,s.nrows-1-e,i])}return t}function Bo(s){const t=new Map;for(const e of[...s?.top??[],...s?.right??[]]){const n=t.get(e.name)??{lo:Number.POSITIVE_INFINITY,hi:Number.NEGATIVE_INFINITY};for(const i of e.values)Number.isFinite(i)&&(i<n.lo&&(n.lo=i),i>n.hi&&(n.hi=i));t.set(e.name,n)}return t}function ze(s,t,e,n,i,o,r){return s.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:n,yAxisIndex:n,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 Re(s,t,e){const n={type:"value",gridIndex:s,min:-.5,max:t-.5,show:!1},i={type:"value",gridIndex:s,min:0,max:1,show:!1};return e?[i,n]:[n,i]}function zo(s,t,e,n){const i=Po(s,t),o=t.fontSize,r=(s.margins?.top??[]).filter(E=>E.values.length>0),a=(s.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=Bo(s.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=s.stats??[],b=(s.xLabel===""?0:o*1.6)+(w.length>0?o*1.8:0),S={left:s.yLabel===""?o*3.5:o*5,right:g,top:h,bottom:o*2.6+b},A=Math.max(1,n.width-S.left-S.right),v=Math.max(1,n.height-S.top-S.bottom),k=Math.max(1,s.ncols),$=Math.max(1,s.nrows),x=s.aspect==="fill"?{width:A/k,height:v/$}:(()=>{const E=Math.min(A/k,v/$);return{width:E,height:E}})(),M={left:S.left+(A-x.width*k)/2,top:S.top+(v-x.height*$)/2,width:x.width*k,height:x.height*$,containLabel:!1,...Pn(e)},T=[M],C=[],O=[],I=[],F=(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:It(s.xTicks,s.ncols),name:s.xLabel,nameLocation:"middle",nameGap:o*2.2,...F(s.xTicks,s.ncols)}),O.push({type:"category",gridIndex:0,data:[...It(s.yTicks,s.nrows)].reverse(),name:s.yLabel,nameLocation:"middle",nameGap:o*3.4,...F(s.yTicks,s.nrows)}),I.push({type:"heatmap",id:"matrix",name:s.label,data:qo(s),xAxisIndex:0,yAxisIndex:0,itemStyle:{borderWidth:0},emphasis:{itemStyle:{borderColor:e.ink,borderWidth:1}},progressive:0}),r.length>0){T.push({left:M.left,width:M.width,top:M.top-l-c,height:l});const E=T.length-1,[q,at]=Re(E,s.ncols,!1);C.push(q),O.push(at),I.push(...ze(r,e,t,E,!1,u,d))}if(a.length>0){T.push({left:M.left+M.width+c,width:l,top:M.top,height:M.height});const E=T.length-1,[q,at]=Re(E,s.nrows,!0);C.push(q),O.push(at),I.push(...ze(a,e,t,E,!0,u,d))}const V=M.left+M.width+c+(a.length>0?l+c:0),_=Math.max(o*6,M.height-o*2),R=[0,...r.length>0?[1]:[]],D=[0,...a.length>0?[T.length-1]:[]],et=(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]))},K=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||K!==""?{title:[...f?[{text:t.title,left:"center",top:4,textStyle:{color:e.ink,fontSize:o+4,fontFamily:e.fontFamily}}]:[],...K===""?[]:[{text:K,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} ${At(q.lo)}–${At(q.hi)}`}}},...i===null?{}:{visualMap:{type:"continuous",min:i.vmin,max:i.vmax,calculable:!0,realtime:!0,orient:"vertical",left:V,top:M.top+(M.height-_)/2,itemWidth:Math.round(o*.9),itemHeight:Math.round(_),formatter:E=>At(E),inRange:{color:Fo(t.colormap??s.colormap)},textStyle:{color:e.muted,fontSize:o,fontFamily:e.fontFamily},seriesIndex:0}},dataZoom:[{id:ue,type:"inside",xAxisIndex:R,zoomOnMouseWheel:!0,moveOnMouseMove:!0,filterMode:"none",...et(t.x.domain,s.ncols)},{id:de,type:"inside",yAxisIndex:D,zoomOnMouseWheel:"shift",moveOnMouseMove:!1,filterMode:"none",...et(t.y.domain,s.nrows)}],tooltip:t.tooltip?{trigger:"item",backgroundColor:e.background,borderColor:e.grid,textStyle:{color:e.ink,fontSize:o},formatter:Ro(s)}:{show:!1},series:I}}function Ro(s){const t=It(s.xTicks,s.ncols),e=It(s.yTicks,s.nrows);return n=>{const i=n.value;if(!Array.isArray(i)||i.length<3)return"";const[o,r,a]=i,l=s.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`${ot(u)} · ${ot(c)}<br/><b>${ot(d)}</b>`}}const Do={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 P(s,t,e){const n=t.get(e);if(n!==void 0&&n!=="")return n;const i=s.getAttribute(e);return i===null||i===""?null:i}function Rt(s){const t=new Map,e=s.getAttribute("style");if(e===null)return t;for(const n of e.split(";")){const i=n.indexOf(":");i<0||t.set(n.slice(0,i).trim().toLowerCase(),n.slice(i+1).trim())}return t}function L(s,t){if(s===null)return t;const e=Number.parseFloat(s);return Number.isFinite(e)?e:t}function _o(s,t){return s==="middle"?"center":s==="end"?"right":s==="start"?"left":t}function Vo(s,t){switch(s){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 Wo(s){if(s===null||s==="none")return null;const t=s.split(/[\s,]+/).filter(e=>e!=="").map(e=>Number.parseFloat(e));return t.length===0||t.some(e=>!Number.isFinite(e)||e<0)?[]:t}function Dn(s,t,e){const n=Rt(s),i={...t},o=P(s,n,"fill");o!==null&&(i.fill=De(o,t.fill,e),i.fillGradient=Go(o,t.fillGradient,e));const r=P(s,n,"stroke");r!==null&&(i.stroke=De(r,t.stroke,e));const a=P(s,n,"stroke-width");a!==null&&(i.strokeWidth=L(a,t.strokeWidth));const l=P(s,n,"opacity");l!==null&&(i.opacity=t.opacity*dt(L(l,1)));const c=P(s,n,"fill-opacity");c!==null&&(i.fillOpacity=dt(L(c,1)));const u=P(s,n,"stroke-opacity");u!==null&&(i.strokeOpacity=dt(L(u,1)));const d=P(s,n,"stroke-linecap");(d==="round"||d==="square"||d==="butt")&&(i.lineCap=d);const f=P(s,n,"stroke-linejoin");(f==="round"||f==="bevel"||f==="miter")&&(i.lineJoin=f);const m=Wo(P(s,n,"stroke-dasharray"));m!==null&&(i.dash=m);const h=P(s,n,"font-size");h!==null&&(i.fontSize=L(h,t.fontSize));const y=P(s,n,"font-family");y!==null&&(i.fontFamily=y);const g=P(s,n,"font-weight");g!==null&&(i.fontWeight=g);const w=P(s,n,"font-style");w!==null&&(i.fontStyle=w),i.anchor=_o(P(s,n,"text-anchor"),t.anchor),i.baseline=Vo(P(s,n,"dominant-baseline")??P(s,n,"alignment-baseline"),t.baseline);const b=P(s,n,"paint-order");return b!==null&&(i.strokeFirst=b.trim().split(/\s+/)[0]==="stroke"),i}function dt(s){return s<0?0:s>1?1:s}function _n(s){return/^url\(\s*['"]?#([^)'"]+)['"]?\s*\)$/.exec(s.trim())?.[1]??null}function De(s,t,e){const n=s.trim();if(n==="none"||n==="transparent")return null;if(n==="currentColor"||n==="inherit")return t;const i=_n(n);return i!==null?e.get(i)?.flat??null:n}function Go(s,t,e){const n=s.trim();if(n==="inherit")return t;const i=_n(n);return i===null?null:e.get(i)?.linear??null}function Ho(s){const t=new Map,e=s.querySelectorAll("linearGradient, radialGradient");for(const n of Array.from(e)){const i=n.getAttribute("id");if(i===null)continue;const o=Array.from(n.querySelectorAll("stop"));if(o.length===0)continue;const r=o[Math.floor((o.length-1)/2)],a=P(r,Rt(r),"stop-color")??"#000000";t.set(i,{flat:a,linear:n.tagName.toLowerCase()==="lineargradient"?Ko(n,o):null})}return t}function Ko(s,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 n=0;return{units:s.getAttribute("gradientUnits")==="userSpaceOnUse"?"userSpaceOnUse":"objectBoundingBox",x1:e(s.getAttribute("x1"),0),y1:e(s.getAttribute("y1"),0),x2:e(s.getAttribute("x2"),1),y2:e(s.getAttribute("y2"),0),stops:t.map(i=>{const o=Rt(i);return n=Math.max(n,dt(e(i.getAttribute("offset"),0))),{offset:n,rgb:$s(P(i,o,"stop-color")??"#000000"),opacity:dt(L(P(i,o,"stop-opacity"),1))}})}}function Yo(s){let t=[1,0,0,1,0,0];const e=/(matrix|translate|scale|rotate|skewX|skewY)\s*\(([^)]*)\)/g;let n;for(;(n=e.exec(s))!==null;){const i=n[2].split(/[\s,]+/).filter(o=>o!=="").map(o=>Number.parseFloat(o)).map(o=>Number.isFinite(o)?o:0);t=te(t,Uo(n[1],i))}return t}function Uo(s,t){switch(s){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,n=Math.cos(e),i=Math.sin(e),o=[n,i,-i,n,0,0];if(t.length<3)return o;const r=t[1],a=t[2];return te(te([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 te(s,t){return[s[0]*t[0]+s[2]*t[1],s[1]*t[0]+s[3]*t[1],s[0]*t[2]+s[2]*t[3],s[1]*t[2]+s[3]*t[3],s[0]*t[4]+s[2]*t[5]+s[4],s[1]*t[4]+s[3]*t[5]+s[5]]}const Zo=[1,0,0,1,0,0];function ee(s){return s[0]===1&&s[1]===0&&s[2]===0&&s[3]===1&&s[4]===0&&s[5]===0}function Xo(s,t){let e=0;const n=()=>{for(;e<t.length&&(t[e]===" "||t[e]===","||t[e]===`
|
|
5
|
+
`||t[e]===" "||t[e]==="\r");)e+=1},i=()=>{n();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=()=>{n();const b=t[e];return b==="0"||b==="1"?(e+=1,b==="1"?1:0):Number.NaN},r=()=>{n();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)=>{s.moveTo(b,S),a=b,l=S,c=b,u=S,m=!0},y=(b,S)=>{m?(s.lineTo(b,S),a=b,l=S):h(b,S)},g=(b,S,A,v,k,$)=>{m||h(a,l),s.bezierCurveTo(b,S,A,v,k,$),a=k,l=$};let w="";for(n();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":{s.closePath(),a=c,l=u,d=null,f=null,w="",n();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(),$=v+i(),x=A+i(),M=v+i(),T=A+i(),C=v+i();g(k,$,x,M,T,C),d={x,y:M},f=null;break}case"S":{const k=d===null?a:2*a-d.x,$=d===null?l:2*l-d.y,x=A+i(),M=v+i(),T=A+i(),C=v+i();g(k,$,x,M,T,C),d={x,y:M},f=null;break}case"Q":{const k=A+i(),$=v+i(),x=A+i(),M=v+i();m||h(a,l),s.quadraticCurveTo(k,$,x,M),a=x,l=M,f={x:k,y:$},d=null;break}case"T":{const k=f===null?a:2*a-f.x,$=f===null?l:2*l-f.y,x=A+i(),M=v+i();m||h(a,l),s.quadraticCurveTo(k,$,x,M),a=x,l=M,f={x:k,y:$},d=null;break}case"A":{const k=i(),$=i(),x=i(),M=o(),T=o(),C=A+i(),O=v+i();if(Number.isNaN(M)||Number.isNaN(T)||Number.isNaN(C)||Number.isNaN(O))return;m||h(a,l);for(const I of ne(a,l,k,$,x,M===1,T===1,C,O))s.bezierCurveTo(I[0],I[1],I[2],I[3],I[4],I[5]);a=C,l=O,d=null,f=null;break}default:return}if(Number.isNaN(a)||Number.isNaN(l)||(n(),!r()&&e<t.length&&!/[MmLlHhVvCcSsQqTtAaZz]/.test(t[e])))return}}function ne(s,t,e,n,i,o,r,a,l){let c=Math.abs(e),u=Math.abs(n);if(c===0||u===0)return[[s,t,a,l,a,l]];const d=i*Math.PI/180,f=Math.cos(d),m=Math.sin(d),h=(s-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)),$=k*c*w/u,x=-k*u*g/c,M=f*$-m*x+(s+a)/2,T=m*$+f*x+(t+l)/2,C=(E,q)=>Math.atan2(q,E),O=C((g-$)/c,(w-x)/u);let F=C((-g-$)/c,(-w-x)/u)-O;!r&&F>0&&(F-=2*Math.PI),r&&F<0&&(F+=2*Math.PI);const V=Math.max(1,Math.ceil(Math.abs(F)/(Math.PI/2))),_=F/V,R=4/3*Math.tan(_/4),D=[],et=E=>[M+c*Math.cos(E)*f-u*Math.sin(E)*m,T+c*Math.cos(E)*m+u*Math.sin(E)*f],K=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<V;E++){const q=O+E*_,at=q+_,[rs,as]=et(q),[fe,me]=et(at),[ls,cs]=K(q),[us,ds]=K(at);D.push([rs+R*ls,as+R*cs,fe-R*us,me-R*ds,fe,me])}return D}function Qo(s,t,e){const i=new DOMParser().parseFromString(s,"image/svg+xml").documentElement;i===null||i.nodeName==="parsererror"||Jo(i,t,e)}function Jo(s,t,e){const n=jo(s),i=Ho(s),o=tr(s);if(t.save(),e!==void 0&&n!==null&&n.width>0&&n.height>0){const r=e.width/n.width,a=e.height/n.height;(r!==1||a!==1)&&t.transform(r,0,0,a,0,0)}n!==null&&(n.x!==0||n.y!==0)&&t.transform(1,0,0,1,-n.x,-n.y),Vn(s,t,Do,i,o),t.restore()}function jo(s){const t=s.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(s.getAttribute("width"),Number.NaN),n=L(s.getAttribute("height"),Number.NaN);return!Number.isFinite(e)||!Number.isFinite(n)?null:{x:0,y:0,width:e,height:n}}function tr(s){const t=new Map;for(const e of Array.from(s.querySelectorAll("clipPath"))){const n=e.getAttribute("id");n!==null&&t.set(n,e)}return t}const er=new Set(["defs","style","clippath","lineargradient","radialgradient","title","desc","metadata","filter","mask","pattern","marker","symbol"]);function Vn(s,t,e,n,i){for(const o of Array.from(s.children)){const r=o.tagName.toLowerCase();if(er.has(r))continue;const a=Dn(o,e,n),l=Wn(o),c=Gn(o,i),u=!ee(l)||c!==null;u&&t.save(),ee(l)||t.transform(...l),c!==null&&Hn(t,c,i),r==="g"||r==="a"||r==="svg"?Vn(o,t,a,n,i):sr(o,r,t,a),u&&t.restore()}}function Wn(s){const t=s.getAttribute("transform");return t===null||t===""?Zo:Yo(t)}function Gn(s,t){const e=s.getAttribute("clip-path")??Rt(s).get("clip-path")??null;if(e===null)return null;const n=/^url\(\s*['"]?#([^)'"]+)['"]?\s*\)$/.exec(e.trim());return n===null?null:t.get(n[1])??null}function Hn(s,t,e){s.beginPath();let n=!1;for(const o of Array.from(t.children)){const r=Wn(o);ee(r)&&vt(o,o.tagName.toLowerCase(),s)&&(n=!0)}const i=Gn(t,e);i!==null&&Hn(s,i,e),n&&s.clip()}function vt(s,t,e){switch(t){case"path":{const n=s.getAttribute("d");return n===null||n===""?!1:(Xo(e,n),!0)}case"rect":{const n=L(s.getAttribute("x"),0),i=L(s.getAttribute("y"),0),o=L(s.getAttribute("width"),0),r=L(s.getAttribute("height"),0);if(!(o>0)||!(r>0))return!1;const a=Math.min(L(s.getAttribute("rx"),0),o/2),l=Math.min(L(s.getAttribute("ry"),a),r/2);return a>0&&l>0?nr(e,n,i,o,r,a,l):e.rect(n,i,o,r),!0}case"circle":{const n=L(s.getAttribute("r"),0);return n>0?(e.moveTo(L(s.getAttribute("cx"),0)+n,L(s.getAttribute("cy"),0)),e.arc(L(s.getAttribute("cx"),0),L(s.getAttribute("cy"),0),n,0,Math.PI*2),!0):!1}case"ellipse":{const n=L(s.getAttribute("rx"),0),i=L(s.getAttribute("ry"),0);if(!(n>0)||!(i>0))return!1;const o=L(s.getAttribute("cx"),0),r=L(s.getAttribute("cy"),0);e.moveTo(o+n,r);for(const a of ne(o+n,r,n,i,0,!0,!0,o-n,r))e.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5]);for(const a of ne(o-n,r,n,i,0,!0,!0,o+n,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(s.getAttribute("x1"),0),L(s.getAttribute("y1"),0)),e.lineTo(L(s.getAttribute("x2"),0),L(s.getAttribute("y2"),0)),!0;case"polyline":case"polygon":{const n=(s.getAttribute("points")??"").split(/[\s,]+/).filter(i=>i!=="").map(i=>Number.parseFloat(i));if(n.length<4)return!1;e.moveTo(n[0],n[1]);for(let i=2;i+1<n.length;i+=2)e.lineTo(n[i],n[i+1]);return t==="polygon"&&e.closePath(),!0}default:return!1}}function nr(s,t,e,n,i,o,r){s.moveTo(t+o,e),s.lineTo(t+n-o,e),s.quadraticCurveTo(t+n,e,t+n,e+r),s.lineTo(t+n,e+i-r),s.quadraticCurveTo(t+n,e+i,t+n-o,e+i),s.lineTo(t+o,e+i),s.quadraticCurveTo(t,e+i,t,e+i-r),s.lineTo(t,e+r),s.quadraticCurveTo(t,e,t+o,e),s.closePath()}function sr(s,t,e,n){if(t==="text"||t==="tspan"){Kn(s,e,n);return}if(t==="image"||t==="use"||t==="foreignobject"||(e.beginPath(),!vt(s,t,e)))return;const i=n.fill===null?null:n.fillGradient;if(i===null){_e(e,n);return}const o=()=>or(s,t,e,n,i),r=()=>{e.beginPath(),vt(s,t,e),_e(e,{...n,fill:null})};n.strokeFirst?(r(),o()):(o(),r())}const ir=100;function or(s,t,e,n,i){const o=rr(s,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=n.opacity*n.fillOpacity,g=(w,b,S,A)=>{const v=F=>[i.x1+c*F,i.y1+u*F],k=-u/Math.sqrt(d),$=c/Math.sqrt(d);let x=0;for(const[F,V]of l)x=Math.max(x,Math.abs((F-i.x1)*k+(V-i.y1)*$));x+=1;const[M,T]=v(w),[C,O]=v(b),I=[a(M+k*x,T+$*x),a(C+k*x,O+$*x),a(C-k*x,O-$*x),a(M-k*x,T-$*x)];e.globalAlpha=y*A,e.fillStyle=`rgb(${S.map(F=>Math.round(dt(F)*255)).join(", ")})`,e.beginPath(),e.moveTo(I[0][0],I[0][1]);for(const[F,V]of I.slice(1))e.lineTo(F,V);e.closePath(),e.fill()};if(e.save(),e.beginPath(),vt(s,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 $=((v-i.x1)*c+(k-i.y1)*u)/d;w=Math.min(w,$),b=Math.max(b,$)}const S=[],A=v=>{const k=S[S.length-1];k!==void 0&&k.opacity===v.opacity&&k.rgb.every((x,M)=>x===v.rgb[M])?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],$=f[v+1],x=$.offset-k.offset;if(!(x>0))continue;const T=k.opacity===$.opacity&&k.rgb.every((C,O)=>C===$.rgb[O])?1:Math.max(1,Math.round(x*ir));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(I=>k.rgb[I]+($.rgb[I]-k.rgb[I])*O),opacity:k.opacity+($.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 $=y*v.opacity>=1&&k+1<S.length;g(v.from,$?v.to+(v.to-v.from)/2:v.to,v.rgb,v.opacity)})}e.restore(),e.globalAlpha=1}function rr(s,t){let e=1/0,n=1/0,i=-1/0,o=-1/0;const r=(c,u)=>{e=Math.min(e,c),n=Math.min(n,u),i=Math.max(i,c),o=Math.max(o,u)},a=()=>{};return!vt(s,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>n)?null:{x:e,y:n,width:i-e,height:o-n}}function _e(s,t,e){const n=t.stroke!==null&&t.strokeWidth>0,i=()=>{t.fill!==null&&(s.globalAlpha=t.opacity*t.fillOpacity,s.fillStyle=t.fill,s.fill())},o=()=>{n&&(s.globalAlpha=t.opacity*t.strokeOpacity,s.strokeStyle=t.stroke,s.lineWidth=t.strokeWidth,s.lineJoin=t.lineJoin,s.lineCap=t.lineCap,s.setLineDash(t.dash),s.stroke())};t.strokeFirst?(o(),i()):(i(),o()),s.globalAlpha=1,s.setLineDash([])}function Kn(s,t,e){const n=Array.from(s.children).filter(o=>o.tagName.toLowerCase()==="tspan"),i=n.length>0?"":s.textContent??"";if(i.trim()!==""){const o=L(s.getAttribute("x"),0)+L(s.getAttribute("dx"),0),r=L(s.getAttribute("y"),0)+L(s.getAttribute("dy"),0);t.font=ar(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 n)Kn(o,t,Dn(o,e,new Map))}function ar(s){const t=s.fontStyle!=="normal"?`${s.fontStyle} `:"",e=s.fontWeight!=="normal"?`${s.fontWeight} `:"";return`${t}${e}${s.fontSize}px ${s.fontFamily}`}const Ve=1/12;function lr(s,t){return{x:s.right-s.left>=Math.max(1,t.width)*Ve,y:s.bottom-s.top>=Math.max(1,t.height)*Ve}}function cr(s){return s.metaKey||s.ctrlKey}function ur(s){const{host:t}=s;if(typeof window>"u")return{destroy:()=>{}};const e=p("div",{class:"figure-marquee hidden"});t.appendChild(e);let n=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(n?.x??h.x,h.x),right:Math.max(n?.x??h.x,h.x),top:Math.min(n?.y??h.y,h.y),bottom:Math.max(n?.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"),n=null,i=null},c=h=>{!cr(h)||h.button!==0||s.chart()!==null&&(h.preventDefault(),h.stopPropagation(),n=o(h),i=h.pointerId,t.setPointerCapture?.(h.pointerId))},u=h=>{n===null||h.pointerId!==i||(h.preventDefault(),h.stopPropagation(),a(r(o(h))))},d=h=>{if(n===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=lr(y,{width:t.clientWidth,height:t.clientHeight});!g.x&&!g.y||s.onZoom(y,g)},f=h=>{h.pointerId===i&&l()},m=()=>s.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 We(s,t,e,n,i){const o=u=>{const d=i?[s.getWidth()/2,u]:[u,s.getHeight()/2],f=s.convertFromPixel({gridIndex:0},d),m=Array.isArray(f)?f[i?1:0]:null;if(typeof m=="number"&&Number.isFinite(m))return m;const h=s.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(n);if(r===null||a===null)return null;const[l,c]=r<=a?[r,a]:[a,r];return l<c?[l,c]:null}let ut=null,Ge=null;async function dr(){ut===null&&(Ge??=Ts(()=>import("./echartsBundle-Dqa1ruUg.js"),[],import.meta.url).then(s=>{ut=s.echarts}),await Ge)}function se(s){const t=Cs(s),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:(n,i)=>{const o=fr();return o===null?n.length*i*.6:(o.font=`${i}px ${e}`,o.measureText(n).width)}}}function hr(s){const t=s??{},e=[t,...t.batch??[]].map(n=>n.dataZoomId).filter(n=>typeof n=="string");return e.length===0?null:new Set(e)}let Wt;function fr(){return Wt===void 0&&(Wt=document.createElement("canvas").getContext("2d")),Wt}function mr(s){return Math.max(260,Math.min(520,Math.round(s*.78)))}function Gt(s){const t=p("div",{class:s.fill===!0?"figure-chart figure-chart-fill":"figure-chart"});let e=s.style,n=null,i=s.fill===!0,o=0,r=0,a=!1,l=!1,c=null,u={x:s.style.x.domain,y:s.style.y.domain};const d=(x,M=t)=>s.spec.kind==="matrix"?zo(s.spec.output,e,se(M),x):$o(s.spec,e,se(M),x),f=()=>i?t.clientHeight:mr(o),m=()=>{n!==null||o<=0||ut===null||(r=f(),!(r<=0)&&(n=ut.init(t,null,{renderer:"svg",width:o,height:r}),n.on("legendselectchanged",x=>{const M=s.spec;if(M.kind==="matrix")return;const T=x.selected;if(T===void 0)return;const C=M.series.filter(O=>T[O.name]===!1).map(O=>O.id);e={...e,hidden:C},s.onStyle?.(e)}),n.on("dataZoom",x=>{if(l||n===null)return;const M=n.getOption().dataZoom;if(M===void 0)return;const T=_=>{if(_===void 0)return null;const R=_.startValue,D=_.endValue;return typeof R!="number"||typeof D!="number"||!Number.isFinite(R)||!Number.isFinite(D)||R>=D?null:[R,D]},C=hr(x),O=C===null||C.has(ue),I=C===null||C.has(de),F=e.x.domain;e={...e,x:O?{...e.x,domain:T(M[0])??e.x.domain}:e.x,y:I?{...e.y,domain:T(M[1])??e.y.domain}:e.y};const V=s.spec;if(V.kind!=="matrix"){const _=K=>({showMinLabel:K.labels.showMinLabel??null,showMaxLabel:K.labels.showMaxLabel??null,customValues:K.ticks??null}),R=Lt(V,e,"x"),D=Lt(V,e,"y"),et=e.y.domain===null&&e.x.domain!==F;l=!0,n.setOption({xAxis:{axisLabel:_(R),axisTick:{customValues:R.ticks??null}},yAxis:{...et?{min:D.bounds.min??null,max:D.bounds.max??null}:{},axisLabel:_(D),axisTick:{customValues:D.ticks??null}}}),l=!1}s.onStyle?.(e)}),g()))},h=(x,M)=>{if(n===null)return;const T={...e};if(M.x){const C=We(n,{xAxisIndex:0},x.left,x.right,!1);C!==null&&(T.x={...T.x,domain:C})}if(M.y){const C=We(n,{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(),s.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(),s.onStyle?.(e))},g=()=>{n!==null&&(l=!0,n.setOption(d({width:o,height:r}),!0),l=!1)},w=()=>{if(o<=0)return;if(n===null){m();return}const x=f();x<=0||(r=x,n.resize({width:o,height:r}),(s.spec.kind==="matrix"||e.legend==="right")&&g())},b=typeof ResizeObserver>"u"?null:new ResizeObserver(x=>{const M=x[0]?.contentRect,T=M?.width??0;Math.abs(T-o)<.5&&(!i||Math.abs((M?.height??0)-r)<.5)&&n!==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=Es(()=>g()),$=dr().then(()=>{a||typeof document>"u"||(o>0&&m(),c??=ur({host:t,chart:()=>n,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:$,draw(x,M){if(ut===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:${M.width}px;height:${M.height}px`,t.appendChild(T);const C=ut.init(T,null,{renderer:"svg",width:M.width,height:M.height});try{C.setOption(wo(d(M,As())),!0),Qo(C.renderToSVGString(),x,M)}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(),n?.dispose(),n=null}}}const He=24;function pr(s){const t=p("div",{class:"controls-card figure-settings"}),e=i=>{s.onChange({...s.style(),...i})},n=()=>{const i=s.style(),o=s.spec.kind==="xy"?[yr(s.spec,i,e),Un(s.spec,i,e),kr(s.spec,i,e,s.theme()),$t(i,e)]:s.spec.kind==="matrix"?s.spec.output.streaks!==void 0?[$t(i,e,Ot(s.spec.output))]:[Sr(i,e),$t(i,e,Ot(s.spec.output))]:[Mr(s.spec,i,e),...wr(s.spec,i,e),$t(i,e)];t.replaceChildren(fn("Figure","chart-line","controls-title"),p("div",{class:"panel-controls"},...o,p("div",{class:"figure-actions"},N("reset",()=>s.onReset(),{class:"btn btn-quiet",title:"Back to the figure the task returned, and forget what was set here"}),...s.exports??[])))};return n(),{el:t,refresh:n}}function ht(s,...t){return p("div",{class:"figure-group"},p("h4",{class:"figure-group-head",text:s}),...t.filter(e=>e!==!1))}function j(s,t,e,n){const i=p("select",{class:"select"});for(const o of s){const r=p("option",{value:o,text:o}),a=n?.[o];a!==void 0&&(r.title=a),i.appendChild(r)}return i.value=t,i.addEventListener("change",()=>e(i.value)),i}function tt(s,t,e,n){const i=`figure-toggle-${br+=1}`,o=N(t?"on":"off",()=>e(!t),{class:"btn btn-toggle",title:n});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:s,id:i,title:n}),o)}function gr(s,t,e,n){const i=N(s,()=>e(!t),{class:"btn btn-toggle",title:n});return i.setAttribute("aria-pressed",String(t)),i}let br=0;function rt(s,t,e,n){const i=p("input",{class:"input input-num",type:"number",title:e,placeholder:"auto"});i.value=s===null?"":At(s,6),n!==void 0&&(i.step=String(n));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 he(s,t,e,n){const i=p("input",{class:"input",type:"text",title:e,placeholder:n});return i.value=s,i.addEventListener("change",()=>t(i.value)),i}const Yn={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 yr(s,t,e){const n=[...pn,...mn],i=s.series.some(r=>r.low!==void 0),o=t.mark==="line"||t.mark==="area"||t.mark==="step";return ht("chart",z("mark",j(n,t.mark,r=>e({mark:r}),Yn)),o&&z("line width",rt(t.lineWidth,r=>e({lineWidth:r??1.8}),"In CSS pixels",.25)),(t.mark==="points"||t.jitter||t.mark==="box")&&z("point size",rt(t.pointSize,r=>e({pointSize:r??6}),"In CSS pixels",1)),o&&tt("smooth",t.smooth,r=>e({smooth:r}),"A curve through the samples rather than straight segments — a claim about what is between them"),o&&tt("fill under",t.fillArea,r=>e({fillArea:r}),"Shade the space between the line and the axis"),i&&tt("band",t.bands,r=>e({bands:r}),"The spread the task computed, drawn around each line"),t.mark==="histogram"&&z("bins",rt(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")&&tt("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 vr(s,t,e,n){const i=ce(s,t,e);if(i!==null)return i[n];const o=t[e].scale==="log",r=t.mark==="histogram";let a=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY;for(const c of s.series){if(t.hidden.includes(c.id))continue;const u=r?zt(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:n===0?a:l}function Ke(s,t,e,n){const i=e[s],o=l=>n({[s]:{...i,...l}}),r=i.domain,a=l=>rt(r===null?null:r[l],c=>{if(c===null){o({domain:null});return}const u=r===null?vr(t,e,s,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[z(`${s} scale`,j(["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"})),z(`${s} name`,he(i.label??"",l=>o({label:l===""?null:l}),"What the axis is called; empty is the task’s own name",s==="x"?t.xLabel:t.yLabel)),p("div",{class:"field ann-field figure-range"},p("span",{class:"field-label",text:`${s} from`}),a(0),p("span",{class:"field-label",text:"to"}),a(1)),tt(`${s} grid`,i.grid,l=>o({grid:l}),"Rules across the plot at the ticks")]}function wr(s,t,e){const n=t.plot;return n===null||n.x===null?[]:[Un(gn(s,n.x,n.y,n.mark,n.fit,t.x.domain),t,e)]}function Un(s,t,e){return ht("axes",...Ke("x",s,t,e),...Ke("y",s,t,e),p("div",{class:"figure-actions"},N("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 kr(s,t,e,n){const i=s.series.slice(0,He).map((r,a)=>{const l=t.hidden.includes(r.id),c=Q(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=$r(On(r,a,t,n)),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=s.series.length-i.length;return ht("series",p("div",{class:"figure-series"},...i),o>0&&p("p",{class:"hint",text:`…and ${o} more, all of them drawn. Only the first ${He} are listed.`}),p("div",{class:"figure-actions"},N("show all",()=>e({hidden:[]}),{class:"btn btn-quiet",title:"Every series back on the picture"}),N("reset colours",()=>e({colours:{}}),{class:"btn btn-quiet",title:"Back to the task’s own colours and the palette"})))}const xr=["right","top","bottom","none"];function $t(s,t,e=!0){return ht("text",z("title",he(s.title??"",n=>t({title:n===""?null:n}),"Printed on the figure itself, so it survives the export; empty is no title","none")),z("type size",rt(s.fontSize,n=>t({fontSize:n??11}),"In CSS pixels, for every word on the figure",1)),z("legend",j(xr,s.legend,n=>t({legend:n}))),...e?[tt("tooltip",s.tooltip,n=>t({tooltip:n}),"The readout that follows the pointer")]:[])}function Sr(s,t){const e=["auto",...Ns];return ht("colour",z("colormap",j(e,s.colormap??"auto",n=>t({colormap:n==="auto"?null:n}))),p("div",{class:"field ann-field figure-range"},p("span",{class:"field-label",text:"scale"}),rt(s.vmin,n=>t({vmin:n}),"The value the lowest colour means; empty fits the data"),p("span",{class:"field-label",text:"to"}),rt(s.vmax,n=>t({vmax:n}),"The value the highest colour means; empty fits the data")))}function Mr(s,t,e){const n=Ls(s),i=[...n,...Os(s)],o=t.plot,r=s.columns.map(l=>l.key),a=t.columns??r;return ht("rows",z("filter",he(t.filter,l=>e({filter:l}),"Rows whose text contains this, anywhere","every row")),z("sort by",j(["—",...r],t.sortKey??"—",l=>e({sortKey:l==="—"?null:l}))),t.sortKey!==null&&tt("descending",t.sortDown,l=>e({sortDown:l}),"Largest or last first"),p("div",{class:"figure-columns"},...s.columns.map(l=>{const c=a.includes(l.key);return gr(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`)})),n.length>0&&z("plot",j(["table",...n.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&&z("against",j(["—",...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&&tt("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&&z("as",j(o.x===null?mn:pn,o.mark,l=>e({plot:{...o,mark:l}}),Yn)))}function $r(s){const t=s.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 n=/^#([0-9a-f]{6})[0-9a-f]{2}$/i.exec(t);if(n!==null)return`#${n[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 Er="figure:side";function Ye(s){const t=Is(s.output);if(t===null)throw new Error("this output is not a figure");return Tr(t,s)}function Tr(s,t){let e=Fs(t.uri,t.task,s),n=null,i=null,o=d(s,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 $=n!==null;if(v.kind==="matrix"&&v.output.streaks!==void 0){const x=Ps(v.output.streaks);return x.setFill?.($),x}if(v.kind==="matrix"){const x=Ot(v.output)?v.output:Nr(v,k);return Ot(x)?Gt({spec:{...v,output:x},style:Ze(v,k),onStyle:M=>f(M),fill:$}):qs(x)}if(v.kind==="table"){const x=Zn(v,k);return x===null?Ci(v,k,(M,T)=>m({sortKey:M,sortDown:T})):Gt({spec:x.spec,style:x.style,onStyle:M=>f(M),fill:$})}return Gt({spec:v,style:k,onStyle:x=>f(x),fill:$})}function f(v){const k=e;e=v,be(t.uri,t.task,s.id,e),i?.refresh(),g(),Xn(s,k,e)&&setTimeout(()=>{h(),w()},0)}function m(v){const k=e;e={...e,...v},be(t.uri,t.task,s.id,e);const $=u();$!==null&&Cr(s,k,e)?$.update(Ze(s,e)):s.kind==="matrix"&&s.output.streaks!==void 0||h(),i?.refresh(),g(),w()}function h(){const v=d(s,e);(o.el.parentElement??r).replaceChild(v.el,o.el),o.destroy(),o=v}function y(){Rs(t.uri,t.task,s.id),e=Ds(s),h(),i?.refresh(),g(),w()}function g(){const v=[];if(s.kind==="xy"){const k=p("select",{class:"select select-tight"});for(const $ of["line","area","step","points","bars","histogram","box","violin"])k.appendChild(p("option",{value:$,text:$}));k.value=e.mark,k.title="How the series are drawn",k.addEventListener("change",()=>m({mark:k.value})),v.push(k),v.push(Xe("x",e,m),Xe("y",e,m),Ar("list",e.legend!=="none","legend",()=>m({legend:e.legend==="none"?"right":"none"})),N("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(!(s.kind==="matrix"&&s.output.streaks!==void 0))if(s.kind==="matrix"){const k=p("select",{class:"select select-tight"});k.appendChild(p("option",{value:"",text:"auto"}));const $=Ht.includes(e.colormap??"")?Ht:[...e.colormap===null?[]:[e.colormap],...Ht];for(const x of $)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=Ue(o);l.replaceChildren(p("span",{class:"analysis-figure-title",text:e.title??t.output.label}),...t.extras??[],...v===null||t.onPng===void 0?[]:[N("PNG",()=>t.onPng?.(v),{class:"btn",title:"The figure as a raster, redrawn at 300 dpi"})],...v===null||t.onPdf===void 0?[]:[N("PDF",()=>t.onPdf?.(v),{class:"btn",title:"The figure as a true vector page — restylable, recolourable, scalable"})],...v===null||t.onCopy===void 0?[]:[N("Copy",()=>t.onCopy?.(v),{class:"btn",title:"The figure as a raster at 300 dpi, onto the clipboard — the PNG, to paste"})],Q("sliders-horizontal","Customise this figure",()=>b(),{class:"btn btn-icon figure-enlarge",size:14}))}function b(){if(n!==null)return;const v=A();n=zs({title:e.title??t.output.label,stage:o.el,side:v.el,memoryKey:()=>t.uri,scope:Er,onResize:()=>S(!0),onClose:()=>{n=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=pr({spec:s,style:()=>e,onChange:v=>m(v),onReset:()=>y(),theme:()=>se(c)})),i.refresh(),i}return g(),w(),{el:c,drawable:()=>Ue(o),ready:()=>"ready"in o?o.ready:Promise.resolve(),destroy(){n?.close(),o.destroy()}}}function Ue(s){return"draw"in s?s:null}function Cr(s,t,e){return s.kind==="matrix"?!0:s.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&&!Xn(s,t,e):!0}function Zn(s,t){const e=t.plot;if(e===null)return null;const n=e.x===null?Bs(s,e.y,e.mark):gn(s,e.x,e.y,e.mark,e.fit,t.x.domain);return{spec:n,style:{...t,mark:e.mark,legend:n.series.length>1?t.legend==="none"?"none":"top":"none"}}}function Ze(s,t){return s.kind==="table"?Zn(s,t)?.style??t:s.kind==="matrix"?{...t,legend:"none"}:t}function Xn(s,t,e){if(s.kind!=="table"||e.plot===null||!e.plot.fit||e.plot.x===null)return!1;const n=t.x.domain,i=e.x.domain;return n===null||i===null?n!==i:n[0]!==i[0]||n[1]!==i[1]}const Ht=["fall","viridis","magma","seismic","coolwarm","bwr"];function Xe(s,t,e){const n=t[s],i=n.scale==="log",o=N(`log ${s}`,()=>e({[s]:{...n,scale:i?"linear":"log"}}),{class:"btn btn-toggle",title:i?`A linear ${s} axis`:`A log ${s} axis — values at or below zero become gaps`});return o.setAttribute("aria-pressed",String(i)),o}function Ar(s,t,e,n){const i=Q(s,t?`Hide the ${e}`:`Show the ${e}`,n,{class:"btn btn-icon btn-toggle",size:13});return i.setAttribute("aria-pressed",String(t)),i}function Nr(s,t){const e={...s.output};if(t.colormap!==null&&(e.colormap=t.colormap),t.vmin===null&&t.vmax===null)return e;let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const a of s.output.values)Number.isFinite(a)&&(a<n&&(n=a),a>i&&(i=a));const o=t.vmin??(Number.isFinite(n)?n:0),r=t.vmax??(Number.isFinite(i)?i:1);return o<r&&(e.range=[o,r]),e}const Qe="10.1093/bioinformatics/btae088",Et="10.1371/journal.pcbi.1012067",Je="10.1093/nar/gkw257",Lr={coverage:{method:"Coverage as cooltools computes it (Open2C 2024).",doi:Et,agreement:"identical",section:9},cistrans:{method:"Cis and trans sums as cooltools’ expected_cis and expected_trans make them (Open2C 2024).",doi:Et,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:Et,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},mapreport:{method:"The map resolution of Rao et al. 2014, its counts at every bin size.",doi:"10.1016/j.cell.2014.11.021",agreement:"identical",section:29},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:Et,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"},arrowhead:{method:"Contact domains by Arrowhead (Rao et al. 2014), as juicer_tools arrowhead calls them.",doi:"10.1016/j.cell.2014.11.021",agreement:"identical",section:28},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:Qe,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:Qe,agreement:"identical",section:16},metaplot:{method:"deepTools’ computeMatrix and plotProfile (Ramírez et al. 2016).",doi:Je,agreement:"identical",section:14},trackcorr:{method:"deepTools’ multiBigwigSummary and plotCorrelation (Ramírez et al. 2016), on exact window means.",doi:Je,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 Or(s){return Lr[s]??null}function Ir(s){return s.agreement!=="untested"}const Qn={identical:"Identical in the validation",equivalent:"Equivalent in the validation",untested:"Not validated yet"};function Fr(s,t){s.replaceChildren(p("p",{class:"question-tip-text",text:t.method}),p("p",{class:"question-tip-note"},`${Qn[t.agreement]} · `,p("a",{text:`doi:${t.doi}`,attrs:{href:`https://doi.org/${t.doi}`,target:"_blank",rel:"noopener noreferrer"}})))}function Pr(s){return _s({class:`task-ref${Ir(s)?" is-validated":""}`,label:`${s.method} ${Qn[s.agreement]}.`,fill:t=>Fr(t,s)})}const qr={"2d":"grid-2x2","3d":"box","1d":"chart-line",metagenome:"library"};function Br(s){switch(s.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:s.total>0?B.pct(Math.min(1,s.done/s.total),0):"running",tone:"is-running",spinner:!0,batch:s.batch===void 0?"":`${s.batch.at+1} of ${s.batch.of}`,detail:s.batch===void 0?s.note:`${s.batch.label}${s.note===""?"":` — ${s.note}`}`};case"done":return{text:`done in ${wn(s.ms)}`,tone:"is-done",spinner:!1,detail:"",batch:""};case"failed":return{text:"failed",tone:"is-failed",spinner:!1,detail:s.message,batch:""};case"cancelled":return{text:"cancelled",tone:"",spinner:!1,detail:"",batch:""}}}function zr(s){return s.status==="running"||s.status==="queued"}function Jn(s){return s==="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 Rr{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 n=this.rows.find(i=>!i.el.classList.contains("is-filtered-out")&&!i.el.classList.contains("is-waiting"));n!==void 0&&this.options.onOpen(n.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?[]:bn(t),n=e.map(i=>i.id).join(`
|
|
6
|
+
`);n!==this.built&&(this.built=n,this.rebuild(e)),this.paint()}destroy(){this.unsubscribe(),this.rows.length=0,this.el.remove()}groups(t){const e=[];for(const n of t)e.includes(n.group)||e.push(n.group);return e}rebuild(t){if(this.rows.length=0,this.groupNotes.length=0,this.cards.length=0,this.filterEl.placeholder=`filter ${B.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 "+(yn("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 n of this.groups(t)){const i=[],o=p("p",{class:"analysis-group-needs hidden"});this.groupNotes.push({group:n,needs:o}),i.push(o);for(const a of t.filter(l=>l.group===n)){const l=this.row(a);this.rows.push(l),i.push(l.el,l.needs)}const r=p("section",{class:"card analysis-card"},fn(vn[n],qr[n]),...i);this.cards.push({group:n,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=Dr(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 n=t.length>0&&e===0&&this.rows.length>0;this.noMatchEl.textContent=n?`No task matches “${this.filterEl.value.trim()}”.`:"",this.noMatchEl.classList.toggle("hidden",!n)}row(t){const e=p("span",{class:"analysis-chip"}),n=p("span",{class:"analysis-chip analysis-batch hidden"}),i=Q("circle-stop",`Stop ${t.title}. ${Jn(t.venue)}`,()=>this.options.runner.cancel(t.id),{class:"btn btn-icon",size:14});i.addEventListener("click",f=>f.stopPropagation());const o=Or(t.id),r=o===null?p("span",{class:"task-ref-blank",attrs:{"aria-hidden":"true"}}):Pr(o),a=p("div",{class:"plot-icon-row"},e,n,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:n,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(),n=this.options.blocked?.()??null;this.blockedEl.textContent=n??"",this.blockedEl.classList.toggle("hidden",n===null);const i=this.rows.map(l=>n!==null&&J(l.task)),o=this.rows.map((l,c)=>n!==null&&i[c]?{state:"waiting",needs:n}: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=Br(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=zr(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 Dr(s){return[s.title,s.blurb,...s.keywords??[],vn[s.group],s.id].join(`
|
|
7
|
+
`).toLowerCase()}function _r(s){let t=(Number.isFinite(s)?Math.trunc(s):0)>>>0;return function(){t=t+1831565813>>>0;let n=t;return n=Math.imul(n^n>>>15,n|1),n^=n+Math.imul(n^n>>>7,n|61),((n^n>>>14)>>>0)/4294967296}}function jn(s,t){return s.options.filter(e=>e.needsGenomes===!0&&!t.hasGenomes?!1:e.needsKinds===void 0?!0:t.entries.some(n=>n.status!=="error"&&e.needsKinds.includes(n.kind)))}function Vr(s,t,e){const n={...e};for(const i of s){if(i.kind!=="choice")continue;const o=jn(i,t);if(o.length===0)continue;const r=Y(n[i.key],i.default);o.some(a=>a.value===r)||(n[i.key]=o[0].value)}return n}function Wr(s,t){return t.hasGenomes?s.label:s.coolLabel??s.label}const Gr=400,Hr="score";let Kr=0;function Yr(){const s=new Map;return{get:t=>s.get(t),set:(t,e)=>{e===null?s.delete(t):s.set(t,e)}}}function je(s,t){const e=t.toLowerCase();return s.accept.some(n=>e.endsWith(n))}const Ur=Js.filter(js);function Zr(s){switch(s.kind){case"featureSet":return Ur;case"pairSet":return["pairs"];case"track":return["track"];case"sequence":return["sequence"]}}function Ft(s,t){const e=Zr(s);return t.entries.filter(n=>e.includes(n.kind)&&n.status!=="error")}function Pt(s){return(s.find(e=>e.primary===!0)??s[0])?.id??null}function Xr(s){return s.kind==="featureSet"||s.kind==="pairSet"||s.kind==="track"||s.kind==="sequence"}function Qr(s,t,e){const n=Ft(s,t),i=typeof e=="string"&&e!=="";return i&&n.some(o=>o.id===e)?e:s.optional===!0?i||e===""?"":Pt(ts(n))??"":Pt(n)}function ts(s){return s.filter(t=>t.source.kind!=="computed"&&t.source.kind!=="derived")}function Jr(s,t,e){const n=Ft(s,t),i=new Set(n.map(a=>a.id)),o=Array.isArray(e)?e.filter(a=>typeof a=="string"&&i.has(a)):[];if(s.optional===!0){if(Array.isArray(e))return o;const a=Pt(ts(n));return a===null?null:[a]}if(o.length>0)return o;const r=Pt(n);return r===null?[]:[r]}function jr(s){const e=/^\s*(.*?)\s*[=:]\s*(\S+)\s*$/.exec(s)??/^\s*(.*\S)\s+(\S+)\s*$/.exec(s);if(e===null)return null;const n=e[1];return n===""||!Number.isFinite(Number(e[2]))?null:n}function es(s){const t=[Hr],e=s?.payload;if(e===void 0)return t;const n=e.data.detail,i=new Set(t),o=Math.min(n.length,Gr);for(let r=0;r<o;r++)for(const a of n[r].split(Qs)){const l=jr(a);l===null||i.has(l)||(i.add(l),t.push(l))}return t}function ns(s,t,e){const n=e[s.from],i=typeof n=="string"?n:Array.isArray(n)?n[0]??"":"";return i===""?void 0:t.entries.find(o=>o.id===i)}function ta(s,t,e){return es(ns(s,t,e))}function ea(s,t){const e=s.contigs.map(i=>i.name);if(!Array.isArray(t))return e;const n=new Set(e);return t.filter(i=>typeof i=="string"&&n.has(i))}function ss(s,t,e){const n=ta(s,t,e),i=e[s.key],o=typeof i=="string"&&i!=="";return o&&n.includes(i)?i:s.optional===!0?o||i===""?"":n[0]??"":n[0]??null}function Kt(s,t,e){const n=new Set(s.map(o=>o.key)),i={};for(const[o,r]of Object.entries(e))n.has(o)&&(i[o]=r);for(const o of s)Xr(o)&&(i[o.key]=o.multiple===!0?Jr(o,t,i[o.key]):Qr(o,t,i[o.key]));for(const o of s)o.kind==="column"&&(i[o.key]=ss(o,t,i));for(const o of s)o.kind==="sequences"&&(i[o.key]=ea(t,i[o.key]));for(const o of s)o.kind==="toggle"&&o.derive!==void 0&&(i[o.key]=o.derive(t));for(const o of s)o.settled!==void 0&&(Zs(o,t)||(i[o.key]=o.settled));return Vr(s,t,i)}function tn(s,t){return typeof s=="number"&&Number.isFinite(s)?s:t}function Y(s,t){return typeof s=="string"?s:t}function en(s,t=!1){const e=s.framing;if(e===null||e.level==="genome")return"";const[n,i]=e.rows,o=c=>s.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===s.contigs.length)return"";if(c.length>1)return s.contigs.filter(u=>c.includes(u)).map(u=>u.name).join(", ")}const r=s.contigs.find(c=>n>=c.startBin&&n<c.startBin+c.bins);if(r===void 0)return"";if(i>r.startBin+r.bins)return r.name;const a=(n-r.startBin)*e.binsize,l=Math.min(r.length,(i-r.startBin)*e.binsize);return le({contig:r.name,start:Math.max(0,Math.round(a)),end:Math.round(l)})}function na(s){const t=Math.floor(_r(s)()*4294967296);return t===s?s+1>>>0:t}function ie(s,t){return Array.isArray(s)&&Array.isArray(t)?s.length===t.length&&s.every((e,n)=>e===t[n]):s===t}function sa(s,t){for(const e of new Set([...Object.keys(s),...Object.keys(t)]))if(!ie(s[e],t[e]))return!1;return!0}class ia{constructor(t){this.options=t,this.specs=t.specs,this.context=t.context,this.shelf=t.files??Yr(),this.params={...Kt(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(Nt(e)||e.retired===!0)continue;const n=this.build(e);this.controls.push(n),this.groups.get(e.section??"")?.appendChild(n.wrapper),n.shown=!0}this.syncVisibility()}el;context;params;specs;controls=[];groups=new Map;teardown=[];id=`pf${Kr++}`;shelf;get value(){return{...this.params}}setContext(t){this.context=t;const e={...this.params};this.params={...Kt(this.specs,t,this.params)},this.fillRegions();for(const n of this.controls)n.refill?.(),n.sync();this.syncVisibility(),sa(e,this.params)||this.options.onChange(this.value)}setValue(t){this.params={...Kt(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(n=>!Nt(n)&&n.retired!==!0),e=[""];for(const n of t){const i=n.section??"";e.includes(i)||e.push(i)}return e.filter(n=>t.some(i=>(i.section??"")===n))}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,n){return p("div",{class:"param-row"},e,n,t.hint===void 0?null:p("div",{class:"hint",text:t.hint}))}labelled(t,e,n){return p("label",{class:"field param-field",attrs:{for:n}},p("span",{class:"field-label",text:t.label}),e)}named(t,e,n){return p("div",{class:"field param-field"},p("span",{class:"field-label",text:t.label,id:n}),e)}blocked(t,e,n){return e.setAttribute("role","group"),e.setAttribute("aria-labelledby",n),p("div",{class:"field field-block param-field"},p("span",{class:"field-label",text:t.label,id:n}),e)}commit(t,e){if(!ie(this.params[t],e)){this.params[t]=e;for(const n of this.controls)n.spec.kind==="column"&&n.refill?.(),n.sync();this.syncVisibility(),this.options.onChange(this.value)}}syncVisibility(){const t=new Map;for(let e=this.controls.length-1;e>=0;e--){const n=this.controls[e],i=n.spec.section??"",o=this.groups.get(i);if(o===void 0)continue;const r=Vs(n.spec,this.params,this.context),a=t.get(i)??null;r&&!n.shown?o.insertBefore(n.wrapper,a):!r&&n.shown&&n.wrapper.remove(),n.shown=r,r&&t.set(i,n.wrapper)}for(const[e,n]of this.groups)n.parentElement?.classList.toggle("hidden",!t.has(e))}fillRegions(){for(const t of this.specs){if(t.kind!=="region"||Y(this.params[t.key],"")!=="")continue;const e=t.default??en(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=Y(this.params[t.key],"").trim();e===""||kt(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}`,n=t.min!==void 0&&t.max!==void 0,i=t.slider===!0&&n,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=()=>tn(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}`,n=()=>Y(this.params[t.key],t.default),i=p("select",{class:"select",attrs:{id:e}}),o=()=>{const a=jn(t,this.context);i.replaceChildren();for(const c of a)i.appendChild(p("option",{value:c.value,text:Wr(c,this.context),...c.hint===void 0?{}:{title:c.hint}}));const l=n();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=n()};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`,n=p("button",{class:"btn btn-toggle",type:"button",text:"on",title:t.hint??t.label});n.setAttribute("aria-labelledby",e),n.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;n.setAttribute("aria-pressed",String(o)),n.textContent=o===!0?"on":"off"};return i(),{spec:t,wrapper:this.wrap(t,this.named(t,p("div",{class:"plot-icon-row"},n),e)),shown:!1,sync:i}}entrySelect(t){const e=`${this.id}-${t.key}`,n=p("select",{class:"select",attrs:{id:e}}),i=()=>{const r=Ft(t,this.context);n.replaceChildren(),t.optional===!0&&n.appendChild(p("option",{value:"",text:t.noneLabel??"none"}));for(const a of r)n.appendChild(p("option",{value:a.id,text:a.label}));r.length===0&&t.optional!==!0&&n.appendChild(p("option",{value:"",text:"nothing loaded"})),n.disabled=r.length===0};n.addEventListener("change",()=>this.commit(t.key,n.value===""?t.optional===!0?"":null:n.value));const o=()=>{n.value=Y(this.params[t.key],"")};return i(),o(),{spec:t,wrapper:this.wrap(t,this.labelled(t,n,e)),shown:!1,sync:o,refill:i}}entryList(t){const e=`${this.id}-${t.key}-label`,n=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=Ft(t,this.context);n.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))),n.appendChild(p("label",{class:"ann-head param-check"},u,p("span",{text:c.label}))),{id:c.id,input:u}}),l.length===0&&n.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,n,e)),shown:!1,sync:a,refill:r}}sequenceList(t){const e=`${this.id}-${t.key}-label`,n=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=()=>{n.replaceChildren(),o=this.context.contigs.map(d=>{const f=p("input",{class:"checkbox",type:"checkbox"});return f.addEventListener("change",a),n.appendChild(p("label",{class:"ann-head param-check"},f,p("span",{text:d.name}),p("span",{class:"hint param-check-note",text:B.bp(d.length)}))),{name:d.name,input:f}}),o.length===0&&n.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?"":`${B.int(d.size)} of ${B.int(o.length)} ticked`},u=p("div",{class:"param-check-actions"},N("all",()=>this.commit(t.key,this.context.contigs.map(d=>d.name)),{class:"btn btn-quiet",title:"Tick every sequence"}),N("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,n),e)),shown:!1,sync:c,refill:()=>{l(),c()}}}columnControl(t){const e=`${this.id}-${t.key}`,n=p("select",{class:"select",attrs:{id:e}});let i=null;const o=()=>{const a=ns(t,this.context,this.params),l=`${a?.id??""}:${a?.payload?.data.length??0}`;if(l===i)return;i=l;const c=es(a);n.replaceChildren(),t.optional===!0&&n.appendChild(p("option",{value:"",text:t.noneLabel??"none"}));for(const u of c)n.appendChild(p("option",{value:u,text:u}));this.params[t.key]=ss(t,this.context,this.params),n.value=Y(this.params[t.key],"")};n.addEventListener("change",()=>this.commit(t.key,n.value===""?t.optional===!0?"":null:n.value));const r=()=>{n.value=Y(this.params[t.key],"")};return o(),r(),{spec:t,wrapper:this.wrap(t,this.labelled(t,n,e)),shown:!1,sync:r,refill:o}}locusControl(t){const e=`${this.id}-${t.key}`,n=`${e}-sequences`,i=p("datalist",{attrs:{id:n}}),o=p("input",{class:"input input-region param-region",type:"text",attrs:{id:e,list:n},placeholder:en(this.context),title:yn("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?N("pick on map",()=>ve()?Xs():Ws(),{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=ve();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=Y(this.params[t.key],""))};if(a){let f=we();this.teardown.push(Gs(()=>{const m=we();m!==null&&m!==f&&(f=m,this.commit(t.key,m.whole===!0?m.contig:le(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`,n=`${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=Q("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:n,"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(!je(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=()=>{Us({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=>{!Hs(g)&&!ye(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"),ye(g)){Ks(g).then(b=>{if(b===null)return;const S=b.name??b.uri.split(/[\\/]/).pop()??b.uri;if(!je(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=Ys(g.dataTransfer);w.length>0&&d(w[0])});const m=()=>{const g=l.value.trim();if(g!==""&&!kt(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=Y(this.params[t.key],"").trim(),w=this.shelf.get(t.key),b=w!==void 0&&w.value===g&&g!==""&&!kt(g),S=w!==void 0&&w.value===g&&kt(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":`${B.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 n=e?.value??"";if(ie(this.params[t.key],n)){for(const i of this.controls)i.sync();this.options.onChange(this.value);return}this.commit(t.key,n)}textControl(t){const e=`${this.id}-${t.key}`,n=p("input",{class:"input",type:"text",attrs:{id:e},...t.placeholder===void 0?{}:{placeholder:t.placeholder},style:{width:"100%"}}),i=()=>this.commit(t.key,n.value.trim());n.addEventListener("change",i),n.addEventListener("keydown",r=>{r.key==="Enter"&&(r.preventDefault(),i())});const o=()=>{document.activeElement!==n&&(n.value=Y(this.params[t.key],""))};return o(),{spec:t,wrapper:this.wrap(t,this.labelled(t,n,e)),shown:!1,sync:o}}seedControl(t){const e=`${this.id}-${t.key}`,n=p("input",{class:"input input-num input-step",type:"number",attrs:{id:e,size:"1",step:"1",min:"0"}}),i=()=>tn(this.params[t.key],t.default),o=()=>{const l=Number(n.value);if(!Number.isFinite(l)){n.value=String(i());return}const c=Math.max(0,Math.trunc(l));n.value=String(c),this.commit(t.key,c)};n.addEventListener("change",o),n.addEventListener("keydown",l=>{l.key==="Enter"&&o()});const r=Q("rotate-cw","Roll a new seed — the same seed gives the same numbers, a new one resamples",()=>{const l=na(i());n.value=String(l),this.commit(t.key,l)},{class:"btn btn-icon",size:14}),a=()=>{document.activeElement!==n&&(n.value=String(i()))};return a(),{spec:t,wrapper:this.wrap(t,this.labelled(t,p("div",{class:"plot-icon-row"},n,r),e)),shown:!1,sync:a}}}const mt="\0all-maps",oe="chromosomix:analysis-drawer:width",oa=380,ra=.75,aa=.95,la=300;let ca=0;function ua(){try{const s=window.localStorage.getItem(oe);if(s===null)return null;const t=Number(s);return Number.isFinite(t)&&t>0?t:null}catch{return null}}function nn(s){try{s===null?window.localStorage.removeItem(oe):window.localStorage.setItem(oe,String(Math.round(s)))}catch{}}function da(s){if(s===null)return!0;const t=typeof s;return t==="number"||t==="string"||t==="boolean"?!0:Array.isArray(s)&&s.every(e=>typeof e=="string")}function pt(s){return s===null?"":s.memoryKey??s.uri}function ha(s,t){const e={...qt(s.params)},n=xn(t,s.id);if(n===null)return e;for(const i of s.params){const o=n[i.key];da(o)&&(e[i.key]=o)}return e}function fa(s){const t=[s.note.replace(/\.\s*$/,"")];return s.requests!==null&&s.requests>0&&t.push(`${B.int(s.requests)} request${s.requests===1?"":"s"}`),s.bytes!==null&&s.bytes>0&&t.push(B.bytes(s.bytes)),t.join(" · ")}function ma(s,t){return Nn(s,{params:s.params,framing:t})}function pa(s){return s instanceof HTMLTextAreaElement||s instanceof HTMLSelectElement?!0:s instanceof HTMLInputElement?!["button","checkbox","radio","range","submit","reset"].includes(s.type):s.isContentEditable}function re(s){return li(s.provenance.createdAt)}function ga(s,t,e){if(s===t)return"The run on screen";const n=[];for(const o of e.params){const r=s.provenance.params[o.key],a=t.provenance.params[o.key];Tt(r)!==Tt(a)&&n.push(`${o.label}: ${Tt(r)} (latest: ${Tt(a)})`)}const i=`Finished ${re(s)}.`;return n.length===0?`${i} The same parameters as the latest run.`:`${i} ${n.join(" · ")}`}function Tt(s){return s==null||s===""?"—":Array.isArray(s)?s.length===0?"—":s.join(", "):String(s)}function sn(s){return s.mapless===!0?"the sequences chosen":"the loaded tracks"}function ba(s){switch(s.status){case"running":return[p("span",{class:"analysis-spinner",attrs:{"aria-hidden":"true"}}),s.note===""?"working":s.note];case"queued":return["waiting for the job in front of it"];case"failed":return[p("span",{class:"inline-error",text:s.message})];default:return[]}}function ae(s){const t=s.getBoundingClientRect();return{width:Math.max(1,Math.round(t.width)),height:Math.max(1,Math.round(t.height))}}function Yt(s){const t=ae(s.el),e=ui(la),n=document.createElement("canvas");n.width=Math.max(1,Math.round(t.width*e)),n.height=Math.max(1,Math.round(t.height*e));const i=n.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),s.draw(i,t),n}function ya(s){const t=s.split("::")[0];return(t.split(/[\\/]/).pop()??t).split("?")[0].split("#")[0].replace(/\..*$/,"")||"map"}function on(s){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"figure"}function Ct(s,t,e,n){return yt(t.task,s,e).replace(/\.tsv$/,`.${n}`)}class va{constructor(t){this.options=t;const e=`analysis-drawer-${ca++}`;this.titleEl.id=`${e}-title`,this.recomputeButton=N("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=N("run",()=>this.run(),{class:"btn"}),this.runAllButton=N("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=N("cancel",()=>this.cancel(),{class:"btn"}),this.cliButton=N("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,N("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.documentsEl),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,Q("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"});documentsEl=p("span",{class:"analysis-documents"});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=ua();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=qt(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(!J(t)){this.runButton.replaceChildren("run"),this.runButton.title=`Run ${t.title} on ${sn(t)}`+(e<2?".":" — it reads no map, so it runs once, whichever map is starred.");return}const n=e<2?null:this.options.runner.target();if(n===null){this.runButton.replaceChildren("run"),this.runButton.title=`Run ${t.title} on the open map.`;return}this.runButton.replaceChildren("run on ",ke("star",{size:12,class:"run-star"})),this.runButton.title=`Run ${t.title} on ${n.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 n=this.options.runner.resultsFor(t.id);this.syncMaps(t,n);const i=this.chosenMap.get(t.id),o=i===mt&&n.length>1,r=i===void 0||i===mt?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(n):this.syncOutputs(u),this.syncFraming(u??n[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)&&pa(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 ti({side:"right",what:"Analysis drawer",width:()=>this.widthNow(),resize:t=>{this.width=t,this.paintWidth()},commit:()=>nn(this.widthNow()),reset:()=>{this.width=null,nn(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*aa),n=Math.min(oa,e);return Math.max(n,Math.min(e,this.width??Math.round(t*ra)))}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=ha(t,pt(e));const n=this.options.runner,i=new ia({specs:t.params,context:e,value:this.params,onChange:o=>this.onParams(o),files:{get:o=>n.heldFile(t.id,o),set:(o,r)=>n.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,n=this.context();e===null||n===null||(Ut(pt(n),e.id,t),this.syncRun(e,n))}blockedFor(t){return J(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:(Ut(pt(e),t.id,this.params),ei(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 n=this.options.runner.stateOf(t.id),i=n.status==="running"||n.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||!J(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?"":fa(o)),this.cancelButton.classList.toggle("hidden",!i),this.cancelButton.title=`Stop this job. ${Jn(t.venue)}`;const c=n.status==="running"&&n.total>0;this.progressEl.classList.toggle("hidden",!c),c&&n.status==="running"&&(this.progressFill.style.width=`${Math.min(100,n.done/n.total*100).toFixed(1)}%`);const u=ba(n);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 n=[...e.map(a=>a.target.map),mt],i=this.chosenMap.get(t.id)??n[0],o=a=>{this.chosenMap.set(t.id,a),this.chosenRun.delete(t.id),this.drawn=null,this.refresh()},r=a=>{const l=n.indexOf(i);o(n[(l+a+n.length)%n.length])};this.mapsEl.classList.remove("hidden"),this.mapsEl.replaceChildren(Q("chevron-left","The previous map",()=>r(-1),{class:"btn-quiet"}),...e.map(a=>N(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}`})),N("all maps",()=>o(mt),{class:`btn btn-quiet analysis-map${i===mt?" is-on":""}`,title:"Every map’s curves on one axis and every map’s tables as one — the comparison the deck was opened for"}),Q("chevron-right","The next map",()=>r(1),{class:"btn-quiet"}))}syncRuns(t,e,n){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=N("older",()=>i(n+1),{class:"btn btn-quiet",title:"The run before this one, with the figures it produced"});o.disabled=n>=e.length-1;const r=N("newer",()=>i(n-1),{class:"btn btn-quiet",title:"Back towards the most recent run"});r.disabled=n<=0;const a=N("latest",()=>i(0),{class:"btn btn-quiet",title:"The most recent run of this task"});a.disabled=n===0,this.runsEl.classList.remove("hidden"),this.runsEl.replaceChildren(ke("rotate-cw",{size:13,class:"analysis-runs-mark"}),o,p("span",{class:"analysis-run-at",text:n===0?`latest of ${e.length} runs`:`run ${e.length-n} of ${e.length} · ${re(e[n])}`,title:ga(e[n],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:n}=oo(t.map(a=>({label:a.target.label,result:a.result})),a=>a.kind==="curve"?a:a.kind==="profile"?ci(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));n.length>0&&r.push(p("p",{class:"analysis-elsewhere",text:`${n.join(", ")} ${n.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 n=Ye({output:t,task:`${this.current?.id??"task"}:combined`,uri:pt(this.context()),extras:[N("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(n),n.el}saveCombinedTsv(t,e){const n=W(new Date),i=new Blob([...ni(t,e)],{type:"text/tab-separated-values"});X(i,yt(this.current?.id??"task",t,n))}syncFraming(t){const e=this.options.framing();if(this.current!==null&&!J(this.current)){const n=sn(this.current);this.framingEl.className="analysis-framing",this.framingEl.textContent=t===null?`reads ${n}, not the map`:`from ${n}, not the map`,this.framingEl.title="",this.recomputeButton.classList.add("hidden");return}if(t!==null){const n=t.provenance,i=e!==null&&!ma(n,e);this.framingEl.className=i?"analysis-framing is-stale":"analysis-framing",this.framingEl.textContent=i?`from ${n.framing.label} — the view has moved since`:`from ${n.framing.label}`,this.framingEl.title=n.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 ${wn(t.ms)} at ${re(t)}`,this.recordNote.title=e.createdAt,this.paintCli(e),this.paintDocuments(t),this.notesEl.replaceChildren(...t.notes.map(n=>p("li",{text:n}))),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 n=[];let i=null;const o=()=>{i!==null&&(n.push(this.elsewhere(i.where,i.items,e)),i=null)};for(const r of t){const a=this.elsewhereOf(r);a===null?(o(),n.push(this.block(r,e))):i!==null&&i.where===a?i.items.push(r):(o(),i={where:a,items:[r]})}return o(),n}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 n=Ye({output:t,task:this.current?.id??"task",uri:pt(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(n),n.el}profileButtons(t,e){const n=i=>{this.options.writeProfile(t,e,i).catch(o=>{this.setStatus(o instanceof Error?o.message:String(o))})};return[N("bigWig",()=>n("bigwig"),{class:"btn",title:"Written here, byte for byte — no bedGraphToBigWig step. What IGV, deepTools and pyBigWig open."}),N("bedGraph",()=>n("bedgraph"),{class:"btn",title:"One line per bin that has a value; bins with none are omitted, never written as 0."})]}elsewhere(t,e,n){const i=e.length>1,o=t==="lane"?i?`${B.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?`${B.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?`${B.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,n)]:[],...r.kind==="intervals"&&r.entryKind==="structure"?[this.pdbButton(r,n)]:[],this.tsvButton(r,n))).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 n=this.options.surfaces?.(e)??null;t.replaceChildren(...n===null?[]:[n])}bedButton(t,e){const n=t.entryKind==="structure",i=n?"bed3d":t.payload.kind==="pairs"?"BEDPE":"BED";return N(i,()=>this.saveIntervals(t,e),{class:"btn",title:n?"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 n=W(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"?kn(o.data,i):Zt(o,i),l=r?"bed3d":o.kind==="pairs"?"bedpe":"bed";X(new Blob([a],{type:"text/plain"}),Ct(t,e,n,l))}pdbButton(t,e){const n=t.payload,i=n.kind==="features"?si(n.data):"This output holds no model.",o=N("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 n=t.payload;if(n.kind!=="features")return;const i=ii(n.data,{label:t.label,file:e.framing.label,created:e.createdAt});X(new Blob([i],{type:"text/plain"}),Ct(t,e,W(new Date),"pdb"))}tsvButton(t,e){return N("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 n=W(new Date),i=new Blob([...Xt(t,e)],{type:"text/tab-separated-values"});X(i,yt(e.task,t,n))}copyPng(t,e){let n;try{n=Yt(t)}catch(i){this.setStatus(i instanceof Error?i.message:String(i));return}oi(Dt(n)).then(()=>{this.setStatus(""),ri(`Copied ${e} · ${n.width} × ${n.height} px`)},i=>this.setStatus(`${e} could not be copied: ${i instanceof Error?i.message:String(i)}`))}async savePngPlain(t,e){const n=await ct(`${on(e)}-${W(new Date)}.png`,"image/png");if(n!==null)try{await n.write(await Dt(Yt(t))),this.setStatus("")}catch(i){this.setStatus(i instanceof Error?i.message:String(i))}}async savePdfPlain(t,e){const n=new Date,i=await ct(`${on(e)}-${W(n)}.pdf`,"application/pdf");if(i!==null)try{const o=ae(t.el),r=new xe(o.width,o.height);t.draw(r.ctx,o);const a=await r.toBlob({title:e,created:n});await i.write(a),this.setStatus("")}catch(o){this.setStatus(o instanceof Error?o.message:String(o))}}async savePng(t,e,n){const i=await ct(Ct(e,n,W(new Date),"png"),"image/png");if(i!==null)try{await i.write(await Dt(Yt(t))),this.setStatus("")}catch(o){this.setStatus(o instanceof Error?o.message:String(o))}}async savePdf(t,e,n){const i=new Date,o=await ct(Ct(e,n,W(i),"pdf"),"application/pdf");if(o!==null)try{const r=ae(t.el),a=new xe(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))}}paintDocuments(t){const n=(bt(t.provenance.task)?.documents??[]).filter(i=>i.shellOnly!==!0);this.documentsEl.replaceChildren(...n.map(i=>N(i.label,()=>{const o=ya(t.provenance.framing.uri),r=new Blob([i.write(t,o)],{type:i.type});X(r,`${o}.${t.provenance.task}.${i.id}-${W(new Date)}.${i.extension}`)},{class:"btn",title:"Every figure and table of this run on one page, with its notes and provenance, in a file that needs nothing beside it."})))}paintCli(t){const e=bt(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 n=bt(e.provenance.task);if(n===void 0)return;const o=t.map(({label:a,provenance:l})=>{const c=En({task:n,provenance:l,context:this.options.context(n)}).text;return a===null?c:`# ${a}
|
|
8
|
+
${c}`}).join(`
|
|
9
|
+
|
|
10
|
+
`),r=t.length>1?0:o.split(`
|
|
11
|
+
`).filter(a=>a.startsWith("#")).length;Se(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?ai(t.map(({label:n,provenance:i})=>({label:n??"",provenance:i}))):Bt(t[0].provenance)).join(`
|
|
12
|
+
`);Se(e).then(()=>{this.setStatus("Provenance copied.")},n=>{this.setStatus(n instanceof Error?n.message:String(n))})}}function is(s){return Number.isInteger(s)?String(s):String(Number(s.toPrecision(7)))}function os(s){return s!==void 0&&Number.isFinite(s)}function*wa(s,t,e){yield*Sn(Bt(e));const{values:n,extent:i,binsize:o}=s,r=new di;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=n[u-i[0]];if(!os(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} ${is(d)}`);h!==void 0&&(yield h)}const a=r.flush();a!==void 0&&(yield a)}function ka(s,t,e){const n=Bt(e),i=new Map;for(const o of s){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(!os(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)n.push(`${o.name} ${l} ${c} ${is(u)}`)}return Sn(n)}class $a{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?.()??Z},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 Rr({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 va({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=Me.find(m=>m.id===u.task);return hi(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 n=t.store(),i=this.runner.subscribe(()=>{this.panel.refresh(),this.drawer.refresh()});let o=n===null?"":ln(n);const r=n===null?()=>{}:n.subscribe(()=>{const a=ln(n);a!==o&&(o=a,this.drawer.fillSurfaces());const l=an(n);l!==this.entries&&(this.entries=l,this.refresh())});n!==null&&(this.entries=an(n)),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&&bn(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,n){const i=n.map,o=e.provenance.framing.uri,r=this.host.context(t),a=this.host.memoryKey?.(o)??o;if(Ut(a,t.id,fi(t,e.provenance.params,xn(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=mi(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,n,null,!1);for(const h of c)this.profiles.set(ft(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(ft(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=>ft(h.id,i)),...u.map(h=>cn(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=pi(h,y,h.colour??f,n),w=l.byId(g.id)?.revision??0;if(h.group!==void 0&&h.groupMode!==void 0){const S=this.host.groups?.()??null,A=gi(h.group,n);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:ft(c[c.length-1].id,i);for(const h of u){const y=h.lane?.under,g=this.adoptIntervals(t,e,h,l,n,y===void 0?m:"output"in y?ft(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,n,i,o,r,a=!0,l){const c=o.map,u={kind:"computed",name:n.label,task:t.id,recipe:{taskVersion:e.provenance.taskVersion,params:e.provenance.params,framing:e.provenance.framing},framing:e.provenance.framing.label},d=n.entryKind==="structure",f=cn(t.id,n.id,c),m=c===Z?n.label:`${n.label} · ${o.label}`,h={output:n,provenance:e.provenance,task:t.id};if(!d){const b=bi(i,{id:f,label:m,source:u,payload:n.payload,summary:rn(n),colour:i.byId(f)?.style.colour??l??i.nextColour(),map:c,display:a?n.display??(n.payload.kind==="pairs"?"overlay":"lane"):"overlay",look:n.look??"corner",overlay:this.host.context(t)?.hasMap??!0,under:r});return this.intervals.set(b,h),b}const y=xa(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:vi(),style:yi("structure",w)}),i.update(y,{status:"ready",payload:n.payload,summary:n.payload.kind==="features"?wi(n.payload.data):rn(n)}),this.intervals.set(y,h),null}carry(){const t=this.host.store();if(t===null)return[];const e=[];for(const n of t.entries){if(n.source.kind!=="computed")continue;const i=this.profiles.get(n.id),o=this.intervals.get(n.id);e.push({entry:n,...i===void 0?{}:{profile:i},...o===void 0?{}:{intervals:o}})}return e}placeOnTarget(t,e,n,i){i!==Z&&(t.placeOn(e,i,n),t.unplaceFrom(e,Z))}adoptCarried(t){const e=this.host.store();if(!(e===null||t.length===0)){for(const{entry:n,profile:i,intervals:o}of t){const r=n.source;r.kind==="computed"&&(e.begin({card:n.card,kind:n.kind,id:n.id,label:n.label,source:r,placement:n.placement,style:n.style,visible:n.visible,...n.partner===void 0?{}:{partner:n.partner}}),i!==void 0&&(this.profiles.set(n.id,i),this.register(n.id,i.output,i.grid)),o!==void 0&&this.intervals.set(n.id,o),e.update(n.id,{status:n.status,...n.summary===void 0?{}:{summary:n.summary},...n.payload===void 0?{}:{payload:n.payload},...n.fileExtent===void 0?{}:{fileExtent:n.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):ki(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(),n=this.host.context();if(e===null||n===null)return;const i=this.host.contigs();if(i.length===0)return;const o=n.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 $=Math.min(b,(v+1)*o)-Math.max(w,v*o);$>0&&(f[k]+=g*$,d[k]+=$)}}}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,n){const i=this.host.annotations();if(i===null)return;const o={binsize:e.binsize,firstBin:e.extent[0],values:e.values.slice(),contigs:n};i.request({kind:"register",entry:t,vector:o}).catch(()=>{})}recompute(t){const e=t.source;if(e.kind!=="computed")return;const n=Me.find(i=>i.id===e.task);n!==void 0&&this.show(n)}createdAt(t){return this.intervals.get(t)?.provenance.createdAt}async exportEntry(t,e){const n=W(new Date),i=$e(t.label);if(e==="anchors"){const a=Ee(t);if(a?.kind!=="pairs")return;const l=this.intervals.get(t.id),c=Zt({kind:"features",data:xi(a.data)},{label:`${t.label} anchors`,...l===void 0?{}:{file:l.provenance.framing.label,created:l.provenance.createdAt}});X(new Blob([c],{type:"text/plain"}),`${i}-anchors-${n}.bed`);return}if(e==="bed"){const a=Ee(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?kn(a.data,c):Zt(a,c),f=u?"bed3d":a.kind==="pairs"?"bedpe":"bed";X(new Blob([d],{type:"text/plain"}),`${i}-${n}.${f}`);return}const o=this.intervals.get(t.id);if(o!==void 0&&e==="tsv"){X(new Blob([...Xt(o.output,o.provenance)],{type:"text/tab-separated-values"}),yt(i,o.output,n));return}if(t.source.kind==="derived"){await this.exportDerived(t,e,i,n);return}const r=this.profiles.get(t.id);if(r!==void 0){if(e==="tsv"){X(new Blob([...Xt(r.output,r.provenance)],{type:"text/tab-separated-values"}),yt(i,r.output,n));return}await this.writeProfile(r.output,r.provenance,e,r.grid,i)}}async exportDerived(t,e,n,i){const o=t.derivedFrom,r=this.host.context();if(o===void 0||r===null||e==="bed")return;const a=await ct(`${n}-${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=Si(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=Sa(t,o.op,r),m=this.host.contigs();if(e==="tsv"){await a.write(new Blob([...Mi(t.label,Mn[o.op],d,m,f)],{type:"text/tab-separated-values"}));return}if(e==="bedgraph"){await a.write(new Blob([...ka(d,m,f)],{type:"text/plain"}));return}const h=await Te({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 n=this.host.contigs().filter(i=>i.length>0);if(n.length===0)return null;try{return await e.request({kind:"sample",entry:t,regions:n.map(i=>({contig:i.name,start:0,end:i.length})),basesPerPixel:1,exact:!0})}catch{return null}}async writeProfile(t,e,n,i,o=$e(t.label)){const r=W(new Date),a=await ct(`${o}-${r}.${n==="bedgraph"?"bedGraph":"bw"}`,n==="bedgraph"?"text/plain":"application/octet-stream");if(a===null)return;if(n==="bedgraph"){await a.write(new Blob([...wa(t,i,e)],{type:"text/plain"}));return}const l=await Te({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 xa(s,t){if(s.byId(t)===void 0)return t;for(let e=2;e<1e3;e++){const n=`${t}#${e}`;if(s.byId(n)===void 0)return n}return`${t}#${Date.now()}`}function rn(s){const t=s.payload,e=t.data.length,n=s.noun??(t.kind==="pairs"?{one:"pair",many:"pairs"}:{one:"interval",many:"intervals"});return`${B.int(e)} ${e===1?n.one:n.many}`}function Sa(s,t,e){const n=`${e.binsize.toLocaleString()} bp bins`;return{task:`track ${Mn[t]}`,taskVersion:1,params:{operation:t,of:s.label},framing:{uri:e.uri,label:e.hasMap?`two loaded tracks, read onto this file’s ${n}`:`two loaded tracks, read onto the assembly’s ${n}`,binsize:e.binsize,binsPerCell:1,rows:[0,e.nBins],cols:[0,e.nBins],balance:!1,value:"",normalise:null,level:"bin"},app:un,createdAt:new Date().toISOString()}}function an(s){return s.entries.map(t=>`${t.id}:${t.kind}:${t.status}:${t.label}`).join("|")}function ln(s){return s.entries.filter($i).map(t=>`${t.id}:${t.card}:${t.style.shape}`).join("|")}function cn(s,t,e){return e===Z?`analysis:${s}:${t}`:`analysis:${e}:${s}:${t}`}export{$a as AnalysisWorkspace,an as entrySignature,xa as freshId};
|
package/dist/index.html
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
<!-- The manifest, touch-icon and theme-color tags are stripped for this build. -->
|
|
28
28
|
<!-- Written by `npm run icons:app` (scripts/make-app-icons.py) — do not edit by hand. -->
|
|
29
29
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cdefs%3E%3ClinearGradient id='p' x2='0' y2='1'%3E%3Cstop stop-color='%232c231e'/%3E%3Cstop offset='1' stop-color='%230f0b09'/%3E%3C/linearGradient%3E%3ClinearGradient id='r' x2='0' y2='1'%3E%3Cstop stop-color='%23ffffff' stop-opacity='.333'/%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='.125'/%3E%3C/linearGradient%3E%3Crect id='c' x='.085' y='.085' width='.83' height='.83' rx='.141'/%3E%3C/defs%3E%3Crect width='1024' height='1024' rx='229.069' fill='url(%23p)'/%3E%3Cg fill='%23ce5c30' transform='translate(110.263 48.457) scale(123.611)'%3E%3Cuse href='%23c' x='0' y='0'/%3E%3Cuse href='%23c' x='1' y='0' opacity='.555'/%3E%3Cuse href='%23c' x='2' y='0' opacity='.308'/%3E%3Cuse href='%23c' x='6' y='0' opacity='.6'/%3E%3Cuse href='%23c' x='0' y='1' opacity='.555'/%3E%3Cuse href='%23c' x='1' y='1'/%3E%3Cuse href='%23c' x='2' y='1' opacity='.555'/%3E%3Cuse href='%23c' x='3' y='1' opacity='.065'/%3E%3Cuse href='%23c' x='4' y='1' opacity='.34'/%3E%3Cuse href='%23c' x='0' y='2' opacity='.308'/%3E%3Cuse href='%23c' x='1' y='2' opacity='.555'/%3E%3Cuse href='%23c' x='2' y='2'/%3E%3Cuse href='%23c' x='3' y='2' opacity='.099'/%3E%3Cuse href='%23c' x='4' y='2' opacity='.065'/%3E%3Cuse href='%23c' x='1' y='3' opacity='.065'/%3E%3Cuse href='%23c' x='2' y='3' opacity='.099'/%3E%3Cuse href='%23c' x='3' y='3'/%3E%3Cuse href='%23c' x='4' y='3' opacity='.555'/%3E%3Cuse href='%23c' x='5' y='3' opacity='.065'/%3E%3Cuse href='%23c' x='1' y='4' opacity='.34'/%3E%3Cuse href='%23c' x='2' y='4' opacity='.065'/%3E%3Cuse href='%23c' x='3' y='4' opacity='.555'/%3E%3Cuse href='%23c' x='4' y='4'/%3E%3Cuse href='%23c' x='5' y='4' opacity='.099'/%3E%3Cuse href='%23c' x='6' y='4' opacity='.065'/%3E%3Cuse href='%23c' x='3' y='5' opacity='.065'/%3E%3Cuse href='%23c' x='4' y='5' opacity='.099'/%3E%3Cuse href='%23c' x='5' y='5'/%3E%3Cuse href='%23c' x='6' y='5' opacity='.555'/%3E%3Cuse href='%23c' x='0' y='6' opacity='.6'/%3E%3Cuse href='%23c' x='4' y='6' opacity='.065'/%3E%3Cuse href='%23c' x='5' y='6' opacity='.555'/%3E%3Cuse href='%23c' x='6' y='6'/%3E%3C/g%3E%3Cg fill='%235eb1e0'%3E%3Crect x='48.457' y='58.964' width='37.083' height='102.597' rx='12.608'/%3E%3Crect x='48.457' y='182.576' width='37.083' height='102.597' rx='12.608' opacity='.52'/%3E%3Crect x='48.457' y='306.187' width='37.083' height='102.597' rx='12.608' opacity='.3'/%3E%3Crect x='48.457' y='429.798' width='37.083' height='102.597' rx='12.608' opacity='.86'/%3E%3Crect x='48.457' y='553.41' width='37.083' height='102.597' rx='12.608' opacity='.44'/%3E%3Crect x='48.457' y='677.021' width='37.083' height='102.597' rx='12.608' opacity='.74'/%3E%3Crect x='48.457' y='800.633' width='37.083' height='102.597' rx='12.608' opacity='.36'/%3E%3C/g%3E%3Cg fill='%236b8899'%3E%3Crect x='120.77' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.82'/%3E%3Crect x='244.381' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.38'/%3E%3Crect x='367.993' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.55'/%3E%3Crect x='491.604' y='938.459' width='102.597' height='37.083' rx='12.608'/%3E%3Crect x='615.216' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.34'/%3E%3Crect x='738.827' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.68'/%3E%3Crect x='862.438' y='938.459' width='102.597' height='37.083' rx='12.608' opacity='.46'/%3E%3C/g%3E%3Crect x='14.336' y='14.336' width='995.328' height='995.328' rx='214.733' fill='none' stroke='url(%23r)' stroke-width='28.672'/%3E%3C/svg%3E" />
|
|
30
|
-
<script type="module" crossorigin src="./assets/index-
|
|
31
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
30
|
+
<script type="module" crossorigin src="./assets/index-CPxipgOR.js"></script>
|
|
31
|
+
<link rel="stylesheet" crossorigin href="./assets/index-D34Q3Ivo.css">
|
|
32
32
|
</head>
|
|
33
33
|
<body>
|
|
34
34
|
<!-- What a reader without JavaScript sees, and all that a crawler which runs none reads of the page:
|