@apollo-annotation/jbrowse-plugin-apollo 0.2.1 → 0.2.2

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@apollo-annotation/common"),t=require("@apollo-annotation/shared"),n=require("@jbrowse/core/configuration"),a=require("@jbrowse/core/pluggableElementTypes"),o=require("@jbrowse/core/Plugin"),r=require("@jbrowse/core/util"),s=require("@mui/icons-material/Add"),l=require("mobx"),i=require("mobx-state-tree"),c=require("socket.io-client"),u=require("@gmod/gff"),d=require("@mui/icons-material/Link"),f=require("@mui/material"),m=require("@mui/material/InputAdornment"),g=require("@mui/material/LinearProgress"),p=require("bson-objectid"),h=require("react"),y=require("@jbrowse/core/ui"),b=require("@mui/icons-material/Close"),S=require("mobx-react"),w=require("tss-react/mui"),v=require("@jbrowse/core/util/types/mst"),C=require("idb/with-async-ittr"),E=require("@jbrowse/core/util/aborting"),x=require("jsonpath"),A=require("@jbrowse/core/util/io"),T=require("fast-deep-equal/es6"),k=require("file-saver"),N=require("@mui/material/Checkbox"),R=require("@mui/material/FormControlLabel"),D=require("@mui/icons-material/Delete"),F=require("@mui/x-data-grid"),M=require("@mui/material/utils"),I=require("autosuggest-highlight/match"),L=require("autosuggest-highlight/parse"),q=require("nanoid"),P=require("@mui/icons-material/AccountCircle"),U=require("@jbrowse/core/pluggableElementTypes/AdapterType"),B=require("@jbrowse/core/data_adapters/BaseAdapter"),_=require("@jbrowse/core/util/rxjs"),j=require("@jbrowse/core/util/simpleFeature"),O=require("@jbrowse/core/TextSearch/BaseResults"),$=require("@apollo-annotation/mst"),G=require("@jbrowse/core/util/tracks"),W=require("@mui/icons-material/Clear"),H=require("@mui/icons-material/UnfoldLess"),z=require("@mui/icons-material/ExpandLess"),V=require("@mui/icons-material/ExpandMore"),J=require("@mui/icons-material/Error"),X=require("@mui/icons-material/Save");function Y(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function K(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,a.get?a:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var Z=Y(o),Q=Y(s),ee=Y(u),te=Y(d),ne=Y(m),ae=Y(g),oe=Y(p),re=Y(h),se=K(h),le=Y(b),ie=Y(x),ce=Y(T),ue=Y(N),de=Y(R),fe=Y(D),me=Y(I),ge=Y(L),pe=Y(P),he=Y(U),ye=Y(j),be=Y(O),Se=Y(W),we=Y(H),ve=Y(z),Ce=Y(V),Ee=Y(J),xe=Y(X);const Ae=n.ConfigurationSchema("ApolloInternetAccount",{baseURL:{description:"Location of Apollo server",type:"string",defaultValue:""},tokenType:{description:"A custom name for a token to include in the header",type:"string",defaultValue:"Bearer"}},{baseConfiguration:a.BaseInternetAccountConfig,explicitlyTyped:!0});async function Te(e,n,a){const o=ee.default.parseStringSync(n,{parseSequences:!0,parseComments:!0,parseDirectives:!1,parseFeatures:!0});if(0===o.length)throw new Error("No features found in GFF3 file");let r=0,s=a.assemblies.get(e);s||(s=a.addAssembly(e,"InMemoryFileDriver"));for(const e of o)if(Array.isArray(e)){const n=t.gff3ToAnnotationFeature(e),a=s.refSeqs.get(n.refSeq)??s.addRefSeq(n.refSeq,n.refSeq);a.features.has(n._id)||a.addFeature(n)}else if("comment"in e)s.addComment(e.comment);else{r++;let t=s.refSeqs.get(e.id);t||(t=s.addRefSeq(e.id,e.id,e.description)),e.description&&!t.description&&t.setDescription(e.description),t.addSequence({start:0,stop:e.sequence.length,sequence:e.sequence})}if(0===r)throw new Error("No embedded FASTA section found in GFF3");const l=await ke(s);return a.addCheckResults(l),s}async function ke(t){const n=[];for(const a of t.refSeqs.values())for(const t of a.features.values())for(const o of e.checkRegistry.getChecks().values()){const e=await o.checkFeature(i.getSnapshot(t),((e,t)=>Promise.resolve(a.getSequence(e,t))));n.push(...e)}return n}async function Ne(e,t){let n;try{n=await e.text()}catch{n=""}return`${t?`${t} — `:""}${e.status} ${e.statusText}${n?` (${n})`:""}`}const Re=w.makeStyles()((e=>({dialogTitle:{background:e.palette.primary.main,color:e.palette.primary.contrastText,padding:e.spacing(2)},closeButton:{position:"absolute",right:e.spacing(1),top:e.spacing(1.5),color:e.palette.primary.contrastText}}))),De=S.observer((function(e){const{classes:t}=Re(),{handleClose:n,title:a,...o}=e;return re.default.createElement(y.Dialog,{...o,header:re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogTitle,{className:t.dialogTitle},a),re.default.createElement(f.IconButton,{"aria-label":"close",onClick:n,className:t.closeButton},re.default.createElement(le.default,null)))})}));var Fe;function Me({changeManager:e,handleClose:a,session:o}){const{internetAccounts:r}=i.getRoot(o),{notify:s}=o,l=r.filter((e=>"ApolloInternetAccount"===e.type));if(0===l.length)throw new Error("No Apollo internet account found");const[c,u]=h.useState(""),[d,m]=h.useState(""),[g,p]=h.useState(!1),[y,b]=h.useState(null),[S,w]=h.useState(Fe.GFF3),[v,C]=h.useState(!0),[E,x]=h.useState(!1),[A,T]=h.useState(l[0]),[k,N]=h.useState(""),[R,D]=h.useState(""),[F,M]=h.useState(""),[I,L]=h.useState(!1);let q=!1;try{const e=new URL(k);"http:"!==e.protocol&&"https:"!==e.protocol||(q=!0)}catch{}let P=!1;try{const e=new URL(R);"http:"!==e.protocol&&"https:"!==e.protocol||(P=!0)}catch{}let U=!1;try{const e=new URL(F);"http:"!==e.protocol&&"https:"!==e.protocol||(U=!0)}catch{}return re.default.createElement(De,{open:!0,maxWidth:!1,"data-testid":"add-assembly-dialog",title:"Add new assembly",handleClose:a},I?re.default.createElement(ae.default,null):null,re.default.createElement("form",{onSubmit:async function(n){n.preventDefault(),m(""),x(!0),L(!0),s(`Assembly "${c}" is being added`,"info"),a(),n.preventDefault();const{jobsManager:r}=o,l=new AbortController,i={name:`UploadAssemblyFile for ${c}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{l.abort(),r.abortJob(i.name)}};r.runJob(i);let u="";const{baseURL:d,getFetcher:f,internetAccountId:g}=A;if(S!==Fe.EXTERNAL&&y){const e=new URL("files",d);e.searchParams.set("type",S);const t=e.href,n=new FormData;n.append("file",y),n.append("fileName",y.name),n.append("type",S);const a=f({locationType:"UriLocation",uri:t});if(a){r.update(i.name,"Uploading file, this may take awhile");const{signal:e}=l,o=await a(t,{method:"POST",body:n,signal:e});if(!o.ok){const e=await Ne(o,"Error when inserting new assembly (while uploading file)");return r.abortJob(i.name,e),void m(e)}u=(await o.json())._id}}let p;if(S===Fe.EXTERNAL)p=new t.AddAssemblyFromExternalChange({typeName:"AddAssemblyFromExternalChange",assembly:(new oe.default).toHexString(),assemblyName:c,externalLocation:{fa:k,fai:R,...F?{gzi:F}:{}}});else{const e={assembly:(new oe.default).toHexString(),assemblyName:c,fileIds:{fa:u}};p=S===Fe.GFF3&&v?new t.AddAssemblyAndFeaturesFromFileChange({typeName:"AddAssemblyAndFeaturesFromFileChange",...e}):new t.AddAssemblyFromFileChange({typeName:"AddAssemblyFromFileChange",...e})}r.done(i),await e.submit(p,{internetAccountId:g,updateJobsManager:!0}),x(!1),L(!1)}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},l.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:A.internetAccountId,onChange:function(e){x(!1);const t=l.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);T(t)},disabled:E&&!d},r.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.TextField,{margin:"dense",id:"name",label:"Assembly name",type:"TextField",fullWidth:!0,variant:"outlined",onChange:e=>{x(!1),u(e.target.value),function(e){const{assemblies:t}=o;t.find((t=>n.readConfObject(t,"displayName")===e))?(p(!1),m(`Assembly ${e} already exists.`)):(p(!0),m(""))}(e.target.value)},disabled:E&&!d}),re.default.createElement(f.FormControl,{style:{marginTop:20}},re.default.createElement(f.FormLabel,null,"Select GFF3, FASTA or EXTERNAL option"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:Fe.GFF3,name:"radio-buttons-group",onChange:function(e){w(e.target.value),C(e.target.value===Fe.GFF3),N(""),D(""),b(null)},value:S},re.default.createElement(f.FormControlLabel,{value:Fe.GFF3,control:re.default.createElement(f.Radio,null),label:"GFF3",disabled:E&&!d}),re.default.createElement(f.FormControlLabel,{value:Fe.FASTA,control:re.default.createElement(f.Radio,null),label:"FASTA",disabled:E&&!d}),re.default.createElement(f.FormControlLabel,{value:Fe.EXTERNAL,control:re.default.createElement(f.Radio,null),label:"External",disabled:E&&!d}))),S===Fe.EXTERNAL?re.default.createElement(f.Box,{style:{marginTop:20}},re.default.createElement(f.Typography,{variant:"caption"},"Enter FASTA and FASTA index(es) URL"),re.default.createElement(f.TextField,{margin:"dense",helperText:"Can be bgz-compressed",id:"fasta",label:"FASTA",type:"TextField",fullWidth:!0,variant:"outlined",error:!q,onChange:e=>{N(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}}),re.default.createElement(f.TextField,{margin:"dense",id:"fasta-index",label:"FASTA Index",helperText:".fai or .gz.fai",type:"TextField",fullWidth:!0,variant:"outlined",error:!P,onChange:e=>{D(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}}),re.default.createElement(f.TextField,{margin:"dense",id:"fasta-gzi-index",label:"FASTA GZI Index",helperText:"Only for bgz-compressed FASTA, .gz.gzi",type:"TextField",fullWidth:!0,variant:"outlined",error:Boolean(F)&&!U,onChange:e=>{M(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}})):re.default.createElement(f.Box,{style:{marginTop:20}},re.default.createElement("input",{type:"file",onChange:function(e){if(!e.target.files)return;const t=e.target.files.item(0);if(b(t),!t)return;const n=t.name.toLowerCase();n.endsWith(".fasta")||n.endsWith(".fna")||n.endsWith(".fa")?w(Fe.FASTA):(n.endsWith(".gff3")||n.endsWith(".gff"))&&w(Fe.GFF3)},disabled:E&&!d}),re.default.createElement(f.FormGroup,null,re.default.createElement(f.FormControlLabel,{control:re.default.createElement(f.Checkbox,{checked:S===Fe.GFF3&&v,onChange:()=>{C(!v)},disabled:S!==Fe.GFF3||E&&!d}),label:"Also load features from GFF3 file"})))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!g||!((c&&y)??(c&&k&&R&&q&&P))||E,variant:"contained",type:"submit"},E?"Submitting...":"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),d?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},d)):null)}!function(e){e.GFF3="text/x-gff3",e.FASTA="text/x-fasta",e.EXTERNAL="text/x-external"}(Fe||(Fe={}));const Ie=new Set(["i","me","my","myself","we","our","ours","ourselves","you","your","yours","yourself","yourselves","he","him","his","himself","she","her","hers","herself","it","its","itself","they","them","their","theirs","themselves","what","which","who","whom","this","that","these","those","am","is","are","was","were","be","been","being","have","has","had","having","do","does","did","doing","a","an","the","and","but","if","or","because","as","until","while","of","at","by","for","with","about","against","between","into","through","during","before","after","above","below","to","from","up","down","in","out","on","off","over","under","again","further","then","once","here","there","when","where","why","how","all","any","both","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","s","t","can","will","just","don","should","now",..."1234567890"]);function Le(e,t){for(const[n,a]of t.entries())if(e.startsWith(a))return e.replace(a,n);return e}const qe="$PREFIXED_ID";function Pe(e,t,n){return t===qe?[Le(e.id,n)]:ie.default.query(e,t)}function Ue(e){return e.toLowerCase().split(/[^\d:A-Za-z]+/).filter((e=>e&&!Ie.has(e)))}function*Be(e){for(const t of e)yield*Ue(t)}function*_e(e){for(const t of e)if("string"==typeof t)yield t;else if("object"==typeof t){const e=ie.default.query(t,"$..*");yield*_e(e)}}function*je(e,t,n){for(const a of t){const t=Pe(e,a,n);if(t.length>0)for(const e of Be(_e(t)))yield[a,e]}}async function Oe(e,t,n){const a=await this.db,o=t??a.transaction(["nodes"]);E.checkAbortSignal(n);const r=[...Ue(e)],s=[],l=new Map;s.push(...r.map((async(e,t)=>{E.checkAbortSignal(n);const a=o.objectStore("nodes").index("full-text-words");for await(const o of a.iterate(IDBKeyRange.bound(e,`${e}￿`,!1,!1))){E.checkAbortSignal(n);const e=o.value,a=l.get(e.id)??[e,new Set];a[1].add(t),l.set(e.id,a)}}))),await Promise.all(s),E.checkAbortSignal(n);const i=[];for(const[,[e,t]]of l)E.checkAbortSignal(n),i.push(...$e(this.textIndexFields,e,t,r,this.prefixes));return i.sort(((e,t)=>t.score-e.score)),i.slice(0,this.options.maxSearchResults??this.DEFAULT_MAX_SEARCH_RESULTS)}function $e(e,t,n,a,o){const r=[...n].sort().map((e=>a[e])),s=r.map((e=>{const t=e.replaceAll(/[$()*+./?[\\\]^{|}-]/g,String.raw`\$&`);return new RegExp(`\\b${t}`,"gi")}));let l=[],i=0;for(const[n,r]of e.entries()){const c=new Set,u=e.length-n-1,d=[..._e(Pe(t,r.jsonPath,o))];for(const e of d){let n=0;const o=[];for(const[t,r]of s.entries())for(const s of e.matchAll(r)){n+=1+1*u,c.add(t);const r=s.index,l=a[t];void 0!==r&&(n+=.01*l.length,n+=l.length/e.length*100*.05,o.push({wordIndex:t,position:r}))}n+=100*c.size,i<n&&(i=n),o.sort(((e,t)=>e.position-t.position)),o.length>0&&l.push({term:t,field:r,str:e,score:n,wordMatches:o})}}l=l.filter((e=>e.score===i));for(const e of l){const{wordMatches:t}=e;for(let n=0;n<t.length-1;n++){const a=t[n],o=t[n+1],s=o.wordIndex-a.wordIndex;if(1===s||-1===s){e.score+=1,1===s&&(e.score+=1);const t=Math.abs(o.position-(a.position+r[a.wordIndex].length))-1;e.score-=.05*t}}}return l}function Ge(e){return"string"==typeof e.id}function We(e){return"string"==typeof e.sub&&"string"==typeof e.pred&&"string"==typeof e.obj}function He(e){return Boolean(e.meta?.deprecated)}async function ze(e){return C.openDB(e,2,{upgrade(e,t,n,a,o){if(t<2&&(e.objectStoreNames.contains("meta")&&e.deleteObjectStore("meta"),e.objectStoreNames.contains("nodes")&&e.deleteObjectStore("nodes"),e.objectStoreNames.contains("edges")&&e.deleteObjectStore("edges")),e.objectStoreNames.contains("meta")||e.createObjectStore("meta"),!e.objectStoreNames.contains("nodes")){e.createObjectStore("nodes",{keyPath:"id"});const t=a.objectStore("nodes");t.createIndex("by-label","lbl"),t.createIndex("by-type","type"),t.createIndex("by-synonym",["meta","synonyms","val"]),t.createIndex("full-text-words","fullTextWords",{multiEntry:!0})}if(!e.objectStoreNames.contains("edges")){e.createObjectStore("edges",{autoIncrement:!0});const t=a.objectStore("edges");t.createIndex("by-subject","sub"),t.createIndex("by-object","obj"),t.createIndex("by-predicate","pred")}}})}function Ve(e){const t=new Set;for(const[,n]of e)t.add(n);return[...t]}async function Je(e){const t=Date.now();let n;try{n=JSON.parse(await A.openLocation(this.sourceLocation).readFile("utf8"))}catch{throw new Error("Error in loading ontology")}const a=Date.now(),[o,...r]=n.graphs??[];if(o){if(r.length>0)throw new Error("multiple graphs not supported");try{const n=e.transaction(["meta","nodes","edges"],"readwrite");await n.objectStore("meta").clear(),await n.objectStore("nodes").clear(),await n.objectStore("edges").clear();const r=n.objectStore("nodes"),s=Xe.call(this).map((e=>e.jsonPath));for(const e of o.nodes??[])Ge(e)&&await r.add({...e,fullTextWords:Ve(je(e,s,this.prefixes))});const l=n.objectStore("edges");for(const e of o.edges??[])We(e)&&await l.add(e);await n.done;const i=e.transaction("meta","readwrite");await i.objectStore("meta").add({ontologyRecord:{name:this.ontologyName,version:this.ontologyVersion,sourceLocation:this.sourceLocation},storeOptions:this.options,graphMeta:o.meta,timestamp:String(new Date),schemaVersion:2,timings:{overall:Date.now()-t,load:Date.now()-a}},"meta"),await i.done}catch(t){throw await e.transaction("meta","readwrite").objectStore("meta").clear(),t}}}function Xe(){return[{displayName:"ID",jsonPath:qe},...this.options.textIndexing?.indexFields??et]}async function Ye(e){const[t]=await e.transaction("meta").objectStore("meta").getAll();return!!t&&ce.default(this.options.prefixes,t.storeOptions.prefixes)&&ce.default(this.options.textIndexing,t.storeOptions.textIndexing)}class Ke{ontologyName;ontologyVersion;sourceLocation;db;options;loadOboGraphJson=Je;getTermsByFulltext=Oe;openDatabase=ze;isDatabaseCurrent=Ye;get textIndexFields(){return Xe.call(this)}get prefixes(){return this.options.prefixes??new Map}DEFAULT_MAX_SEARCH_RESULTS=100;constructor(e,t,n,a){this.ontologyName=e,this.ontologyVersion=t,this.sourceLocation=n,this.db=this.prepareDatabase(),this.options=a??{}}validate(){const e=[],{sourceLocation:t,sourceType:n}=this;return n?"obo-graph-json"!==n&&e.push(new Error(`ontology source file ${JSON.stringify(t)} has type ${n}, which is not yet supported`)):e.push(new Error(`unable to determine format of ontology source file ${JSON.stringify(t)}, file name must end with ".json", ".obo", or ".owl"`)),e}get sourceType(){if(r.isUriLocation(this.sourceLocation)){if(this.sourceLocation.uri.endsWith(".json"))return"obo-graph-json"}else if(r.isLocalPathLocation(this.sourceLocation)&&this.sourceLocation.localPath.endsWith(".json"))return"obo-graph-json"}get dbName(){return`Apollo Ontology "${this.ontologyName}" "${this.ontologyVersion}"`}async prepareDatabase(){const e=this.validate();if(e.length>0)throw e;const t=await this.openDatabase(this.dbName);if(await this.isDatabaseCurrent(t))return t;try{const{sourceLocation:e,sourceType:n}=this;if("obo-graph-json"!==n)throw new Error(`ontology source file ${JSON.stringify(e)} has type ${n}, which is not yet supported`);return await this.loadOboGraphJson(t),t}catch(e){throw t.close(),await C.deleteDB(this.dbName),e}}async termCount(e){const t=await this.db;return(e??t.transaction("nodes")).objectStore("nodes").count()}unique(e){const t=new Map,n=[];for(const a of e)t.has(a.id)||(t.set(a.id,!0),n.push(a));return n}async getTermsWithLabelOrSynonym(e,t,n){const a=t?.includeSubclasses??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=r.objectStore("nodes"),l=[...await s.index("by-label").getAll(e),...await s.index("by-synonym").getAll(e)];if(a){const e=await this.recurseEdges("by-object",l.map((e=>e.id)),(e=>"is_a"===e.pred),"sub",r);for(const t of e){const e=await s.get(t);e&&l.push(e)}}return l}async getPropertiesByLabel(e,t,n){const a=t?.includeSubProperties??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=(await this.getTermsWithLabelOrSynonym(e,{includeSubclasses:!1},r)).filter((e=>at(e)));if(a){const e=await this.recurseEdges("by-object",s.map((e=>e.id)),(e=>"subPropertyOf"===e.pred),"sub",r),t=r.objectStore("nodes");for(const n of e){const e=await t.get(n);e&&at(e)&&s.push(e)}}return s}async recurseEdges(e,t,n,a,o){const r=new Set;return await async function t(s){await Promise.all([...s].map((async s=>{const l=(await o.objectStore("edges").index(e).getAll(s)).filter((e=>n(e))).map((e=>e[a]));if(l.length>0){for(const e of l)r.add(e);await t(l)}})))}(t),r.values()}async*expandNodeSet(e,t="is_a",n,a){const o=await this.db,r=a??o.transaction(["edges"]),s=[...e],l=await this.recurseEdges("subclasses"===n?"by-object":"by-subject",s,(e=>e.pred===t),"subclasses"===n?"sub":"obj",r);for(const e of s)yield e;for(const e of l)yield e}expandSubclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"subclasses",n)}expandSuperclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"superclasses",n)}async getClassesThat(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=await this.getPropertiesByLabel(e,{includeSubProperties:!0},o),s=new Set(r.map((e=>e.id))),l=await async function(e){const t=[];for await(const n of e)t.push(n);return t}(this.expandSuperclasses(t.map((e=>e.id)),"is_a",o)),i=await this.recurseEdges("by-object",l,(e=>s.has(e.pred)),"sub",o),c=this.expandSubclasses(i,"is_a",o),u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&nt(t)&&!He(t)&&u.push(t)}return u}async getClassesWithoutPropertyLabeled(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=o.objectStore("nodes"),s=o.objectStore("edges"),l=(await this.getPropertiesByLabel(e,t,o)).map((e=>e.id)),i=await(async()=>{const e=new Set;for(const t of l)for await(const n of s.index("by-predicate").iterate(t))e.add(n.value.sub);const t=new Set;for await(const n of this.expandSubclasses(e,"is_a",o))t.add(n);return t})(),c=[];for await(const e of r){const t=e.value;nt(t)&&!i.has(t.id)&&c.push(t.id)}const u=[];for(const e of c){const t=await o.objectStore("nodes").get(e);t&&nt(t)&&!He(t)&&u.push(t)}return u}async getAllClasses(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").index("by-type").getAll("CLASS")).filter((e=>!He(e)))}async getAllTerms(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").getAll()).filter((e=>!He(e)))}}const Ze=i.types.model("OntologyRecord",{name:i.types.string,version:"unversioned",source:i.types.union(v.LocalPathLocation,v.UriLocation,v.BlobLocation),options:i.types.frozen()}).volatile((e=>({dataStore:void 0}))).actions((e=>({ping(){},initDataStore(){e.dataStore=new Ke(e.name,e.version,i.getSnapshot(e.source),e.options)},afterCreate(){i.addDisposer(e,l.autorun((()=>{this.initDataStore()})))}}))),Qe=i.types.model("OntologyManager",{ontologies:i.types.array(Ze),prefixes:i.types.optional(i.types.map(i.types.string),{"GO:":"http://purl.obolibrary.org/obo/GO_","SO:":"http://purl.obolibrary.org/obo/SO_"})}).views((e=>({get featureTypeOntologyName(){const t=i.getRoot(e).jbrowse.configuration;return n.readConfObject(t.ApolloPlugin,"featureTypeOntologyName")}}))).views((e=>({get featureTypeOntology(){return this.findOntology(e.featureTypeOntologyName)},findOntology:(t,n)=>e.ontologies.find((e=>e.name===t&&(void 0===n||e.version===n))),openOntology(e,t){return this.findOntology(e,t)?.dataStore},applyPrefixes:t=>Le(t,e.prefixes),expandPrefixes:t=>function(e,t){for(const[n,a]of t.entries())if(e.startsWith(n))return e.replace(n,a);return e}(t,e.prefixes)}))).actions((e=>({addOntology(t,n,a,o){const r=e.ontologies.push({name:t,version:n,source:a,options:{prefixes:new Map(e.prefixes.entries()),...o}});e.ontologies[r-1].ping()}}))),et=[{displayName:"Label",jsonPath:"$.lbl"},{displayName:"Synonym",jsonPath:"$.meta.synonyms[*].val"},{displayName:"Definition",jsonPath:"$.meta.definition.val"}],tt=n.ConfigurationSchema("OntologyRecord",{name:{type:"string",description:'the full name of the ontology, e.g. "Gene Ontology"',defaultValue:"My Ontology"},version:{type:"string",description:"the ontology's version string",defaultValue:"unversioned"},source:{type:"fileLocation",description:"the download location for the ontology's source file",defaultValue:{locationType:"UriLocation",uri:"http://example.com/myontology.json"}},textIndexFields:{type:"frozen",description:"JSON paths for text fields that will be indexed for text searching",defaultValue:et}});function nt(e){return"CLASS"===e.type}function at(e){return"PROPERTY"===e.type}async function ot(e,t,n){if(!e)return;const a=await t.getTermsWithLabelOrSynonym(e.type,{includeSubclasses:!1}),o=a.filter(nt);if(0===a.length)return;const r=await t.getClassesThat("part_of",o);return 0!==r.length?r:void 0}function rt({fetchValidTerms:e,filterTerms:t,includeDeprecated:n,onChange:a,ontologyName:o,ontologyVersion:r,renderInput:s,session:l,style:i,value:c}){const[u,d]=h.useState(!1),[m,g]=h.useState(),[p,y]=h.useState(""),[b,S]=h.useState(),{ontologyManager:w}=l.apolloDataStore,v=w.findOntology(o,r)?.dataStore,C=v&&u&&!m,x=v&&!b,A=h.useCallback((e=>(n||!He(e))&&(!t||t(e))),[t,n]);h.useEffect((()=>{u||g(void 0)}),[u]),h.useEffect((()=>{const e=new AbortController,{signal:t}=e;return x&&(y(""),async function(e,t,n,a){if(!t)return;const o=(await e.getTermsWithLabelOrSynonym(t,{includeSubclasses:!1})).find((e=>(n??(()=>!0))(e)));if(!o)throw new Error(`not a valid ${e.ontologyName} term`);return o}(v,c,A).then((e=>{t.aborted||S(e)}),(e=>{t.aborted||E.isAbortException(e)||y(String(e))}))),()=>{e.abort()}}),[l,c,A,v,x]),h.useEffect((()=>{const t=new AbortController,{signal:n}=t;return C&&async function(e,t,n,a){let o;if(t){const n=await t(e,a);n&&(o=n)}return o||(o=await e.getAllTerms()),n?o.filter((e=>n(e))):o}(v,e,A,n).then((e=>{e&&!n.aborted&&g(e)}),(e=>{n.aborted||E.isAbortException(e)||l.notify(e instanceof Error?e.message:String(e),"error")})),()=>{t.abort()}}),[C,A,v,l,e]);const T={};return p&&(T.error=!0,T.helperText=p),re.default.createElement(f.Autocomplete,{style:i,autoComplete:!0,filterSelectedOptions:!0,disableClearable:!0,selectOnFocus:!0,clearOnBlur:!0,handleHomeEndKeys:!0,freeSolo:!0,value:c,options:m??[],onOpen:()=>{d(!0)},onClose:()=>{d(!1)},loading:C,renderInput:s??(e=>re.default.createElement(f.TextField,{...e,...T})),getOptionLabel:e=>"string"==typeof e?e:e.lbl??"",isOptionEqualToValue:(e,t)=>e.lbl===t.lbl,onChange:(e,t)=>{t&&("string"==typeof t?(S(void 0),a(c,t)):t.lbl!==c&&(y(""),S(t),a(c,t.lbl)))}})}function st({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,[l,i]=h.useState(String(r.max)),[c,u]=h.useState(String(r.min+1)),[d,m]=h.useState(""),[g,p]=h.useState(""),[y,b]=h.useState(""),S=Number(l)<=Number(c);return re.default.createElement(De,{open:!0,title:"Add new child feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},re.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),p("");const i=new t.AddFeatureChange({changedIds:[r._id],typeName:"AddFeatureChange",assembly:o,addedFeature:{_id:(new oe.default).toHexString(),refSeq:r.refSeq,min:Number(c)-1,max:Number(l),type:d},parentFeatureId:r._id});await e.submit(i),s("Feature added successfully","success"),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:c,onChange:e=>{u(e.target.value)}}),re.default.createElement(f.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:l,onChange:e=>{i(e.target.value)},error:S,helperText:S?'"End" must be greater than "Start"':null}),re.default.createElement(rt,{session:a,ontologyName:"Sequence Ontology",style:{width:170},value:d,filterTerms:nt,fetchValidTerms:async function(e,t,n){const a=await ot(e,t);if(a)return a;b(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,r),renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(y),helperText:y}),onChange:(e,t)=>{var n;t&&(n=t,p(""),m(n))}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:S||!(c&&l&&d)},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),g?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},g)):null)}function lt({changeManager:e,handleClose:n,region:a,session:o}){const{notify:r}=o,[s,l]=h.useState(String(a.end)),[i,c]=h.useState(String(a.start+1)),[u,d]=h.useState(""),[m,g]=h.useState(),[p,y]=h.useState(""),b=Number(s)<=Number(i);return re.default.createElement(De,{open:!0,title:"Add new feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},re.default.createElement("form",{onSubmit:async function(l){let c;l.preventDefault(),y("");for(const[,e]of o.apolloDataStore.assemblies??new Map)if(e._id===a.assemblyName)for(const[,t]of e.refSeqs??new Map)t.name===a.refName&&(c=t._id);if(!c)return void y("Invalid refseq id");const d=(new oe.default).toHexString(),f=new t.AddFeatureChange({changedIds:[d],typeName:"AddFeatureChange",assembly:a.assemblyName,addedFeature:{_id:d,refSeq:c,min:Number(i)-1,max:Number(s),type:u,strand:m}});await e.submit(f),r("Feature added successfully","success"),n(),l.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:Number(i),onChange:e=>{c(e.target.value)}}),re.default.createElement(f.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:s,onChange:e=>{l(e.target.value)},error:b,helperText:b?'"End" must be greater than "Start"':null}),re.default.createElement(rt,{session:o,ontologyName:"Sequence Ontology",style:{width:170},value:u,filterTerms:nt,renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0}),onChange:(e,t)=>{var n;t&&(n=t,y(""),d(n))}}),re.default.createElement(f.FormControl,null,re.default.createElement(f.InputLabel,{id:"demo-simple-select-label"},"Strand"),re.default.createElement(f.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Strand",value:m?.toString(),onChange:function(e){switch(y(""),Number(e.target.value)){case 1:g(1);break;case-1:g(-1);break;default:g(void 0)}}},re.default.createElement(f.MenuItem,{value:void 0}),re.default.createElement(f.MenuItem,{value:1},"+"),re.default.createElement(f.MenuItem,{value:-1},"-")))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:b||!(i&&s&&u)},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),p?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},p)):null)}function it(e,t){const n=(new oe.default).toHexString();t.push(n);const a={};if(e.children)for(const n of Object.values(e.children)){const e=it(n,t);a[e._id]=e}const o="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString();return{...e,refSeq:o,children:e.children&&a,_id:n}}function ct({changeManager:e,handleClose:a,session:o,sourceAssemblyId:r,sourceFeature:s}){const{assemblyManager:l,notify:c}=o,u=l.assemblyList,[d,m]=h.useState(u.find((e=>e.name!==r))?.name),[g,p]=h.useState([]),[y,b]=h.useState(""),[S,w]=h.useState(s.min),[v,C]=h.useState("");function E(e,t){const n={};if(e.children)for(const a of Object.values(e.children)){const e=E(a,t);e.refSeq=y,e.min=e.min+t,e.max=e.max+t,n[e._id]=e}const a="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString(),o="string"==typeof e._id?e._id:e._id.toHexString();return{...e,refSeq:a,children:e.children&&n,_id:o}}return h.useEffect((()=>{b(""),async function(){if(!d)return void C("No assemblies to copy to");const e=await l.waitForAssembly(d);if(!e)return;const{refNameAliases:t}=e;if(!t)return;const n=[...Object.entries(t)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""})));p(n),b(n[0]?._id||"")}().catch((e=>{C(String(e))}))}),[d,l]),re.default.createElement(De,{open:!0,title:"Copy features and annotations",handleClose:a,maxWidth:!1,"data-testid":"copy-feature"},re.default.createElement("form",{onSubmit:async function(n){if(!d)return;n.preventDefault(),C("");const o=s.length,r=await l.waitForAssembly(d);if(!r)return void C(`Assembly not found: ${d}.`);const u=r.getCanonicalRefName(y),f=r.regions?.find((e=>e.refName===u));if(!f)return void C(`RefSeq not found: ${y}.`);const m=S+o;if(m>f.end)return void C(`Feature would extend beyond the bounds of the selected reference sequence. (Feature would end at ${m}, but reference sequence ends at ${f.end})`);if(S<f.start)return void C(`Reference sequence starts at ${f.start}, feature cannot start before that.`);const g=[],p=it(i.getSnapshot(s),g),h={...p.attributes};"Parent"in h&&delete h.Parent,p.refSeq=y;const b=S-p.min;p.min=S,p.max=S+o;const w=E(p,b),v=new t.AddFeatureChange({changedIds:[p._id],typeName:"AddFeatureChange",assembly:d,addedFeature:{_id:p._id,refSeq:p.refSeq,min:p.min,max:p.max,type:p.type,children:w.children,attributes:h,strand:p.strand},copyFeature:!0,allIds:g});await e.submit(v),c("Feature copied successfully","success"),a(),n.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Target assembly"),re.default.createElement(f.Select,{labelId:"label",value:d,onChange:function(e){m(e.target.value)}},u.filter((e=>e.name!==r)).map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},n.readConfObject(e,"displayName"))))),re.default.createElement(f.DialogContentText,null,"Target reference sequence"),re.default.createElement(f.Select,{labelId:"label",value:y,onChange:function(e){b(e.target.value)}},g.map((e=>re.default.createElement(f.MenuItem,{key:e._id,value:e._id},e.name)))),re.default.createElement(f.DialogContentText,null,"Start position in target reference sequence"),re.default.createElement(f.TextField,{margin:"dense",type:"number",fullWidth:!0,variant:"outlined",value:S,onChange:e=>{w(Number(e.target.value))}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!d||!y||!S,variant:"contained",type:"submit"},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),v?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},v)):null)}function ut({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),[r,s]=h.useState(),[l,c]=h.useState(""),[u,d]=h.useState(!1),[m,g]=h.useState(!1),p=o.filter((e=>"ApolloInternetAccount"===e.type));if(0===p.length)throw new Error("No Apollo internet account found");const[y,b]=h.useState(p[0]),{collaborationServerDriver:S}=a.apolloDataStore,w=S.getAssemblies();return h.useEffect((()=>{w.length>0&&void 0===r&&s(w[0])}),[w,r]),re.default.createElement(De,{open:!0,title:"Delete Assembly",handleClose:n,maxWidth:!1,"data-testid":"delete-assembly"},re.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),g(!0),c(""),!r)return void c("Must select assembly!");const o=new t.DeleteAssemblyChange({typeName:"DeleteAssemblyChange",assembly:r.name});await e.submit(o,{internetAccountId:y.internetAccountId}),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},p.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:y.internetAccountId,onChange:function(e){g(!1);const t=p.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);b(t)},disabled:m&&!l},o.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:r?.name??"",onChange:function(e){const t=w.find((t=>t.name===e.target.value));s(t)},disabled:0===w.length},w.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContentText,null,re.default.createElement("strong",{style:{color:"red"}},"NOTE: All assembly data will be deleted and this operation cannot be undone!")),re.default.createElement(f.FormGroup,null,re.default.createElement(f.FormControlLabel,{control:re.default.createElement(f.Checkbox,{checked:u,onChange:()=>{d(!u)}}),label:"I understand that all assembly data will be deleted"}))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!r||!u,variant:"contained",type:"submit"},"Delete"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),l?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},l)):null)}function dt({changeManager:e,handleClose:n,selectedFeature:a,session:o,setSelectedFeature:r,sourceAssemblyId:s,sourceFeature:l}){const{notify:c}=o,[u,d]=h.useState("");return re.default.createElement(De,{open:!0,title:"Delete feature",handleClose:n,maxWidth:!1,"data-testid":"delete-feature"},re.default.createElement("form",{onSubmit:async function(o){o.preventDefault(),d(""),a?._id===l._id&&r();const u=new t.DeleteFeatureChange({changedIds:[l._id],typeName:"DeleteFeatureChange",assembly:s,deletedFeature:i.getSnapshot(l),parentFeatureId:l.parent?._id});await e.submit(u),c("Feature deleted successfully","success"),n(),o.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Are you sure you want to delete the selected feature?")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit"},"Yes"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),u?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},u)):null)}function ft({handleClose:e,session:a}){const[o,r]=h.useState(),[s,l]=h.useState(""),{collaborationServerDriver:c,getInternetAccount:u,inMemoryFileDriver:d}=a.apolloDataStore,m=[...c.getAssemblies(),...d.getAssemblies()];return re.default.createElement(De,{open:!0,title:"Export GFF3",handleClose:e,maxWidth:!1,"data-testid":"download-gff3"},re.default.createElement("form",{onSubmit:async function(r){if(r.preventDefault(),l(""),!o)return void l("Must select assembly to download");const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]);s?await async function(e){if(!o)return void l("Must select assembly to download");const t=u(o.configuration.name,e),n=new URL("export/getID",t.baseURL),a=new URLSearchParams({assembly:o.name});n.search=a.toString();const r=n.toString(),s=t.getFetcher({locationType:"UriLocation",uri:r}),i=await s(r,{method:"GET"});if(!i.ok){const e=await Ne(i,"Error when exporting ID");return void l(e)}const{exportID:c}=await i.json(),d=new URL("export",t.baseURL),f=new URLSearchParams({exportID:c});d.search=f.toString();const m=d.toString();window.open(m,"_blank")}(s):function(e){if(!o)return void l("Must select assembly to download");const{assemblies:a}=e.apolloDataStore,r=a.get(o.name),s=r?.refSeqs;if(!s)return void l(`No refSeqs found for assembly "${o.name}"`);const c=[{directive:"gff-version",value:"3"}],u=n.getConf(o,["sequence","adapter","features"]);for(const e of u){const{end:t,refName:n,start:a}=e;c.push({directive:"sequence-region",value:`${n} ${a+1} ${t}`})}for(const[,e]of s){const{features:n}=e;if(n)for(const[,e]of n)c.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const e of u){const{refName:t,seq:n}=e;c.push({id:t,description:"",sequence:n})}const d=ee.default.formatSync(c),f=new Blob([d],{type:"text/plain;charset=utf-8"});k.saveAs(f,`${o.displayName??o.name}.gff3`)}(a),e()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:o?.name??"",onChange:function(e){const t=m.find((t=>t.name===e.target.value));r(t)},disabled:0===m.length},m.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContentText,null,"Select assembly to export to GFF3")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!o,variant:"contained",type:"submit"},"Download"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function mt({changeManager:e,handleClose:a,session:o}){const{apolloDataStore:r}=o,[s,l]=h.useState(),[i,c]=h.useState(),[u,d]=h.useState(""),[m,g]=h.useState(!1),[p,y]=h.useState(),[b,S]=h.useState(!1),[w,v]=h.useState(!1),{collaborationServerDriver:C,getInternetAccount:E}=r,x=C.getAssemblies();return h.useEffect((()=>{i&&(async()=>{const{internetAccountConfigId:e}=n.getConf(i,["sequence","metadata"]),t=E(i.name,e);if(!t)throw new Error("No Apollo internet account found");const{baseURL:a}=t,o=new URL("features/count",a),r=new URLSearchParams({assemblyId:i.name});o.search=r.toString();const s=t.getFetcher({locationType:"UriLocation",uri:o.toString()});v(!0);const l=await s(o.toString(),{method:"GET"});if(!l.ok)throw new Error(await Ne(l));{const e=await l.json();y(e.count)}v(!1)})().catch((e=>{console.error(e),d(e.message??e)}))}),[E,o,i]),re.default.createElement(De,{open:!0,title:"Import Features from GFF3 file",handleClose:a,maxWidth:!1,"data-testid":"import-features-dialog"},w?re.default.createElement(ae.default,null):null,re.default.createElement("form",{onSubmit:async function(r){r.preventDefault(),d(""),v(!0),g(!0);let l="";if(!s)return void d("must select a file");if(!i)return void d("Must select assembly to download");const{internetAccountConfigId:c}=n.getConf(i,["sequence","metadata"]),u=E(i.name,c),{baseURL:f}=u,m=new URL("files",f);m.searchParams.set("type","text/x-gff3");const p=m.href,h=new FormData;h.append("file",s),h.append("fileName",s.name),h.append("type","text/x-gff3");const y=u.getFetcher({locationType:"UriLocation",uri:p});a();const{jobsManager:S}=o,w=new AbortController,C={name:`Importing features for ${i.displayName}`,statusMessage:"Uploading file, this may take awhile",progressPct:0,cancelCallback:()=>{w.abort(),S.abortJob(C.name)}};if(S.runJob(C),y){const{signal:e}=w,t=await y(p,{method:"POST",body:h,signal:e});if(!t.ok){const e=await Ne(t,"Error when inserting new features (while uploading file)");return S.abortJob(C.name,e),void d(e)}l=(await t.json())._id}const x=new t.AddFeaturesFromFileChange({typeName:"AddFeaturesFromFileChange",assembly:i.name,fileId:l,deleteExistingFeatures:b});S.done(C),await e.submit(x,{updateJobsManager:!0})}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:i?.name??"",onChange:function(e){const t=x.find((t=>t.name===e.target.value));c(t),g(!1)},disabled:m&&!u},x.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name))))),re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Upload GFF3 to load features"),re.default.createElement("input",{type:"file",onChange:function(e){g(!1),e.target.files&&l(e.target.files[0])},disabled:m&&!u})),p&&p>0?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,null,"This assembly already has ",p," features, would you like to delete the existing features before importing new ones?"),re.default.createElement(de.default,{label:"Yes, delete existing features",disabled:m&&!u,control:re.default.createElement(ue.default,{checked:b,onChange:function(e){S(e.target.checked)},inputProps:{"aria-label":"controlled"},color:"warning"})})):null,re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!(i&&s&&void 0!==p)||m,variant:"contained",type:"submit"},m?"Submitting...":"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Close"))),u?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},u)):null)}function gt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=h.useState(""),r=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=h.useState(r[0]);return re.default.createElement(De,{open:!0,title:"Log out",handleClose:e,maxWidth:!1,"data-testid":"log-out"},re.default.createElement("form",{onSubmit:function(e){e.preventDefault(),o(""),s.removeToken(),globalThis.location.reload()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},r.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:s.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);l(t)}},n.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Are you sure you want to log out?")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!s,variant:"contained",type:"submit"},"Log Out"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),a?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},a)):null)}function pt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=h.useState(),[r,s]=h.useState(""),[l,c]=h.useState(!1),u=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===u.length)throw new Error("No Apollo internet account found");const[d,m]=h.useState(u[0]),[g,p]=h.useState([]),[y,b]=h.useState([]),{collaborationServerDriver:S}=t.apolloDataStore,w=S.getAssemblies();function v(e,t){const n=[...y],a=e.target.value;if(t)n.includes(a)||(n.push(a),b(n));else{const e=n.indexOf(a,0);-1!==e&&n.splice(e,1),b(n)}}return h.useEffect((()=>{(async function(){const{baseURL:e,getFetcher:t}=d,n=new URL("checks/types",e).href,a=t({locationType:"UriLocation",uri:n}),o=await a(n,{method:"GET"});if(!o.ok){const e=await Ne(o,"Error when retrieving checks from server");return void s(e)}const r=await o.json();p(r)})().catch((e=>{s(String(e))}))}),[d]),h.useEffect((()=>{w.length>0&&void 0===a&&o(w[0])}),[w,a]),h.useEffect((()=>{(async function(){if(!a)return;const{baseURL:e,getFetcher:t}=d,n=new URL(`/assemblies/${a.name}`,e).href,o=t({locationType:"UriLocation",uri:n}),r=await o(n,{method:"GET"});if(!r.ok){const e=await Ne(r,"Error when retrieving assembly from server");return void s(e)}const l=await r.json();b(l.checks)})().catch((e=>{s(String(e))}))}),[a,d]),re.default.createElement(De,{open:!0,title:"Manage Checks",handleClose:e,"data-testid":"manage-checks"},re.default.createElement("form",{onSubmit:async function(n){if(n.preventDefault(),!a)return void s("Must select assembly!");const{notify:o}=t,{baseURL:r,getFetcher:l}=d,i=new URL("assemblies/checks",r).href,c=l({locationType:"UriLocation",uri:i}),u=await c(i,{method:"POST",body:JSON.stringify({_id:a.name,checks:y,name:""}),headers:{"Content-Type":"application/json"}});if(u.ok)o("Assembly checks updated successfully","success"),e();else{const e=await Ne(u,"Error when updating assembly checks");s(e)}}},re.default.createElement(f.DialogContent,null,u.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:d.internetAccountId,onChange:function(e){c(!1);const t=u.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);m(t)},disabled:l&&!r},n.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{style:{width:300},labelId:"label",value:a?.name??"",onChange:function(e){const t=w.find((t=>t.name===e.target.value));o(t)},disabled:0===w.length},w.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement("br",null),re.default.createElement("br",null),re.default.createElement(f.TableContainer,{component:f.Paper},re.default.createElement(f.Table,null,re.default.createElement(f.TableHead,null,re.default.createElement(f.TableRow,null,re.default.createElement(f.TableCell,null,"Check name"),re.default.createElement(f.TableCell,null,"Use check"))),re.default.createElement(f.TableBody,null,g.map((e=>re.default.createElement(f.TableRow,{key:e._id},re.default.createElement(f.TableCell,null,e.name),re.default.createElement(f.TableCell,null,re.default.createElement(f.Checkbox,{value:e._id,checked:y.includes(e._id),onChange:v}))))))))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit"},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),r?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},r)):null)}function ht({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),r=o.filter((e=>"ApolloInternetAccount"===e.type&&e.role?.includes("admin")));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=h.useState(""),[c,u]=h.useState(r[0]),[d,m]=h.useState([]),g=h.useCallback((async()=>{const{baseURL:e}=c,t=new URL("users",e).href,n=c.getFetcher({locationType:"UriLocation",uri:t});if(n){const e=await n(t,{method:"GET"});if(!e.ok){const t=await Ne(e,"Error when getting user data from db");return void l(t)}const a=await e.json();m(a.map((e=>void 0===e.role?{...e,role:""}:e)))}}),[c]);function p(e){return e===c.getUserId()}h.useEffect((()=>{g().catch((e=>{l(String(e))}))}),[g]);const y=[{field:"username",headerName:"User",width:140},{field:"email",headerName:"Email",width:160},{field:"role",headerName:"Role",width:140,type:"singleSelect",valueOptions:["readOnly","user","admin","none"],getOptionLabel(e){switch(e){case"readOnly":return"Read-only";case"user":return"User";case"admin":return"Admin";case"none":return"None";default:return"unknown"}},editable:!0},{field:"actions",type:"actions",getActions:n=>[re.default.createElement(F.GridActionsCellItem,{key:`delete-${n.id}`,icon:re.default.createElement(fe.default,null),onClick:async()=>{globalThis.confirm("Delete this user?")&&await async function(n){const a=new t.DeleteUserChange({typeName:"DeleteUserChange",userId:n});await e.submit(a,{internetAccountId:c.internetAccountId}),m((e=>e.filter((e=>e._id!==n))))}(n.id)},disabled:p(n.id),label:"Delete"})]}];return re.default.createElement(De,{open:!0,fullScreen:!0,title:"Manage users",handleClose:n,"data-testid":"manage-users"},re.default.createElement(f.DialogContent,null,r.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:c.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);u(t)},disabled:!s},o.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement("div",{style:{height:"100%",width:"100%"}},re.default.createElement(F.DataGrid,{pagination:!0,rows:d,columns:y,getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},getRowHeight:()=>"auto",isCellEditable:e=>!p(e.id),processRowUpdate:async function(n){const a=new t.UserChange({typeName:"UserChange",role:n.role,userId:n._id});return await e.submit(a,{internetAccountId:c.internetAccountId}),n},onProcessRowUpdateError:e=>{l(String(e))}}))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function yt({getTagProps:e,index:t,ontology:n,termId:a}){const o=i.getParent(n,2),[r,s]=se.useState(""),[l,c]=se.useState("");return se.useEffect((()=>{const e=new AbortController,{signal:t}=e;return async function(){const e=o.expandPrefixes(a),r=await(n.dataStore?.db);if(!r||t.aborted)return;const l=await r.transaction("nodes").objectStore("nodes").get(e);l&&l.lbl&&!t.aborted&&s(l.lbl||"no label")}().catch((e=>{t.aborted||c(String(e))})),()=>{e.abort()}}),[a,n,o]),se.createElement(f.Tooltip,{title:r},se.createElement("div",null,se.createElement(f.Chip,{label:l||o.applyPrefixes(a),color:l?"error":"default",size:"small",...e({index:t})})))}function bt({includeDeprecated:e,onChange:t,ontologyName:n,ontologyVersion:a,session:o,value:r}){const{ontologyManager:s}=o.apolloDataStore,l=s.findOntology(n,a),[i,c]=se.useState(r.map((e=>({term:{id:e,type:"CLASS"}})))),[u,d]=se.useState(""),[m,g]=se.useState([]),[p,h]=se.useState(!1),[y,b]=se.useState(""),S=se.useMemo((()=>M.debounce((async(t,n)=>{if(!l)return;const{dataStore:a}=l;if(!a)return;const{input:o,signal:r}=t;try{const t=await a.getTermsByFulltext(o,void 0,r),s=new Map,l=[];for(const n of t){if(!nt(n.term)||!e&&He(n.term))continue;let t=s.get(n.term.id);t||(t={term:n.term,matches:[]},s.set(n.term.id,t),l.push(t)),t.matches.push(n)}n(l)}catch(e){E.isAbortException(e)||b(String(e))}}),400)),[e,l]);if(se.useEffect((()=>{const e=new AbortController,{signal:t}=e;if(""!==u)return h(!0),S({input:u,signal:t},(e=>{let t=[];i.length>0&&(t=i),e&&(t=[...t,...e]),g(t),h(!1)})),()=>{e.abort()};g([])}),[S,l,e,u,i]),!l)return null;const w={};return y&&(w.error=!0,w.helperText=y),se.createElement(f.Autocomplete,{getOptionLabel:e=>s.applyPrefixes(e.term.id),filterOptions:e=>e.filter((e=>nt(e.term))),options:m,autoComplete:!0,includeInputInList:!0,filterSelectedOptions:!0,value:i,loading:p,isOptionEqualToValue:(e,t)=>s.applyPrefixes(e.term.id)===s.applyPrefixes(t.term.id),noOptionsText:u?"No matches":"Start typing to search",onChange:(e,n)=>{g(n?[...n,...m]:m),t(n.map((e=>s.applyPrefixes(e.term.id)))),c(n)},onInputChange:(e,t)=>{t&&h(!0),g([]),d(t)},multiple:!0,renderInput:e=>se.createElement(f.TextField,{...e,...w,variant:"outlined",fullWidth:!0}),renderOption:(e,t)=>se.createElement(wt,{...e,ontologyManager:s,option:t,inputValue:u}),renderTags:(e,t)=>e.map(((e,n)=>se.createElement(yt,{termId:e.term.id,index:n,ontology:l,getTagProps:t,key:e.term.id})))})}function St(e){const{search:t,str:n}=e,a=me.default(n,t,{insideWords:!0,findAllOccurrences:!0}),o=ge.default(n,a);return se.createElement(se.Fragment,null,o.map(((e,t)=>se.createElement(f.Typography,{key:t,component:"span",sx:{fontWeight:e.highlight?"bold":"regular"},variant:"body2",color:"text.secondary"},e.text))))}function wt(e){const{inputValue:t,ontologyManager:n,option:a,...o}=e,r=(a.matches??[]).filter((e=>"$.lbl"!==e.field.jsonPath)).map((e=>se.createElement(se.Fragment,{key:`option-${e.term.id}-${e.str}`},se.createElement(f.Typography,{component:"dt",variant:"body2",color:"text.secondary"},e.field.displayName),se.createElement("dd",null,se.createElement(St,{str:e.str,search:t})))));return se.createElement("li",{...o},se.createElement(f.Grid,{container:!0},se.createElement(f.Grid,{item:!0},se.createElement(f.Typography,{component:"span"},n.applyPrefixes(a.term.id))," ",se.createElement(St,{str:a.term.lbl??"(no label)",search:t})," ",se.createElement("dl",null,r))))}const vt=new Map([["Gene Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Sequence Ontology"})]]),Ct=w.makeStyles()((e=>({attributeInput:{maxWidth:600},newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}}))),Et=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"];function xt(e){const{onChange:t,value:n}=e;return re.default.createElement(f.TextField,{type:"text",value:n,onChange:e=>{t(e.target.value.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}function At({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,{internetAccounts:l}=i.getRoot(a),c=h.useMemo((()=>l.find((e=>"ApolloInternetAccount"===e.type))),[l]),u=["admin","user"].includes((c?c.role:"admin")??""),[d,m]=h.useState(""),[g,p]=h.useState(Object.fromEntries([...r.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})))),[y,b]=h.useState(!1),[S,w]=h.useState(""),{classes:v}=Ct(),C=Object.values(g).some((e=>0===e.length||e.includes("")));return re.default.createElement(De,{open:!0,title:"Feature attributes",handleClose:n,maxWidth:!1,"data-testid":"modify-feature-attribute"},re.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),m("");const l={};if(g)for(const[e,t]of Object.entries(g))if(t&&"parent"!==e.toLowerCase())if([...vt.keys()].includes(e))l[e]=t;else switch(e){case"ID":l._id=t;break;case"Name":l.gff_name=t;break;case"Alias":l.gff_alias=t;break;case"Target":l.gff_target=t;break;case"Gap":l.gff_gap=t;break;case"Derives_from":l.gff_derives_from=t;break;case"Note":l.gff_note=t;break;case"Dbxref":l.gff_dbxref=t;break;case"Ontology_term":l.gff_ontology_term=t;break;case"Is_circular":l.gff_is_circular=t;break;default:l[e.toLowerCase()]=t}const i=new t.FeatureAttributeChange({changedIds:[r._id],typeName:"FeatureAttributeChange",assembly:o,featureId:r._id,attributes:l});await e.submit(i),s("Feature attributes modified successfully","success"),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,null,re.default.createElement(f.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const n=vt.get(e)??xt;return re.default.createElement(f.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},re.default.createElement(f.Grid,{item:!0,xs:"auto"},re.default.createElement(f.Paper,{variant:"outlined",className:v.attributeName},re.default.createElement(f.Typography,null,e))),re.default.createElement(f.Grid,{item:!0,flexGrow:1},re.default.createElement(n,{session:a,value:t,onChange:(o=e,e=>{p({...g,[o]:e})})})),re.default.createElement(f.Grid,{item:!0,xs:1},re.default.createElement(f.IconButton,{"aria-label":"delete",size:"medium",disabled:!u,onClick:()=>{!function(e){m("");const{[e]:t,...n}=g;p(n)}(e)}},re.default.createElement(fe.default,{fontSize:"medium",key:e}))));var o})),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Button,{color:"primary",variant:"contained",disabled:y||!u,onClick:()=>{b(!0)}},"Add new")),y?re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Paper,{elevation:8,className:v.newAttributePaper},re.default.createElement(f.Grid,{container:!0,direction:"column"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.FormControl,null,re.default.createElement(f.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?w(""):vt.has(t)?w(t):m("Unknown attribute type")}},re.default.createElement(f.FormControlLabel,{value:"custom",control:re.default.createElement(f.Radio,null),disableTypography:!0,label:re.default.createElement(f.Grid,{container:!0,spacing:1,alignItems:"center"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Typography,null,"Custom")),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.TextField,{label:"Custom attribute key",variant:"outlined",value:vt.has(S)?"":S,disabled:vt.has(S),onChange:e=>{w(e.target.value)}})))}),[...vt.keys()].map((e=>re.default.createElement(f.FormControlLabel,{key:e,value:e,control:re.default.createElement(f.Radio,null),label:e})))))),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{key:"addButton",color:"primary",variant:"contained",style:{margin:2},onClick:function(){m(""),0!==S.trim().length?"Parent"!==S?S in g?m(`Attribute "${S}" already exists`):!/^[A-Z]/.test(S)||Et.includes(S)||[...vt.keys()].includes(S)?(p({...g,[S]:[]}),b(!1),w("")):m(`Key cannot starts with uppercase letter unless key is one of these: ${Et.join(", ")}`):m('"Parent" -key is handled internally and it cannot be modified manually'):m("Attribute key is mandatory")},disabled:!S},"Add"),re.default.createElement(f.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{b(!1),w(""),m("")}},"Cancel")))))):null),d?re.default.createElement(f.DialogContentText,{color:"error"},d):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:y||C||!u},"Submit changes"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",disabled:y,onClick:n},"Cancel"))))}function Tt({handleClose:e,session:t}){const{apolloDataStore:n}=t,{addAssembly:a,addSessionAssembly:o,assemblyManager:s,notify:l}=t,[i,c]=h.useState(null),[u,d]=h.useState(""),[m,g]=h.useState(""),[p,y]=h.useState(!1),b=f.useTheme();return re.default.createElement(De,{open:!0,title:"Open local GFF3 file",handleClose:e,maxWidth:!1,"data-testid":"open-local-file"},re.default.createElement("form",{onSubmit:async function(c){if(c.preventDefault(),g(""),y(!0),!i)throw new Error("No file selected");const d=await new Response(i).text(),f=`${u}-${i.name}-${q.nanoid(8)}`;try{await Te(f,d,n)}catch(t){return console.error(t),l(`Error loading GFF3 ${i.name}, ${String(t)}`,"error"),void e()}const m={name:f,aliases:[u],displayName:u,sequence:{trackId:`sequenceConfigId-${u}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:f},metadata:{apollo:!0,...r.isElectron?{file:i.path}:{}}}};await(o||a)(m);const p=await s.waitForAssembly(m.name);p?(t.addApolloTrackConfig(p),l(`Loaded GFF3 ${i.name}`,"success")):l(`Error loading GFF3 ${i.name}`,"error"),e()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.FormControl,null,re.default.createElement("div",{style:{flexDirection:"row"}},re.default.createElement(f.Button,{variant:"contained",component:"label",style:{marginRight:b.spacing()}},"Choose File",re.default.createElement("input",{type:"file",required:!0,hidden:!0,onChange:function(e){const t=e.target.files?.item(0);if(t&&(g(""),c(t),!u)){const e=t.name,n=e.lastIndexOf(".");d(-1===n?e:e.slice(0,n))}}})),i?i.name:"No file chosen"),re.default.createElement(f.FormHelperText,null,"Make sure your GFF3 has an embedded FASTA section")),re.default.createElement(f.TextField,{required:!0,label:"Assembly name",value:u,onChange:function(e){d(e.target.value)}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!1,variant:"contained",type:"submit"},p?"Submitting...":"Submit"),re.default.createElement(f.Button,{disabled:p,variant:"outlined",type:"submit",onClick:e},"Cancel"))),m?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},m)):null)}const kt=w.makeStyles()((e=>({changeTextarea:{fontFamily:"monospace",width:600,resize:"none",border:`1px solid ${e.palette.divider}`,borderRadius:e.shape.borderRadius}})));function Nt({handleClose:t,session:n}){const{internetAccounts:a}=i.getRoot(n),o=a.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,{classes:s}=kt(),[l,c]=h.useState(),[u,d]=h.useState([]),[m,g]=h.useState(""),[p,y]=h.useState([]),b=[{field:"sequence"},{field:"typeName",headerName:"Change type",width:200,type:"singleSelect",valueOptions:[...e.changeRegistry.changes.keys()]},{field:"changes",headerName:"Change JSON",width:600,renderCell:({value:e})=>re.default.createElement("textarea",{className:s.changeTextarea,value:JSON.stringify(e),readOnly:!0}),valueFormatter:({value:e})=>JSON.stringify(e)},{field:"user",headerName:"User",width:140},{field:"createdAt",headerName:"Time",width:160,type:"dateTime",valueGetter:e=>e&&new Date(e)}];return h.useEffect((()=>{(async function(){const e=new URL("assemblies",r).href,t=o?.getFetcher({locationType:"UriLocation",uri:e});if(t){const n=await t(e,{method:"GET"});if(!n.ok){const e=await Ne(n,"Error when retrieving assemblies from server");return void c(e)}const a=await n.json();d(a)}})().catch((e=>{c(String(e))}))}),[o,r]),h.useEffect((()=>{!m&&u.length>0&&g(u[0]._id)}),[m,u]),h.useEffect((()=>{(async function(){if(!m)return;const e=new URL("changes",r),t=new URLSearchParams({assembly:m});e.search=t.toString();const n=e.toString(),a=o?.getFetcher({locationType:"UriLocation",uri:n});if(a){const e=await a(n,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ne(e,"Error when retrieving changes");return void c(t)}const t=await e.json();y(t)}})().catch((e=>{c(String(e))}))}),[m,o,r]),re.default.createElement(De,{open:!0,fullScreen:!0,title:"View change log",handleClose:t,"data-testid":"view-changelog"},re.default.createElement(f.Select,{style:{width:200,marginLeft:40},value:m,onChange:function(e){g(e.target.value)}},u.map((e=>re.default.createElement(f.MenuItem,{key:e._id,value:e._id},e.name)))),re.default.createElement(f.DialogContent,null,re.default.createElement(F.DataGrid,{pagination:!0,rows:p,columns:b,getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},initialState:{sorting:{sortModel:[{field:"sequence",sort:"desc"}]},columns:{columnVisibilityModel:{sequence:!1}}}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:t},"Close")),l?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},l)):null)}const Rt=[{field:"refName",headerName:"Ref Name"},{field:"aliases",headerName:"Aliases",editable:!0}],Dt=e=>/^[\da-f]{24}$/i.test(e);function Ft({changeManager:e,handleClose:n,session:a}){const o=h.useRef(null),[r,s]=h.useState(""),[l,i]=h.useState(!1),[c,u]=h.useState(),[d,m]=h.useState([]),[g,p]=h.useState(new Map),{apolloDataStore:y}=a,{collaborationServerDriver:b}=y,S=b.getAssemblies();h.useEffect((()=>{let e=0;const t=()=>{if(!c)return;const n=new Map;if(e<2&&!c.refNames&&(e++,setTimeout(t,50)),!c.refNames)return;const a=c.refNameAliases;for(const e in a){const t=a[e];if(t&&!Dt(e))if(n.has(t)){const a=n.get(t)??[];n.set(t,[...a,e])}else n.set(t,[e])}p(n)};t()}),[c]);const w=()=>[...g].map(((e,t)=>({id:t,refName:e[0],aliases:e[1].filter((t=>t!==e[0])).join(", ")})));return re.default.createElement(De,{open:!0,title:"Add reference sequence aliases",handleClose:n,maxWidth:"sm","data-testid":"add-refseq-alias",fullWidth:!0},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.Grid,{container:!0,spacing:2},re.default.createElement(f.Grid,{item:!0,xs:4},re.default.createElement(f.FormControl,{disabled:l&&!r,fullWidth:!0},re.default.createElement(f.InputLabel,{id:"demo-simple-select-label"},"Assembly"),re.default.createElement(f.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Assembly",value:c?.name??"",onChange:e=>{const t=S.find((t=>t.name===e.target.value));u(t),i(!1),s(""),o.current&&(o.current.value="")}},S.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))))),re.default.createElement(f.Grid,{item:!0,xs:1}),re.default.createElement(f.Grid,{item:!0,xs:7},re.default.createElement(f.InputLabel,null,"Load RefName alias"),re.default.createElement("input",{type:"file",onChange:e=>{(async e=>{if(!e.target.files)return;const t=e.target.files[0],n=(await t.text()).split("\n"),a=new Map(g);s("");for(const e of n){const t=e.split("\t");for(const e of t)a.has(e)&&a.set(e,[...a.get(e)??[],...t])}p(a)})(e).catch((()=>{s("Error reading file")}))},ref:o,disabled:l&&!r||!c}))),c&&g.size>0?re.default.createElement("div",{style:{height:200,width:"100%",marginTop:20}},re.default.createElement(f.InputLabel,null,"Refname aliases found for selected assembly."),re.default.createElement(F.DataGrid,{rows:w(),columns:Rt,initialState:{pagination:{paginationModel:{page:0,pageSize:5}}},pageSizeOptions:[5,10],onRowSelectionModelChange:e=>{(e=>{if(e.length>0){i(!0);const t=e.flatMap((e=>w().filter((t=>t.id===e))));m(t)}else i(!1),m([])})(e)},processRowUpdate:(e,t)=>{const n=new Map(g);return n.set(e.refName,e.aliases.split(",")),p(n),e},checkboxSelection:!0})):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:!l,onClick:()=>{const a=[];for(const e of d){const{refName:t}=e,n=e.aliases.split(",").map((e=>e.trim())).filter((e=>e.length>0));a.push({refName:t,aliases:n})}if(s(""),!c)return void s("No assembly selected");const o=new t.AddRefSeqAliasesChange({typeName:"AddRefSeqAliasesChange",assembly:c.name,refSeqAliases:a});e.submit(o).catch((()=>{s("Error submitting change")})),n()}},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),r?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},r)):null)}function Mt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),{collaborationServerDriver:a}=t.apolloDataStore,o=n.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,[s,l]=h.useState(),[c,u]=h.useState(),[d,m]=h.useState([]),g=a.getAssemblies();return h.useEffect((()=>{!c&&g.length>0&&u(g[0])}),[g,c]),h.useEffect((()=>{(async function(){const e=c?.name;if(!e)return;const t=new URL("checks",r),n=new URLSearchParams({assembly:e});t.search=n.toString();const a=t.toString(),s=o?.getFetcher({locationType:"UriLocation",uri:a});if(s){const e=await s(a,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ne(e,"Error when retrieving checks");return void l(t)}const t=await e.json();m(t)}})().catch((e=>{l(String(e))}))}),[c,o,r]),re.default.createElement(De,{open:!0,fullScreen:!0,title:"View check results",handleClose:e,"data-testid":"view-check-results"},re.default.createElement(f.Select,{style:{width:200,marginLeft:40},value:c?.name??"",onChange:function(e){const t=g.find((t=>t.name===e.target.value));u(t)},disabled:0===g.length},g.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContent,null,re.default.createElement(F.DataGrid,{pagination:!0,rows:d,columns:[{field:"_id",headerName:"id",width:50},{field:"name",headerName:"Check name",width:200},{field:"refSeq",headerName:"Reference sequence ID",width:200},{field:"ids",headerName:"Feature IDs",width:200},{field:"message",headerName:"Message",flex:1}],getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},initialState:{sorting:{sortModel:[{field:"name",sort:"asc"}]},columns:{columnVisibilityModel:{name:!0}}}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Close")),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function It(e){const{color:t}=e;return re.default.createElement(f.SvgIcon,{viewBox:"0 0 18 18",style:{fontSize:18,marginRight:4},...e},"disabled"===t?re.default.createElement("path",{d:"M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z"}):re.default.createElement(re.default.Fragment,null,re.default.createElement("path",{d:"M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z",fill:"#4285F4"}),re.default.createElement("path",{d:"M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z",fill:"#34A853"}),re.default.createElement("path",{d:"M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z",fill:"#FBBC05"}),re.default.createElement("path",{d:"M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z",fill:"#EA4335"})))}function Lt(e){const{color:t}=e;return re.default.createElement(f.SvgIcon,{viewBox:"0 0 21 21",style:{fontSize:21},...e},re.default.createElement("rect",{x:"1",y:"1",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#F25022"}),re.default.createElement("rect",{x:"1",y:"11",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#00A4EF"}),re.default.createElement("rect",{x:"11",y:"1",width:"9",height:"9",fill:"disabled"===t?"#939393":"#7FBA00"}),re.default.createElement("rect",{x:"11",y:"11",width:"9",height:"9",fill:"disabled"===t?"#B9B9B9":"#FFB900"}))}const qt=w.makeStyles()((e=>({loginButton:{marginBottom:e.spacing(1),width:"220px",height:"40px",fontSize:"16px",textTransform:"none",justifyContent:"left",padding:"3px 12px"}})));function Pt(e){const{classes:t}=qt(),{disabled:n}=e;return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(It,{color:n?"disabled":void 0}),...e},"Sign in with Google")}function Ut(e){const{classes:t}=qt(),{disabled:n}=e;return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(Lt,{color:n?"disabled":void 0}),...e},"Sign in with Microsoft")}function Bt(e){const{classes:t}=qt();return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(pe.default,{fontSize:"small"}),...e},"Continue as Guest")}const _t=w.makeStyles()((e=>({divider:{marginTop:e.spacing(4),marginBottom:e.spacing(5)}}))),jt=({baseURL:e,handleClose:t,name:n})=>{const{classes:a}=_t(),[o,r]=h.useState(""),[s,l]=h.useState([]);function i(e){t("google"===e?"google":"microsoft"===e?"microsoft":"guest")}h.useEffect((()=>{const t=new AbortController,{signal:n}=t;return async function(){const t=new URL("auth/types",e).href,a=await fetch(t,{method:"GET",signal:n});if(!a.ok){const e=await Ne(a,"Error when retrieving auth types from server");return void r(e)}const o=await a.json();l(o)}().catch((e=>{E.isAbortException(e)||r(String(e))})),()=>{t.abort()}}),[e]);const c=s.includes("google"),u=s.includes("microsoft"),d=s.includes("guest");return re.default.createElement(De,{open:!0,title:`Log in to ${n}`,handleClose:t,maxWidth:!1,"data-testid":"login-apollo"},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column",paddingTop:8}},c?re.default.createElement(Pt,{disabled:!c,onClick:()=>{i("google")}}):null,u?re.default.createElement(Ut,{disabled:!u,onClick:()=>{i("microsoft")}}):null,d?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Divider,{className:a.divider}),re.default.createElement(Bt,{onClick:()=>{i("guest")}})):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:()=>{t()}},"Cancel")),o?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},o)):null)},Ot="undefined"==typeof sessionStorage,$t=o=>a.InternetAccount.named("ApolloInternetAccount").props({type:i.types.literal("ApolloInternetAccount"),configuration:n.ConfigurationReference(o)}).views((e=>({get baseURL(){return n.getConf(e,"baseURL")},getUserId(){const n=e.retrieveToken();if(n)return t.getDecodedToken(n).id}}))).volatile((()=>({role:void 0}))).actions((e=>{let n=!1;return{setRole(){const a=e.retrieveToken();if(!a)return void(e.role=void 0);const o=t.getDecodedToken(a),{role:r}=o;if(!r&&!n){const{session:t}=i.getRoot(e);t.notify("You have registered as a user but have not been given access. Ask your administrator to enable access for your account.","warning"),n=!0}e.role!==r&&(e.role=r)}}})).actions((e=>{let t;return{addMessageChannel(e,n){t=t=>{this.finishOAuthWindow(t,e,n)},window.addEventListener("message",t)},deleteMessageChannel(){window.removeEventListener("message",t)},finishOAuthWindow(t,n,a){if(t.data.name!==`JBrowseAuthWindow-${e.internetAccountId}`)return void this.deleteMessageChannel();const o=t.data.redirectUri.replace("#","?"),r=new URL(o),s=new URLSearchParams(r.search).get("access_token");this.deleteMessageChannel(),s?(e.storeToken(s),e.setRole(),n(s)):a(new Error("Error with token endpoint"))},async openAuthWindow(t,n,a){const o=r.isElectron?"http://localhost/auth":globalThis.location.origin+globalThis.location.pathname,s=new URL("auth/login",e.baseURL),l=new URLSearchParams({type:t,redirect_uri:o});s.search=l.toString();const i=`JBrowseAuthWindow-${e.internetAccountId}`;if(r.isElectron){const{ipcRenderer:t}=globalThis.require("electron"),r=await t.invoke("openAuthWindow",{internetAccountId:e.internetAccountId,data:{redirect_uri:o},url:s.toString()}),l=new MessageEvent("message",{data:{name:i,redirectUri:r}});this.finishOAuthWindow(l,n,a)}else this.addMessageChannel(n,a),window.open(s,i,"width=500,height=600")}}})).actions((e=>({async getTokenFromUser(t,n){const{baseURL:a}=e,o=await new Promise(((t,n)=>{const{session:a}=i.getRoot(e),{baseURL:o,name:r}=e;a.queueDialog((e=>[jt,{name:r,handleClose:a=>{a?a instanceof Error?n(a):t(a):n(new Error("user cancelled entry")),e()},baseURL:o}]))}));if("guest"!==o)return void e.openAuthWindow(o,t,n);const r=new URL("auth/login",a),s=new URLSearchParams({type:o});r.search=s.toString();const l=r.toString(),c=await fetch(l);if(!c.ok){const e=await Ne(c,"Error when logging in");return void n(new Error(e))}const{token:u}=await c.json();t(u)}}))).volatile((()=>({lastChangeSequenceNumber:void 0}))).actions((e=>({setLastChangeSequenceNumber(t){e.lastChangeSequenceNumber=t}}))).actions((t=>({updateLastChangeSequenceNumber:i.flow((function*(){const{baseURL:e}=t,n=new URL("changes",e),a=new URLSearchParams({limit:"1"});n.search=a.toString();const o=n.toString(),r=t.getFetcher({locationType:"UriLocation",uri:o}),s=yield r(o,{method:"GET"});if(!s.ok){const e=yield Ne(s,"Error when fetching server LastChangeSequence");throw new Error(e)}const l=yield s.json();t.setLastChangeSequenceNumber(l.length>0?l[0].sequence:0)})),getMissingChanges:i.flow((function*(){const{session:n}=i.getRoot(t),{changeManager:a}=n.apolloDataStore;if(!t.lastChangeSequenceNumber)throw new Error("No LastChangeSequence stored in session. Please, refresh you browser to get last updates from server");const{baseURL:o,lastChangeSequenceNumber:r}=t,s=new URL("changes",o),l=new URLSearchParams({since:String(r),sort:"1"});s.search=l.toString();const c=s.toString(),u=t.getFetcher({locationType:"UriLocation",uri:c}),d=yield u(c,{method:"GET"});if(!d.ok)return void console.error(`Error when fetching the last updates to recover socket connection — ${d.status}`);const f=yield d.json();for(const t of f){const n=e.Change.fromJSON(t);a.submit(n,{submitToBackend:!1})}}))}))).volatile((e=>{const{origin:t,pathname:n}=new URL("socket.io/",e.baseURL);return{socket:c.io(t,{path:n})}})).actions((n=>({addSocketListeners(){const{session:a}=i.getRoot(n),{notify:o}=a,r=n.retrieveToken();if(!r)throw new Error("No Token found");const{socket:s}=n,{addCheckResult:l,changeManager:c,deleteCheckResult:u}=a.apolloDataStore;s.on("connect",(async()=>{await n.getMissingChanges()})),s.on("connect_error",(e=>{console.error(e),o("Could not connect to the Apollo server.","error")})),s.on("COMMON",(t=>{if("checkResult"in t)return void(t.deleted?u(t.checkResult._id.toString()):l(t.checkResult));if(sessionStorage.setItem("LastChangeSequence",String(t.changeSequence)),t.userSessionId===r)return;const n=e.Change.fromJSON(t.changeInfo);c.submit(n,{submitToBackend:!1})})),s.on("USER_LOCATION",(e=>{const{channel:n,locations:o,userName:s,userSessionId:l}=e,i=t.getDecodedToken(r),c=t.makeUserSessionId(i);"USER_LOCATION"===n&&l!==c&&a.addOrUpdateCollaborator({name:s,id:l,locations:o})})),s.on("REQUEST_INFORMATION",(e=>{const{channel:t,userSessionId:n}=e;"REQUEST_INFORMATION"===t&&n!==r&&a.broadcastLocations()}))}}))).actions((e=>({postUserLocation:(t=>{let n;return t=>{clearTimeout(n),n=setTimeout((()=>{!async function(t){const{baseURL:n}=e,a=new URL("users/userLocation",n).href,o=new URLSearchParams(JSON.stringify(t)),r=e.getFetcher({locationType:"UriLocation",uri:a});try{if(!(await r(a,{method:"POST",body:o})).ok)throw new Error("ignore")}catch{console.error("Broadcasting user location failed")}}(t)}),300)}})()}))).actions((e=>({initialize:i.flow((function*(t){if("admin"===t){const t=i.getRoot(e);r.isAbstractMenuManager(t)&&function(e){e.appendToMenu("Apollo",{label:"Add Assembly",onClick:e=>{e.queueDialog((t=>[Me,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Delete Assembly",onClick:e=>{e.queueDialog((t=>[ut,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Import Features",onClick:e=>{e.queueDialog((t=>[mt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Add reference sequence aliases",onClick:e=>{e.queueDialog((t=>[Ft,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Manage Users",onClick:e=>{e.queueDialog((t=>[ht,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Undo",onClick:e=>{const{apolloDataStore:t}=e,{notify:n}=e;t.changeManager.recentChanges.length>0?t.changeManager.revertLastChange():n("No changes to undo","info")}})}(t)}yield e.updateLastChangeSequenceNumber(),e.addSocketListeners();const{baseURL:n}=e,a=new URL("users/locations",n).href,o=e.getFetcher({locationType:"UriLocation",uri:a});yield o(a,{method:"GET"}),window.addEventListener("beforeunload",(()=>{e.postUserLocation([])})),document.addEventListener("visibilitychange",(()=>{if("hidden"===document.visibilityState&&e.postUserLocation([]),"visible"===document.visibilityState){const{session:t}=i.getRoot(e);t.broadcastLocations()}}))}))}))).actions((e=>({afterAttach(){e.setRole(),l.autorun((async t=>{if(Ot)return;const{session:n}=i.getRoot(e);n&&e.role&&(await e.initialize(e.role),t.dispose())}),{name:"ApolloInternetAccount"})}})));function Gt(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo}const Wt="undefined"==typeof sessionStorage;class Ht extends B.BaseSequenceAdapter{regions;async getRefNames(e){return(await this.getRegions(e)).map((e=>e.refName))}async getRegions(e){if(this.regions)return this.regions;const t=n.readConfObject(this.config,"assemblyId");if(!Wt){const e=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!e)throw new Error("No Apollo data store found");const n=e.getBackendDriver(t),a=await n.getRegions(t);return this.regions=a,a}const a=await new Promise(((n,a)=>{const o=setTimeout((()=>{a("timeout")}),2e4),r=q.nanoid(),s=e=>{const{data:t}=e;Gt(t)&&t.messageId===r&&(clearTimeout(o),removeEventListener("message",s),n(t.regions))};addEventListener("message",s,e),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getRegions",assembly:t,messageId:r})}));return this.regions=a,a}getFeatures(e,t){const{end:a,refName:o,start:r}=e,s=n.readConfObject(this.config,"assemblyId"),l={...e,assemblyName:s};return _.ObservableCreate((async e=>{if(!Wt){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)return void e.error("No Apollo data store found");const n=t.getBackendDriver(s),{seq:i}=await n.getSequence(l);return e.next(new ye.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:i}})),void e.complete()}const n=await new Promise(((e,n)=>{const a=setTimeout((()=>{n("timeout")}),2e4),o=q.nanoid(),r=t=>{const{data:n}=t;Gt(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),e(n.sequence))};addEventListener("message",r,t),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getSequence",region:l,messageId:o})}));e.next(new ye.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:n}})),e.complete()}))}freeResources(){}}var zt=n.ConfigurationSchema("ApolloSequenceAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});function Vt(e,t,n,a,o,r){const s=a/o;e.fillStyle="black",e.fillRect(t,n,s,r),s>2&&(e.clearRect(t+1,n+1,s-2,r-2),e.fillStyle="rgba(255,255,255,0.75)",e.fillRect(t+1,n+1,s-2,r-2))}var Jt=S.observer((function(e){const[a,o]=h.useState(),[s,c]=h.useState(),u=h.useRef(null),d=h.useRef(null),m=h.useRef(null),[g,p]=h.useState(!1),[y,b]=h.useState(!0),[S,w]=h.useState(),[v,C]=h.useState(!1),[E,x]=h.useState([]),{bpPerPx:A,displayModel:T,regions:k}=e,{session:N}=T,{collaborators:R}=N;h.useEffect((()=>l.autorun((()=>{x(l.toJS(R))}))),[]);const[D]=k,F=(D.end-D.start)/A,{apolloFeatureUnderMouse:M,apolloRowHeight:I,apolloRowUnderMouse:L,changeManager:q,codonLayout:P,featureLayout:U,features:B,featuresHeight:_,getAssemblyId:j,selectedFeature:O,setApolloFeatureUnderMouse:$,setApolloRowUnderMouse:G,setSelectedFeature:W,showIntronLines:H,showStartCodons:z,showStopCodons:V}=T,J=[...B.values()].map((e=>[...e.values()].map((e=>i.getSnapshot(e))))),X=h.useMemo((()=>{const{internetAccounts:e}=i.getRoot(N),{assemblyName:t}=D,{assemblyManager:a}=r.getSession(T),o=a.get(t);if(!o)throw new Error(`No assembly found with name ${t}`);const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]),l=e.find((e=>n.getConf(e,"internetAccountId")===s));if(!l)throw new Error(`No InternetAccount found with config id ${s}`);return l}),[T,D,N]),{role:Y}=X;return h.useEffect((()=>{Y?.includes("admin")&&p(!0),(Y?.includes("admin")??Y?.includes("user"))&&b(!1)}),[Y]),h.useEffect((()=>{const e=u.current;if(!e)return;const t=e.getContext("2d");if(!t)return;const n={};t.clearRect(0,0,F,_);for(const[e,a]of U)for(const[o,r]of a){const a=D.reversed?D.end-r.max:r.min-D.start-1,s=r.max-D.start-1,l=a/A,i=s/A;Vt(t,l,e*I,s-a,A,I);const c=e*I+I/2;n[o]||(n[o]=[]),n[o].some((e=>e[0]===l&&e[1]===c))||n[o].push([l,c]),n[o].some((e=>e[0]===i&&e[1]===c))||n[o].push([i,c])}if(H){let e=-Math.floor(Object.keys(n).length/2);for(const a in n){t.strokeStyle=`hsl(${e*(180*(3-Math.sqrt(5)))+60},100%,50%)`;const o=n[a].sort(((e,t)=>e[0]-t[0]));let[r]=o;for(const[n,a]of o.entries())if(0!==n){if(n%2==0){const n=[(a[0]-r[0])/2+r[0],Math.max(1,Math.min(r[1],a[1])-I/2+2*e)];t.beginPath(),t.moveTo(r[0],r[1]+2*e),t.lineTo(...n),t.stroke(),t.moveTo(...n),t.lineTo(a[0],a[1]+2*e),t.stroke()}r=a}e+=1}}}),[H,D,A,D.start,D.end,D.reversed,F,U,_,B,I,J]),h.useEffect((()=>{const e=m.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,F,_);for(const[e,{starts:n,stops:a}]of P){const o=A;for(const a of n){const n=a/o;D.start/o<=n&&n<=D.end/o&&(t.fillStyle="rgba(255,0,255,1)",z?t.fillRect(Math.round(n-.5-D.start/o),e*I,1,I):t.clearRect(Math.round(n-.5-D.start/o),e*I,1,I))}for(const n of a){const a=n/o;D.start/o<=a&&a<=D.end/o&&(t.fillStyle="black",V?t.fillRect(Math.round(a-.5-D.start/o),e*I,1,I):t.clearRect(Math.round(a-.5-D.start/o),e*I,1,I))}}}}),[z,V,P,F,_,A,I,D,D.start,D.end]),h.useEffect((()=>{const e=d.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,F,_);for(const e of E){const{locations:n}=e;if(0===n.length)return;for(const a of n){const{end:n,start:o}=a,r=(D.reversed?D.end-o:o-D.start)/A,s=(n-o)/A;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(r,1,s,100),t.fillStyle="black",t.fillText(e.name,r+1,11,s-2)}}}}),[M,L,A,_,F,D,D.start,D.end,D.reversed,S,I,E]),re.default.createElement("div",{style:{position:"relative",width:F,height:_}},re.default.createElement(f.Menu,{open:Boolean(s),anchorReference:"anchorPosition",anchorPosition:a?{left:a[0],top:a[1]}:void 0,"data-testid":"base_linear_display_context_menu",onClose:()=>{c(void 0)}},re.default.createElement(f.MenuItem,{disabled:y,key:1,value:1,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[st,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e,internetAccount:X}]))}},"Add child feature"),re.default.createElement(f.MenuItem,{disabled:y,key:2,value:2,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[ct,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e}]))}},"Copy features and annotations"),re.default.createElement(f.MenuItem,{disabled:!g,key:3,value:3,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[dt,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e,selectedFeature:O,setSelectedFeature:W}]))}},"Delete feature")),re.default.createElement("canvas",{ref:u,width:F,height:_,style:{position:"absolute",left:0,top:0}}),re.default.createElement("canvas",{ref:d,width:F,height:_,onMouseLeave:function(){$(),G()},onMouseUp:async function(){if(v){if(S){const e=j(D.assemblyName),{bp:n,edge:a,feature:o}=S;let r;if("end"===a){const a=o._id,s=o.max,l=Math.round(n);r=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[a],featureId:a,oldEnd:s,newEnd:l,assembly:e})}else{const a=o._id,s=o.min,l=Math.round(n);r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[a],featureId:a,oldStart:s,newStart:l,assembly:e})}await q.submit(r)}}else M&&W(M);w(void 0),C(!1)},onContextMenu:function(e){e.preventDefault(),c(M),o([e.pageX,e.pageY])},style:{position:"absolute",left:0,top:0}}),re.default.createElement("canvas",{ref:m,width:F,height:6*I,style:{position:"absolute",left:0,top:0}}))})),Xt=n.ConfigurationSchema("ApolloSixFrameRenderer",{},{explicitlyTyped:!0});class Yt extends a.RendererType{async renderInClient(e,t){return this.render(t)}async freeResourcesInClient(e,t){return 0}}class Kt extends B.BaseAdapter{get baseURL(){return n.readConfObject(this.config,"baseURL").uri}get trackId(){return n.readConfObject(this.config,"trackId")}get assemblyNames(){return n.readConfObject(this.config,"assemblyNames")}mapBaseResult(e,t,n){return e.map((e=>{const a=t.getCanonicalRefName(e.refSeq);return new be.default({label:n,trackId:this.trackId,locString:`${a}:${e.min+1}..${e.max}`})}))}async searchIndex(e){const t=e.queryString,n=[],a=this.pluginManager?.rootModel?.session;if(!a)return n;const{apolloDataStore:o}=a,{assemblyManager:r}=a;for(const a of this.assemblyNames){const s=o.getBackendDriver(a),l=r.get(a);if(!s||!l)continue;const i=await s.searchFeatures(e.queryString,[a]);n.push(...this.mapBaseResult(i,l,t))}return n}freeResources(){}}var Zt=n.ConfigurationSchema("ApolloTextSearchAdapter",{assemblyNames:{type:"stringArray",defaultValue:[],description:"List of assemblies covered by text search adapter"},trackId:{type:"string",defaultValue:""},baseURL:{type:"fileLocation",defaultValue:{uri:"",locationType:"UriLocation"}}},{explicitlyTyped:!0,explicitIdentifier:"textSearchAdapterId"});const Qt=n.ConfigurationSchema("ApolloPlugin",{ontologies:i.types.array(tt),featureTypeOntologyName:{description:"Name of the feature type ontology",type:"string",defaultValue:"Sequence Ontology"}});function en(e){if("LinearPileupDisplay"!==e.name)return e;const{stateModel:n}=e,a=n.views((e=>({getFirstRegion:()=>r.getContainingView(e).dynamicBlocks.contentBlocks[0],getAssembly(){const t=e.getFirstRegion(),n=r.getSession(e),{assemblyManager:a}=n,{assemblyName:o}=t,s=a.get(o);if(!s)throw new Error(`Could not find assembly named ${o}`);return s},getRefSeqId(t){const n=e.getFirstRegion(),{refName:a}=n,{refNameAliases:o}=t;if(!o)throw new Error(`Could not find aliases for ${t.name}`);const r=[...Object.entries(o)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""}))),s=r.find((e=>e.name===a))?._id;if(!s)throw new Error(`Could not find refSeqId named ${a}`);return s},createFeature(){const t=e.contextMenuFeature,n=e.getAssembly(),a=e.getRefSeqId(n),o=(t.get("CIGAR").toUpperCase().match(/\d+\D/g)??[]).map((e=>[(/\D/.exec(e)??[])[0],Number.parseInt(e,10)]));let r=0;const s=t.get("start");let l;const i=[];for(const[e,t]of o)"M"===e||"="===e?void 0===l&&(l=r+s):"N"===e&&void 0!==l&&(i.push({start:l,end:r+l}),l=void 0),"I"!==e&&(r+=t);void 0!==l&&i.push({start:l,end:r+s});const c={_id:oe.default().toHexString(),refSeq:a,min:t.get("start"),max:t.get("end"),type:"mRNA",strand:t.get("strand")};if(0===i.length)return c;c.children={};const[u]=i,d={_id:oe.default().toHexString(),refSeq:a,min:u.start,max:u.end,type:"CDS",strand:t.get("strand")};if(c.children[d._id]=d,1===i.length){const e={_id:oe.default().toHexString(),refSeq:a,min:u.start,max:u.end,type:"exon",strand:t.get("strand")};return c.children[e._id]=e,c}for(const e of i){d.min=Math.min(d.min,e.start),d.max=Math.max(d.max,e.end);const{end:n,start:o}=e,r={_id:oe.default().toHexString(),refSeq:a,min:o,max:n,type:"exon",strand:t.get("strand")};c.children[r._id]=r}return c},async onPileupFeatureContext(){const n=e.createFeature(),a=e.getAssembly(),o=new t.AddFeatureChange({changedIds:[n._id],typeName:"AddFeatureChange",assembly:a.name,addedFeature:n}),s=r.getSession(e);await s.apolloDataStore.changeManager.submit(o),s.notify("Annotation added successfully","success")}}))).views((e=>{const t=e.contextMenuItems;return{contextMenuItems:()=>e.contextMenuFeature?[...t(),{label:"Create Apollo annotation",icon:Q.default,onClick:e.onPileupFeatureContext}]:t()}}));return e.stateModel=a,e}const tn=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=h.useState(String(t)),[r,s]=h.useState(!1),[l,i]=h.useState(null);return h.useEffect((()=>{o(String(t))}),[t]),h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),re.default.createElement(f.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{a!==String(t)&&e(a)},inputRef:e=>{i(e)}})})),nn=new Map([["Gene Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Sequence Ontology"})]]),an=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"],on=w.makeStyles()((e=>({newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}})));function rn(e){const{onChange:t,value:n}=e;return re.default.createElement(tn,{value:n,onChangeCommitted:e=>{t(e.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}const sn=S.observer((function({assembly:e,editable:n,feature:a,session:o}){const[r,s]=h.useState(""),[l,c]=h.useState(!1),{classes:u}=on(),[d,m]=h.useState(""),g=Object.fromEntries([...a.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]}))),{notify:p}=o,{changeManager:y}=o.apolloDataStore;async function b(n,o){s("");const r={};if(g){const e=Object.entries({...g,[n]:o});for(const[t,n]of e)if(n&&"parent"!==t.toLowerCase())if([...nn.keys()].includes(t))r[t]=n;else switch(t){case"ID":r._id=n;break;case"Name":r.gff_name=n;break;case"Alias":r.gff_alias=n;break;case"Target":r.gff_target=n;break;case"Gap":r.gff_gap=n;break;case"Derives_from":r.gff_derives_from=n;break;case"Note":r.gff_note=n;break;case"Dbxref":r.gff_dbxref=n;break;case"Ontology_term":r.gff_ontology_term=n;break;case"Is_circular":r.gff_is_circular=n;break;default:r[t.toLowerCase()]=n}}const l=new t.FeatureAttributeChange({changedIds:[a._id],typeName:"FeatureAttributeChange",assembly:e,featureId:a._id,attributes:r});await y.submit(l),p("Feature attributes modified successfully","success")}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Attributes"),re.default.createElement(f.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{if(""===e)return null;const a=nn.get(e)??rn;return re.default.createElement(f.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},re.default.createElement(f.Grid,{item:!0,xs:"auto"},re.default.createElement(f.Paper,{variant:"outlined",className:u.attributeName},re.default.createElement(f.Typography,null,e))),re.default.createElement(f.Grid,{item:!0,flexGrow:1},re.default.createElement(a,{session:o,value:t,onChange:t=>b(e,t)})),re.default.createElement(f.Grid,{item:!0,xs:1},re.default.createElement(f.IconButton,{"aria-label":"delete",size:"medium",disabled:!n,onClick:()=>b(e)},re.default.createElement(fe.default,{fontSize:"medium",key:e}))))})),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Button,{color:"primary",variant:"contained",disabled:l||!n,onClick:()=>{c(!0)}},"Add new")),l?re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Paper,{elevation:8,className:u.newAttributePaper},re.default.createElement(f.Grid,{container:!0,direction:"column"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.FormControl,null,re.default.createElement(f.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?m(""):nn.has(t)?m(t):s("Unknown attribute type")}},re.default.createElement(f.FormControlLabel,{value:"custom",control:re.default.createElement(f.Radio,null),disableTypography:!0,label:re.default.createElement(f.Grid,{container:!0,spacing:1,alignItems:"center"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Typography,null,"Custom")),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.TextField,{label:"Custom attribute key",variant:"outlined",value:nn.has(d)?"":d,disabled:nn.has(d),onChange:e=>{m(e.target.value)}})))}),[...nn.keys()].map((e=>re.default.createElement(f.FormControlLabel,{key:e,value:e,control:re.default.createElement(f.Radio,null),label:e})))))),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{key:"addButton",color:"primary",variant:"contained",onClick:function(){s(""),0!==d.trim().length?"Parent"!==d?d in g?s(`Attribute "${d}" already exists`):!/^[A-Z]/.test(d)||an.includes(d)||[...nn.keys()].includes(d)?b(d,[]):s(`Key cannot starts with uppercase letter unless key is one of these: ${an.join(", ")}`):s('"Parent" -key is handled internally and it cannot be modified manually'):s("Attribute key is mandatory")},disabled:!d},"Add"),re.default.createElement(f.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{c(!1),m(""),s("")}},"Cancel")))))):null),r?re.default.createElement(f.Typography,{color:"error"},r):null)})),ln=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=h.useState(String(t)),[r,s]=h.useState(!1),[l,i]=h.useState(null);h.useEffect((()=>{o(String(t))}),[t]),h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]);const c=Number.isNaN(Number(a));return re.default.createElement(f.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{const n=Number(a);a!==String(t)&&(Number.isNaN(n)?o(String(t)):e(n))},inputRef:e=>{i(e)},error:c,helperText:c?"Not a valid number":void 0})})),cn=S.observer((function({assembly:e,feature:n,session:a}){const[o,r]=h.useState(""),[s,l]=h.useState(""),{_id:i,assemblyId:c,max:u,min:d,strand:m,type:g}=n,p=e=>{a.notify(e.message,"error")},{changeManager:y}=a.apolloDataStore;function b(n){const{value:a}=n.target,o=a?Number(a):void 0,r=new t.StrandChange({typeName:"StrandChange",changedIds:[i],featureId:i,oldStrand:m,newStrand:o,assembly:e});return y.submit(r)}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Basic information"),re.default.createElement(ln,{margin:"dense",id:"start",label:"Start",fullWidth:!0,variant:"outlined",value:d+1,onChangeCommitted:function(n){n--;const a=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[i],featureId:i,oldStart:d,newStart:n,assembly:e});return y.submit(a)}}),re.default.createElement(ln,{margin:"dense",id:"end",label:"End",fullWidth:!0,variant:"outlined",value:u,onChangeCommitted:function(n){const a=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[i],featureId:i,oldEnd:u,newEnd:n,assembly:e});return y.submit(a)}}),re.default.createElement(rt,{session:a,ontologyName:"Sequence Ontology",value:g,filterTerms:nt,fetchValidTerms:async function(e,t,n){const a=await ot(e,t);if(a)return a;l(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,n),renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(s),helperText:s}),onChange:(e,n)=>{n&&function(e){r("");const n=new t.TypeChange({typeName:"TypeChange",changedIds:[i],featureId:i,oldType:g,newType:e,assembly:c});return y.submit(n)}(n).catch(p)}}),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"1",checked:1===m,onChange:b}),"Positive Strand (+)"),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"-1",checked:-1===m,onChange:b}),"Negative Strand (-)"),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"",checked:void 0===m,onChange:b}),"No Strand Information"),o?re.default.createElement(f.Typography,{color:"error"},o):null)})),un=w.makeStyles()({sequence:{width:"100%",resize:"vertical"}}),dn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const o=a.apolloDataStore.assemblies.get(e),[r,s]=h.useState(!1),{classes:l}=un();if(!t||!o)return null;const i=o.getByRefName(n);if(!i)return null;const{max:c,min:u}=t;let d="";return r&&(d=i.getSequence(u,c),d?d=function(e,t,n,a,o){return`>${t}:${n+1}–${a}\n${e}`}(d,n,u,c):a.apolloDataStore.loadRefSeq([{assemblyName:e,refName:n,start:u,end:c}])),re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Sequence"),re.default.createElement(f.Button,{variant:"contained",onClick:()=>{s(!r)}},r?"Hide sequence":"Show sequence"),re.default.createElement("div",null,r&&re.default.createElement("textarea",{readOnly:!0,rows:20,className:l.sequence,value:d})))})),fn=w.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),mn=S.observer((function(e){const{model:t}=e,{assembly:n,feature:a,refName:o}=t,s=r.getSession(t),l=s.apolloDataStore.assemblies.get(n),{classes:i}=fn();if(!a||!l)return null;const c=l.getByRefName(o);if(!c)return null;const{max:u,min:d}=a;return c.getSequence(d,u)||s.apolloDataStore.loadRefSeq([{assemblyName:n,refName:o,start:d,end:u}]),re.default.createElement("div",{className:i.root},re.default.createElement(cn,{feature:a,session:s,assembly:l._id}),re.default.createElement("hr",null),re.default.createElement(sn,{feature:a,session:s,assembly:l._id,editable:!0}),re.default.createElement("hr",null),re.default.createElement(dn,{feature:a,session:s,assembly:l._id,refName:o}))})),gn=i.types.model("ApolloFeatureDetailsWidget",{id:v.ElementId,type:i.types.literal("ApolloFeatureDetailsWidget"),feature:i.types.maybe(i.types.reference($.AnnotationFeatureModel,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}}))),pn=i.types.model("ApolloTranscriptDetails",{id:v.ElementId,type:i.types.literal("ApolloTranscriptDetails"),feature:i.types.maybe(i.types.reference($.AnnotationFeatureModel,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string,changeManager:i.types.frozen()}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}}))),hn=S.observer((function({assembly:e,feature:n,refName:a,session:o}){const{notify:s}=o,l=o.apolloDataStore.assemblies.get(e),i=l?.getByRefName(a),{changeManager:c}=o.apolloDataStore,u=f.useTheme();function d(n,a,o,r){if(!o.children)throw new Error("Transcript should have child features");for(const[,l]of o.children){if(r&&n-1===l.min){const r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[l._id],featureId:o._id,oldStart:n-1,newStart:a-1,assembly:e});return void c.submit(r).catch((()=>{s("Error updating feature start position","error")}))}if(!r&&a===l.max){const n=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[l._id],featureId:o._id,oldEnd:l.max,newEnd:a,assembly:e});return void c.submit(n).catch((()=>{s("Error updating feature start position","error")}))}}}if(!i)return null;const{strand:m,transcriptParts:g}=n,[p]=g,h=p.map(((e,t)=>{const{max:n,min:a,type:o}=e;let s,l,c,d=o;if("threePrimeUTR"===d?d="3` UTR":"fivePrimeUTR"===d&&(d="5` UTR"),"CDS"===o){const{phase:o}=e,d=r.getFrame(a,n,m??1,o);c=u.palette.framesCDS.at(d)?.main;const f=p.at(t-1),g=p.at(t+1);1===m?("intron"===f?.type&&(s=i.getSequence(a-2,a)),"intron"===g?.type&&(l=i.getSequence(n,n+2))):("intron"===f?.type&&(s=r.revcom(i.getSequence(n,n+2))),"intron"===g?.type&&(l=r.revcom(i.getSequence(a-2,a))))}return{min:a,max:n,label:d,fivePrimeSpliceSite:s,threePrimeSpliceSite:l,frameColor:c}})).filter((e=>"intron"!==e.label));return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Structure"),re.default.createElement(f.Typography,{variant:"h6"},1===m?"Forward":"Reverse"," strand"),re.default.createElement(f.TableContainer,{component:f.Paper},re.default.createElement(f.Table,{size:"small"},re.default.createElement(f.TableBody,null,h.map((e=>re.default.createElement(f.TableRow,{key:`${e.label}:${e.min}-${e.max}`},re.default.createElement(f.TableCell,{component:"th",scope:"row",style:{background:e.frameColor}},e.label),re.default.createElement(f.TableCell,null,e.fivePrimeSpliceSite??""),re.default.createElement(f.TableCell,{padding:"none"},re.default.createElement(ln,{margin:"dense",variant:"outlined",value:1===m?e.min+1:e.max,onChangeCommitted:t=>{d(1===m?e.min+1:e.max,t,n,1===m)}})),re.default.createElement(f.TableCell,{padding:"none"},re.default.createElement(ln,{margin:"dense",variant:"outlined",value:1===m?e.max:e.min+1,onChangeCommitted:t=>{d(1===m?e.max:e.min+1,t,n,1!==m)}})),re.default.createElement(f.TableCell,null,e.threePrimeSpliceSite??""))))))))})),yn=60;function bn(e){switch(e){case"upOrDownstream":return"rgb(255,255,255)";case"UTR":return"rgb(194,106,119)";case"CDS":return"rgb(93,168,153)";case"intron":return"rgb(187,187,187)";case"protein":return"rgb(148,203,236)"}}const Sn=S.observer((function({assembly:e,feature:n,refName:a,session:o}){const s=o.apolloDataStore.assemblies.get(e),l=s?.getByRefName(a),[i,c]=h.useState(!1),[u,d]=h.useState("CDS"),m=f.useTheme(),g=h.useRef(null);if(!s||!l)return null;const p=s.getByRefName(a);if(!p)return null;if("mRNA"!==n.type)return null;const y=i?function(e,n,a){const o=[],{cdsLocations:s,strand:l,transcriptParts:i}=n;switch(e){case"genomic":case"cDNA":{const[n]=i;for(const s of n){if("cDNA"===e&&"intron"===s.type)continue;let n=a(s.min,s.max);-1===l&&(n=r.revcom(n));const i="fivePrimeUTR"===s.type||"threePrimeUTR"===s.type?"UTR":s.type,c=o.at(-1);if(c)if(c.type===i){const[e,...a]=c.sequenceLines,o=a.join("")+n;c.sequenceLines=[e,...t.splitStringIntoChunks(o,yn)],c.locs.push({min:s.min,max:s.max})}else{const e=o.reduce(((e,t)=>e+t.sequenceLines.reduce(((e,t)=>e+t.length),0)),0),a=yn-e%yn,r=n.slice(0,a),l=t.splitStringIntoChunks(n.slice(a),yn);o.push({type:i,sequenceLines:[r,...l],locs:[{min:s.min,max:s.max}]})}else{const e=t.splitStringIntoChunks(n,yn);o.push({type:i,sequenceLines:e,locs:[{min:s.min,max:s.max}]})}}return o}case"CDS":{let e="";const[n]=s,i=[];for(const t of n){let n=a(t.min,t.max);-1===l&&(n=r.revcom(n)),e+=n,i.push({min:t.min,max:t.max})}const c=t.splitStringIntoChunks(e,yn);return o.push({type:"CDS",sequenceLines:c,locs:i}),o}}}(u,n,((e,t)=>l.getSequence(e,t))):[],b=[];if(i){const e=y.flatMap((e=>e.locs));let[t]=e;for(let n=1;n<e.length;n++)t.min===e[n].max||t.max===e[n].min?t={min:Math.min(t.min,e[n].min),max:Math.max(t.max,e[n].max)}:(b.push(t),t=e[n]);b.push(t)}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Sequence"),re.default.createElement("div",null,re.default.createElement(f.Button,{variant:"contained",onClick:()=>{c(!i)}},i?"Hide sequence":"Show sequence")),i&&re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Select,{defaultValue:"CDS",value:u,onChange:function(e){d(e.target.value)}},re.default.createElement(f.MenuItem,{value:"CDS"},"CDS"),re.default.createElement(f.MenuItem,{value:"cDNA"},"cDNA"),re.default.createElement(f.MenuItem,{value:"genomic"},"Genomic")),re.default.createElement(f.Paper,{style:{fontFamily:"monospace",padding:m.spacing(),overflowX:"auto"},ref:g},">",p.name,":",b.map((e=>1===n.strand?`${e.min+1}-${e.max}`:`${e.max}-${e.min+1}`)).join(";"),"(",1===n.strand?"+":"-",")",re.default.createElement("br",null),y.map(((e,t)=>re.default.createElement("span",{key:`${e.type}-${t}`,style:{background:bn(e.type),color:m.palette.getContrastText(bn(e.type))}},e.sequenceLines.map(((t,n)=>re.default.createElement(re.default.Fragment,{key:`${t.slice(0,5)}-${n}`},t,n===e.sequenceLines.length-1&&t.length!==yn?null:re.default.createElement("br",null)))))))),re.default.createElement(f.Button,{variant:"contained",onClick:()=>{const e=g.current;if(!e)return;const t=new Blob([e.outerText],{type:"text/plain"}),n=new Blob([e.outerHTML],{type:"text/html"}),a=new ClipboardItem({[t.type]:t,[n.type]:n});navigator.clipboard.write([a])}},"Copy sequence")))})),wn=w.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),vn=S.observer((function(e){const{classes:t}=wn(),{model:n}=e,{assembly:a,feature:o,refName:s}=n,l=r.getSession(n),c=r.getSession(n),u=c.apolloDataStore.assemblies.get(a),{internetAccounts:d}=i.getRoot(l),f=d.find((e=>"ApolloInternetAccount"===e.type)),m=["admin","user"].includes((f?f.role:"admin")??"");if(!o||!u)return null;const g=u.getByRefName(s);if(!g)return null;const{max:p,min:h}=o;return g.getSequence(h,p)||c.apolloDataStore.loadRefSeq([{assemblyName:a,refName:s,start:h,end:p}]),re.default.createElement("div",{className:t.root},re.default.createElement(hn,{feature:o,session:c,assembly:u._id||"",refName:s}),re.default.createElement("hr",null),re.default.createElement(sn,{feature:o,session:c,assembly:u._id||"",editable:m}),re.default.createElement("hr",null),re.default.createElement(Sn,{feature:o,session:c,assembly:u._id||"",refName:s}))})),Cn=n.ConfigurationSchema("LinearApolloDisplay",{},{explicitIdentifier:"displayId",explicitlyTyped:!0}),En=w.makeStyles()({highlighted:{background:"orange"}}),xn=({highlight:e,text:t})=>{const{classes:n}=En();if(!e)return re.default.createElement(re.default.Fragment,null,t);const a=t.split(e);if(1===a.length)return re.default.createElement(re.default.Fragment,null,t);const o=[];for(let t=0;t<a.length-1;t++)o.push(a[t],re.default.createElement("span",{className:n.highlighted},e));return re.default.createElement(re.default.Fragment,null,o,a.at(-1))},An=S.observer((function({feature:e,filterText:t}){const n=[...e.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})).filter((([e])=>e)).map((([e,t])=>`${e}=${Array.isArray(t)?t.join(", "):t}`)).join(", ");return re.default.createElement(xn,{text:n,highlight:t})})),Tn=w.makeStyles()((e=>({inputWrapper:{position:"relative"},hiddenWidthSpan:{padding:e.spacing(.5),color:"transparent"},numberTextInput:{border:"none",background:"inherit",font:"inherit",position:"absolute",width:"100%",left:0}}))),kn=S.observer((function({initialValue:e,notifyError:t,onChangeCommitted:n}){const[a,o]=h.useState(e),[r,s]=h.useState(!1),[l,i]=h.useState(null),{classes:c}=Tn();return h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),re.default.createElement("span",{className:c.inputWrapper},re.default.createElement("span",{className:c.hiddenWidthSpan,"aria-hidden":!0},a),re.default.createElement("input",{type:"text",value:a,className:c.numberTextInput,onChange:function(e){const t=Number(e.target.value);Number.isNaN(t)||o(t)},onKeyDown:t=>{"Enter"===t.key?l?.blur():"Escape"===t.key&&(o(e),s(!0))},onBlur:()=>{a!==e&&n(a).catch(t)},ref:e=>{i(e)}}))}));function Nn(e,t){return t?.palette.bases[e.toUpperCase()].main.toString()??"lightgray"}function Rn(e,t,n,a,o){const r=Math.min(n,10);e.fillStyle="#000",e.font=`${r}px`;const s=e.measureText(a).width;e.fillText(a,t+(n-s)/2,o+10)}function Dn(e,t,n,a,o,s,l,i,c){let u=l.slice(i,i+3).toUpperCase();c&&(u=function(e){return[...e].map((e=>r.revcom(e))).reverse().join("")}(u));const d=r.defaultCodonTable[u];if(!d)return;const f={M:"#33ee33","*":"#f44336"}[d.toUpperCase()];f&&(e.fillStyle=f,e.fillRect(n,a,o,s)),t<=.1&&(e.rect(n,a,o,s),e.stroke(),Rn(e,n,o,d,a))}function Fn(e){return"featureAndGlyphUnderMouse"in e}function Mn(e,t){const n=t<=1?2:0;switch(e){case 3:return 0;case 2:return 1;case 1:return 2;case-1:return 3+n;case-2:return 4+n;case-3:return 5+n}}function In(e,t){if(!(t>1||void 0===e))return 1===e?3:4}function Ln(e,t,n,a,o,r){void 0!==o&&(e.fillStyle=t?.palette.action.focus??"rgba(0,0,0,0.04)",e.fillRect(n,a*o,r,a))}function qn(e,t){return Boolean(t&&e._id===t._id)}function Pn(e,t){return t?e?.palette.text.primary??"black":e?.palette.background.default??"white"}function Un(e,t,n,a,o,r){e.fillStyle=r,e.fillRect(t,n,a,o)}function Bn(e,t,n){const{refName:a,regionNumber:o,x:r}=e,{lgv:s}=n,{offsetPx:l}=s,i=s.bpToPx({refName:a,coord:t.min,regionNumber:o}),c=s.bpToPx({refName:a,coord:t.max,regionNumber:o});if(void 0!==i&&void 0!==c){const e=i.offsetPx-l,t=c.offsetPx-l;if(Math.abs(t-e)<8)return;if(Math.abs(e-r)<4)return"min";if(Math.abs(t-r)<4)return"max"}}const _n={draw:function(e,t,n,a,o){const{apolloRowHeight:r,lgv:s,session:l,theme:i}=a,{bpPerPx:c,displayedRegions:u,offsetPx:d}=s,f=u[o],m=(s.bpToPx({refName:f.refName,coord:t.min,regionNumber:o})?.offsetPx??0)-d,{reversed:g}=f,{apolloSelectedFeature:p}=l,h=t.length/c,y=g?m-h:m,b=n*r,S=qn(t,p),w=Pn(i,S),v=function(e,t){return t?e?.palette.getContrastText(Pn(e,t))??"white":e?.palette.text.primary??"black"}(i,S);!function(e,t,n,a,o,r){Un(e,t,n,a,o,r),a<=2||e.clearRect(t+1,n+1,a-2,o-2)}(e,y,b,h,r,v),h<=2||(function(e,t,n,a,o,r){Un(e,t+1,n+1,a-2,o-2,r)}(e,y,b,h,r,w),function(e,t,n,a,o,r){e.fillStyle=o;const s=Math.max(t+1,0);e.fillText(r,s,n+11,t-1+a-s)}(e,y,b,h,v,t.type))},drawDragPreview:function(e,t){const{apolloDragging:n,apolloRowHeight:a,lgv:o,theme:r}=e,{bpPerPx:s,displayedRegions:l,offsetPx:i}=o;if(!n)return;const{current:c,edge:u,feature:d,start:m}=n,g=Math.floor(m.y/a),p=l[m.regionNumber],h=(p.reversed?p.end-d[u]:d[u]-p.start)/s-i,y=Math.min(c.x,h),b=g*a,S=Math.abs(c.x-h),w=1*a;t.strokeStyle=r?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(y,b,S,w),t.fillStyle=f.alpha(r?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(y,b,S,w)},drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{bpPerPx:i,displayedRegions:c,offsetPx:u}=o,{layoutIndex:d,layoutRow:f}=l,m=c[d],{refName:g,reversed:p}=m,{length:h,max:y,min:b}=s,S=(o.bpToPx({refName:g,coord:p?y:b,regionNumber:d})?.offsetPx??0)-u,w=f*a,v=h/i;t.fillStyle=r?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(S,w,v,a)},drawTooltip:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{featureRow:i,layoutIndex:c,layoutRow:u}=l,{bpPerPx:d,displayedRegions:m,offsetPx:g}=o,p=m[c],{refName:h,reversed:y}=p;let b="Loc: ";const{length:S,max:w,min:v}=s;b+=`${v+1}–${w}`;let C=(o.bpToPx({refName:h,coord:y?w:v,regionNumber:c})?.offsetPx??0)-g;const E=(u+i)*a,x=S/d,A=`Type: ${s.type}`,{attributes:T}=s,k=T.get("gff_name")?.find((e=>""!==e)),N=[t.measureText(A).width,t.measureText(b).width];k&&N.push(t.measureText(`Name: ${k}`).width);const R=Math.max(...N);C=C+x+5,t.fillStyle=f.alpha(r?.palette.text.primary??"rgb(1, 1, 1)",.7),t.fillRect(C,E,R+4,3===N.length?45:35),t.beginPath(),t.moveTo(C,E),t.lineTo(C-5,E+5),t.lineTo(C,E+10),t.fill(),t.fillStyle=r?.palette.background.default??"rgba(255, 255, 255)";let D=E+12;t.fillText(A,C+2,D),k&&(D+=12,t.fillText(`Name: ${k}`,C+2,D)),D+=12,t.fillText(b,C+2,D)},getContextMenuItems:function(e){const{apolloHover:t,apolloInternetAccount:n,changeManager:a,regions:o,selectedFeature:s,session:l}=e,i=[];if(!t)return i;const{feature:c}=t,u=n?n.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),[m]=o,g=e.getAssemblyId(m.assemblyName),p=e.getAssemblyId(m.assemblyName);return i.push({label:"Add child feature",disabled:f,onClick:()=>{l.queueDialog((e=>[st,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:g,internetAccount:n}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{l.queueDialog((e=>[ct,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:p}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{l.queueDialog((t=>[dt,{session:l,handleClose:()=>{t()},changeManager:a,sourceFeature:c,sourceAssemblyId:p,selectedFeature:s,setSelectedFeature:t=>{e.setSelectedFeature(t)}}]))}},{label:"Modify feature attribute",disabled:f,onClick:()=>{l.queueDialog((e=>[At,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:p}]))}},{label:"Edit feature details",onClick:()=>{const e=l.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:c,assembly:p,refName:m.refName});l.showWidget(e)}}),"mRNA"===c.type&&r.isSessionModelWithWidgets(l)&&i.push({label:"Edit transcript details",onClick:()=>{const e=l.addWidget("ApolloTranscriptDetails","apolloTranscriptDetails",{feature:c,assembly:p,changeManager:a,refName:m.refName});l.showWidget(e)}}),i},getFeatureFromLayout:function(e,t,n){return e},getRowCount:function(e){return 1},getRowForFeature:function(e,t){return 0},onMouseDown:function(e,t,n){const{featureAndGlyphUnderMouse:a}=t,{feature:o}=a,r=Bn(t,o,e);r&&(n.stopPropagation(),e.startDrag(t,o,r))},onMouseLeave:function(){},onMouseMove:function(e,t){if(Fn(t)){const{featureAndGlyphUnderMouse:n}=t;e.setApolloHover(n);const{feature:a}=n;if(Bn(t,a,e))return void e.setCursor("col-resize")}e.setCursor()},onMouseUp:function(e,t){if(e.apolloDragging)return;const{featureAndGlyphUnderMouse:n}=t;n?.feature&&e.setSelectedFeature(n.feature)}};let jn=null,On=null,$n=null,Gn=null;if("document"in globalThis)for(const e of["forward","backward"])for(const t of["light","dark"]){const n=document.createElement("canvas"),a=10;n.width=n.height=a;const o=n.getContext("2d");if(o){const r="light"===t?"rgba(0,0,0,0)":"rgba(0,0,0,0.75)",s="light"===t?"rgba(255,255,255,0.25)":"rgba(0,0,0,0.50)",l="forward"===e?o.createLinearGradient(0,a,a,0):o.createLinearGradient(0,0,a,a);l.addColorStop(0,r),l.addColorStop(.25,r),l.addColorStop(.25,s),l.addColorStop(.5,s),l.addColorStop(.5,r),l.addColorStop(.75,r),l.addColorStop(.75,s),l.addColorStop(1,s),o.fillStyle=l,o.fillRect(0,0,10,10),"forward"===e?"light"===t?jn=o.createPattern(n,"repeat"):$n=o.createPattern(n,"repeat"):"light"===t?On=o.createPattern(n,"repeat"):Gn=o.createPattern(n,"repeat")}}function Wn(e,t){const{children:n,type:a}=e;if(!n)return 1;let o=0;if("mRNA"===a){for(const[,e]of n)"CDS"===e.type&&(o+=1);return o}for(const[,e]of n)o+=Wn(e);return o}function Hn(e){if("gene"!==e.type)throw new Error('Top level feature for GeneGlyph must have type "gene"');const{children:t}=e;if(!t)return[[e]];const n=[];for(const[,a]of t){if("mRNA"!==a.type){n.push([a,e]);continue}if(!a.children)continue;const t=[],o=[];for(const[,e]of a.children)"CDS"===e.type?t.push(e):"exon"===e.type&&o.push(e);for(const r of t)n.push([r,...o,a,e])}return n}function zn(e,t,n){if("gene"===t.type||"mRNA"===t.type)return;const{bp:a,refName:o,regionNumber:s,x:l}=e,{lgv:i}=n,{offsetPx:c}=i,u=i.bpToPx({refName:o,coord:t.min,regionNumber:s}),d=i.bpToPx({refName:o,coord:t.max,regionNumber:s});if(void 0===u||void 0===d)return;const f=u.offsetPx-c,m=d.offsetPx-c;if(!(Math.abs(m-f)<8)){if(Math.abs(f-l)<4)return{feature:t,edge:"min"};if(Math.abs(m-l)<4)return{feature:t,edge:"max"};if("CDS"===t.type){const e=t.parent;if(!e?.children)return;const n=[...e.children.values()].filter((e=>"exon"===e.type)).find((e=>{const[t,n]=r.intersection2(a,a+1,e.min,e.max);return void 0!==t&&void 0!==n}));if(!n)return;const u=i.bpToPx({refName:o,coord:n.min,regionNumber:s}),d=i.bpToPx({refName:o,coord:n.max,regionNumber:s});if(void 0===u||void 0===d)return;const f=u.offsetPx-c,m=d.offsetPx-c;if(Math.abs(m-f)<8)return;if(Math.abs(f-l)<4)return{feature:n,edge:"min"};if(Math.abs(m-l)<4)return{feature:n,edge:"max"}}}}const{drawTooltip:Vn,getContextMenuItems:Jn,onMouseLeave:Xn}=_n,Yn={draw:function(e,t,n,a,o){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=a,{bpPerPx:u,displayedRegions:d,offsetPx:m}=l,g=d[o],{refName:p,reversed:h}=g,y=s,b=Math.round(.6*y),S=Math.round(.9*y),{children:w,min:v,strand:C}=t;if(!w)return;const{apolloSelectedFeature:E}=i,x=(l.bpToPx({refName:p,coord:v,regionNumber:o})?.offsetPx??0)-m,A=t.length/u,T=h?x-A:x,k=n*y,N=Wn(t)*y;e.fillStyle=f.alpha(c?.palette.background.paper??"#ffffff",.6),e.fillRect(T,k,A,N);let R=0;for(const[,t]of w){if("mRNA"!==t.type){R+=1;continue}const{children:a,min:r}=t;if(a)for(const[,s]of a){if("CDS"!==s.type)continue;const a=(l.bpToPx({refName:p,coord:r,regionNumber:o})?.offsetPx??0)-m,i=t.length/u,d=h?a-i:a,f=Math.round((R+.5)*y)+n*y;e.strokeStyle=c?.palette.text.primary??"black",e.beginPath(),e.moveTo(d,f),e.lineTo(d+i,f),e.stroke(),R+=1}}const D="dark"===c?.palette.mode?$n:jn,F="dark"===c?.palette.mode?Gn:On;R=0;for(const[,t]of w)if("mRNA"===t.type)for(const a of t.cdsLocations){const{_id:s,children:i}=t;if(i){for(const[,t]of i){if("exon"!==t.type)continue;const a=(l.bpToPx({refName:p,coord:t.min,regionNumber:o})?.offsetPx??0)-m,r=t.length/u,s=h?a-r:a,i=(n+R)*y+(y-b)/2;if(e.fillStyle=c?.palette.text.primary??"black",e.fillRect(s,i,r,b),r>2&&(e.clearRect(s+1,i+1,r-2,b-2),e.fillStyle=E&&t._id===E._id?"rgb(0,0,0)":"rgb(211,211,211)",e.fillRect(s+1,i+1,r-2,b-2),D&&F&&C)){const t=h?-1:1,[n,a]=C*t==1?[D,F]:[F,D];e.fillStyle=n,e.fillRect(s+1,i+1,r-2,(b-2)/2),e.fillStyle=a,e.fillRect(s+1,i+1+(b-2)/2,r-2,(b-2)/2)}}for(const i of a){const a=(i.max-i.min)/u,d=(l.bpToPx({refName:p,coord:i.min,regionNumber:o})?.offsetPx??0)-m,f=h?d-a:d;e.fillStyle=c?.palette.text.primary??"black";const g=(n+R)*y+(y-S)/2;if(e.fillRect(f,g,a,S),a>2){e.clearRect(f+1,g+1,a-2,S-2);const n=r.getFrame(i.min,i.max,t.strand??1,i.phase),o=c?.palette.framesCDS.at(n)?.main,l=o??"rgb(171,71,188)";if(e.fillStyle=E&&s===E._id?"rgb(0,0,0)":l,e.fillStyle=l,e.fillRect(f+1,g+1,a-2,S-2),D&&F&&C){const t=h?-1:1,[n,o]=C*t==1?[D,F]:[F,D];e.fillStyle=n,e.fillRect(f+1,g+1,a-2,(S-2)/2),e.fillStyle=o,e.fillRect(f+1,g+(S-2)/2,a-2,(S-2)/2)}}}R+=1}}else _n.draw(e,t,n,a,o),R+=1},drawDragPreview:function(e,t){const{apolloDragging:n,apolloRowHeight:a,lgv:o,theme:r}=e,{bpPerPx:s,displayedRegions:l,offsetPx:i}=o;if(!n)return;const{current:c,edge:u,feature:d,start:m}=n,g=Math.floor(m.y/a),p=l[m.regionNumber],h=(p.reversed?p.end-d[u]:d[u]-p.start)/s-i,y=Math.min(c.x,h),b=g*a,S=Math.abs(c.x-h),w=1*a;t.strokeStyle=r?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(y,b,S,w),t.fillStyle=f.alpha(r?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(y,b,S,w)},drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{bpPerPx:i,displayedRegions:c,offsetPx:u}=o,{featureRow:d,layoutIndex:f,layoutRow:m}=l,g=c[f],{refName:p,reversed:h}=g,{length:y,max:b,min:S}=s,w=(o.bpToPx({refName:p,coord:h?b:S,regionNumber:f})?.offsetPx??0)-u,v=(m+d)*a,C=y/i;t.fillStyle=r?.palette.action.selected??"rgba(0,0,0,04)",t.fillRect(w,v,C,a*Wn(s))},drawTooltip:Vn,getContextMenuItems:Jn,getFeatureFromLayout:function(e,t,n){const a=Hn(e)[n]||[];for(const e of a){let n;if(t>=e.min&&t<=e.max&&e.parent&&(n=e),n){if("CDS"===n.type&&n.parent&&"mRNA"===n.parent.type){const{cdsLocations:e}=n.parent;for(const a of e)for(const e of a)if(t>=e.min&&t<=e.max)return n;return n.parent}return n}}return e},getRowCount:Wn,getRowForFeature:function(e,t){const n=Hn(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e},onMouseDown:function(e,t,n){const{featureAndGlyphUnderMouse:a}=t,{feature:o}=a,r=zn(t,o,e);r&&(n.stopPropagation(),e.startDrag(t,r.feature,r.edge))},onMouseLeave:Xn,onMouseMove:function(e,t){if(Fn(t)){const{featureAndGlyphUnderMouse:n}=t;e.setApolloHover(n);const{feature:a}=n;if(zn(t,a,e))return void e.setCursor("col-resize")}e.setCursor()},onMouseUp:function(e,t){if(e.apolloDragging)return;const{featureAndGlyphUnderMouse:n}=t;n?.feature&&e.setSelectedFeature(n.feature)}};function Kn(e){const t=[[e]];if(e.children)for(const[,n]of e.children)t.push(...Kn(n));return t}function Zn(e){return Kn(e).length}function Qn(e,t,n,a,o,r){const s=Kn(t)[n-a];for(const t of s)ea(e,t,n,o,r)}function ea(e,t,n,a,o){const{apolloRowHeight:r,lgv:s,session:l}=a,{bpPerPx:i,displayedRegions:c,offsetPx:u}=s,d=c[o],f=(s.bpToPx({refName:d.refName,coord:t.min,regionNumber:o})?.offsetPx??0)-u,{reversed:m}=d,{apolloSelectedFeature:g}=l,p=t.length/i,h=m?f-p:f,y=n*r,b=Zn(t),S=qn(t,g);b>1&&Un(e,h,y,p,b*r,S?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)"),_n.draw(e,t,n,a,o)}const{drawDragPreview:ta,drawTooltip:na,getContextMenuItems:aa,onMouseDown:oa,onMouseLeave:ra,onMouseMove:sa,onMouseUp:la}=_n,ia={draw:function(e,t,n,a,o){for(let r=0;r<Zn(t);r++)Qn(e,t,n+r,n,a,o)},drawDragPreview:ta,drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o}=e;if(!n)return;const{feature:r}=n,s=e.getFeatureLayoutPosition(r);if(!s)return;const{featureRow:l,layoutIndex:i,layoutRow:c}=s,{bpPerPx:u,displayedRegions:d,offsetPx:f}=o,m=d[i],{refName:g,reversed:p}=m,{length:h,max:y,min:b}=r,S=(o.bpToPx({refName:g,coord:p?y:b,regionNumber:i})?.offsetPx??0)-f,w=(c+l)*a,v=h/u;t.fillStyle="rgba(0,0,0,0.2)",t.fillRect(S,w,v,a*Zn(r))},drawTooltip:na,getContextMenuItems:aa,getFeatureFromLayout:function(e,t,n){return Kn(e)[n].find((e=>t>=e.min&&t<=e.max))},getRowCount:Zn,getRowForFeature:function(e,t){const n=Kn(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e},onMouseDown:oa,onMouseLeave:ra,onMouseMove:sa,onMouseUp:la};function ca(e){return function(e){const{children:t}=e;if(!t?.size)return!1;for(const[,e]of t)if("mRNA"===e.type){const{children:t}=e;if(!t?.size)return!1;const n=[...t.values()].some((e=>"CDS"===e.type)),a=[...t.values()].some((e=>"exon"===e.type));if(n&&a)return!0}return!1}(e)?Yn:e.children?.size?ia:_n}const ua=w.makeStyles()((e=>({typeContent:{display:"inline-block",width:"174px",height:"100%",cursor:"text"},feature:{td:{position:"relative",verticalAlign:"top",paddingLeft:"0.5em"}},arrow:{display:"inline-block",width:"1.6em",textAlign:"center",cursor:"pointer"},arrowExpanded:{transform:"rotate(90deg)"},hoveredFeature:{backgroundColor:e.palette.action.hover},typeInputElement:{border:"none",background:"none"},typeErrorMessage:{color:"red"}})));function da(e,t){const{changeManager:n,getAssemblyId:a,regions:o,selectedFeature:s,session:l,setSelectedFeature:c}=e;return function(e,t,n,a,o,s,l){const c=function(e){const{internetAccounts:t}=i.getParent(e);return t.find((e=>"ApolloInternetAccount"===e.type))}(s),u=c?c.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),m=[];if(e){const i=n(t.assemblyName),u=n(t.assemblyName);m.push({label:"Edit feature details",onClick:()=>{const n=s.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:e,assembly:u,refName:t.refName});s.showWidget(n)}},{label:"Add child feature",disabled:f,onClick:()=>{s.queueDialog((t=>[st,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:i,internetAccount:c}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{s.queueDialog((t=>[ct,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{s.queueDialog((t=>[dt,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u,selectedFeature:a,setSelectedFeature:o}]))}},{label:"Edit attributes",disabled:f,onClick:()=>{s.queueDialog((t=>[At,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u}]))}}),"mRNA"===e.type&&r.isSessionModelWithWidgets(s)&&m.push({label:"Edit transcript details",onClick:()=>{const n=s.addWidget("ApolloTranscriptDetails","apolloTranscriptDetails",{feature:e,assembly:u,changeManager:l,refName:t.refName});s.showWidget(n)}})}return m}(t,o[0],a,s,c,l,n)}function fa(e){let t=e;for(;t.parent;)t=t.parent;return t}const ma=S.observer((function e({depth:n,feature:a,isHovered:o,isSelected:r,model:s,selectedFeatureClass:l,setContextMenu:i}){const{classes:c}=ua(),{apolloHover:u,changeManager:d,selectedFeature:f,session:m,tabularEditor:g}=s,{featureCollapsed:p,filterText:h}=g,{_id:y,children:b,max:S,min:w,strand:v,type:C}=a,E=!p.get(y),x=e=>{m.notify(e.message,"error")};return re.default.createElement(re.default.Fragment,null,re.default.createElement("tr",{onMouseEnter:e=>{s.setApolloHover({feature:a,topLevelFeature:fa(a),glyph:ca(fa(a))})},className:c.feature+(r?` ${l}`:o?` ${c.hoveredFeature}`:""),onClick:e=>{e.stopPropagation(),s.setSelectedFeature(a)},onContextMenu:e=>(e.preventDefault(),i({position:{left:e.clientX+2,top:e.clientY-6},items:da(s,a)}),!1)},re.default.createElement("td",{style:{whiteSpace:"nowrap",borderLeft:2*n+"em solid transparent"}},b?.size?re.default.createElement("div",{onClick:e=>{e.stopPropagation(),g.setFeatureCollapsed(y,E)},className:c.arrow+(E?` ${c.arrowExpanded}`:"")},"❯"):null,re.default.createElement("div",{className:c.typeContent},re.default.createElement(rt,{session:m,ontologyName:"Sequence Ontology",style:{width:170},value:C,filterTerms:nt,fetchValidTerms:ga.bind(null,a),renderInput:e=>re.default.createElement("div",{ref:e.InputProps.ref},re.default.createElement("input",{type:"text",...e.inputProps,className:c.typeInputElement,style:{width:170}}),e.error?re.default.createElement("div",{className:c.typeErrorMessage},e.errorMessage??"unknown error"):null),onChange:(e,n)=>{n&&function(e,n,a,o){const r=n._id,s=new t.TypeChange({typeName:"TypeChange",changedIds:[r],featureId:r,oldType:String(a),newType:String(o),assembly:n.assemblyId});return e.submit(s)}(d,a,e,n).catch(x)}}))),re.default.createElement("td",null,re.default.createElement(kn,{initialValue:w+1,notifyError:x,onChangeCommitted:e=>function(e,n,a,o){const r=n._id,s=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:a,newStart:o,assembly:n.assemblyId});return e.submit(s)}(d,a,w,e-1)})),re.default.createElement("td",null,re.default.createElement(kn,{initialValue:S,notifyError:x,onChangeCommitted:e=>function(e,n,a,o){const r=n._id,s=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:a,newEnd:o,assembly:n.assemblyId});return e.submit(s)}(d,a,S,e)})),re.default.createElement("td",null,1===v?"+":-1===v?"-":void 0),re.default.createElement("td",null,re.default.createElement(An,{filterText:h,feature:a}))),E&&b?[...b.entries()].filter((e=>{if(!h)return!0;const[,t]=e;return JSON.stringify(t).includes(h)})).map((([t,a])=>re.default.createElement(e,{isHovered:u?.feature._id===a._id,isSelected:f?._id===a._id,selectedFeatureClass:l,key:t,depth:(n||0)+1,feature:a,model:s,setContextMenu:i}))):null)}));async function ga(e,t,n){const{parent:a}=e;if(a){const e=(await t.getTermsWithLabelOrSynonym(a.type,{includeSubclasses:!1})).filter(nt);if(e.length>0)return await t.getClassesThat("part_of",e)}}const pa=w.makeStyles()((e=>({scrollableTable:{width:"100%",height:"100%",th:{position:"sticky",top:0,zIndex:2,textAlign:"left",background:e.palette.background.paper,paddingTop:"3.2em"},td:{whiteSpace:"normal"}},selectedFeature:{backgroundColor:e.palette.action.selected}}))),ha=S.observer((function({model:e}){const{apolloHover:t,seenFeatures:n,selectedFeature:a,tabularEditor:o}=e,r=f.useTheme(),{classes:s}=pa(),l=h.useRef(null),[i,c]=h.useState(null),{filterText:u}=o;return h.useEffect((()=>{const e=l.current;if(e&&a){const t=e.querySelector(`.${s.selectedFeature}`);if(t){const n=e.scrollTop,a=t.offsetTop-25;a>n&&a<n+e.offsetHeight||e.scroll({top:a-40,behavior:"smooth"})}}}),[a,n,s.selectedFeature]),re.default.createElement("div",{ref:l,style:{width:"100%",overflowY:"auto",height:"100%"}},re.default.createElement("table",{className:s.scrollableTable},re.default.createElement("thead",null,re.default.createElement("tr",null,re.default.createElement("th",null,"Type"),re.default.createElement("th",null,"Start"),re.default.createElement("th",null,"End"),re.default.createElement("th",null,"Strand"),re.default.createElement("th",null,"Attributes"))),re.default.createElement("tbody",null,[...n.entries()].filter((e=>{if(!u)return!0;const[,t]=e;return JSON.stringify(t).includes(u)})).sort(((e,t)=>e[1].min-t[1].min)).map((([n,o])=>re.default.createElement(ma,{key:n,isSelected:a?._id===n,isHovered:t?.feature._id===n,selectedFeatureClass:s.selectedFeature,feature:o,model:e,depth:0,setContextMenu:c}))))),re.default.createElement(y.Menu,{open:Boolean(i),onMenuItemClick:(e,t)=>{t(),c(null)},onClose:()=>{c(null)},TransitionProps:{onExit:()=>{c(null)}},style:{zIndex:r.zIndex.tooltip},menuItems:i?.items??[],anchorReference:"anchorPosition",anchorPosition:i?.position}))})),ya=w.makeStyles()({toolbar:{width:"100%",display:"flex",paddingRight:"2em",flexDirection:"row",justifyContent:"space-between",position:"absolute",zIndex:4},filterText:{}}),ba=S.observer((function({model:e}){const t=e.tabularEditor,{classes:n}=ya();return re.default.createElement("div",{className:n.toolbar},re.default.createElement(f.Tooltip,{title:"Collapse all"},re.default.createElement(f.IconButton,{"aria-label":"collapse",sx:{marginTop:0},onClick:t.collapseAllFeatures},re.default.createElement(we.default,null))),re.default.createElement(f.TextField,{className:n.filterText,label:"Filter features",value:t.filterText,sx:{marginTop:0},variant:"outlined",onChange:e=>{t.setFilterText(e.target.value)},InputProps:{endAdornment:re.default.createElement(f.InputAdornment,{position:"end"},re.default.createElement(f.IconButton,{onClick:()=>{t.clearFilterText()}},re.default.createElement(Se.default,null)))}}))}));function Sa(e){e.stopPropagation()}const wa=S.observer((function({model:e}){return e.tabularEditor.isShown?re.default.createElement("div",{onMouseDown:Sa,onClick:Sa,style:{width:"100%",height:"100%",position:"relative"}},re.default.createElement(ba,{model:e}),re.default.createElement(ha,{model:e})):null})),va=i.types.model("TabularEditor",{isShown:!0,featureCollapsed:i.types.map(i.types.boolean),filterText:""}).actions((e=>({setFeatureCollapsed(t,n){e.featureCollapsed.set(t,n)},setFilterText(t){e.filterText=t},clearFilterText(){e.filterText=""},collapseAllFeatures(){const t=i.getParent(e);for(const[n]of t.seenFeatures.entries())e.featureCollapsed.set(n,!0)},togglePane(){e.isShown=!e.isShown},hidePane(){e.isShown=!1},showPane(){e.isShown=!0}})));function Ca(e,o){return function(e,o){const s=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return a.BaseDisplay.named("BaseLinearApolloDisplay").props({type:i.types.literal("LinearApolloDisplay"),configuration:n.ConfigurationReference(t),graphical:!0,table:!1,heightPreConfig:i.types.maybe(i.types.refinement("displayHeight",i.types.number,(e=>e>=20)))}).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...G.getParentRenderProps(e),config:t.renderer})}})).volatile((()=>({scrollTop:0}))).views((e=>({get lgv(){return r.getContainingView(e)},get height(){return e.heightPreConfig?e.heightPreConfig:e.graphical&&e.table?500:e.graphical?200:300}}))).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get session(){return r.getSession(e)},get regions(){return e.lgv.dynamicBlocks.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:Math.round(a),end:Math.round(t)})))},regionCannotBeRendered(){if(e.lgv&&e.lgv.bpPerPx>=200)return"Zoom in to see annotations"}}))).views((e=>({get apolloInternetAccount(){const[t]=e.regions,{internetAccounts:a}=i.getRoot(e),{assemblyName:o}=t,{assemblyManager:r}=e.session,s=r.get(o);if(!s)throw new Error(`No assembly found with name ${o}`);const{internetAccountConfigId:l}=n.getConf(s,["sequence","metadata"]);return a.find((e=>n.getConf(e,"internetAccountId")===l))},get changeManager(){return e.session.apolloDataStore.changeManager},getAssemblyId(t){const{assemblyManager:n}=e.session,a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return e.session.apolloSelectedFeature}}))).actions((e=>({setScrollTop(t){e.scrollTop=t},setHeight:t=>(e.heightPreConfig=Math.max(t,20),e.height),resizeHeight(t){const n=e.height;return this.setHeight(e.height+t)-n},showGraphicalOnly(){e.graphical=!0,e.table=!1},showTableOnly(){e.graphical=!1,e.table=!0},showGraphicalAndTable(){e.graphical=!0,e.table=!0}}))).views((e=>{const{trackMenuItems:t}=e;return{trackMenuItems(){const{graphical:n,table:a}=e;return[...t(),{type:"subMenu",label:"Appearance",subMenu:[{label:"Show graphical display",type:"radio",checked:n&&!a,onClick:()=>{e.showGraphicalOnly()}},{label:"Show table display",type:"radio",checked:a&&!n,onClick:()=>{e.showTableOnly()}},{label:"Show both graphical and table display",type:"radio",checked:a&&n,onClick:()=>{e.showGraphicalAndTable()}}]}]}}})).actions((e=>({setSelectedFeature(t){e.session.apolloSetSelectedFeature(t)},afterAttach(){i.addDisposer(e,l.autorun((()=>{e.lgv.initialized&&!e.regionCannotBeRendered()&&(e.session.apolloDataStore.loadFeatures(e.regions),e.lgv.bpPerPx<=3&&e.session.apolloDataStore.loadRefSeq(e.regions))}),{name:"LinearApolloDisplayLoadFeatures",delay:1e3}))}})))}(0,t);return o.named("LinearApolloDisplayLayouts").props({featuresMinMaxLimit:5e5}).volatile((()=>({seenFeatures:l.observable.map()}))).views((e=>({get featuresMinMax(){const{assemblyManager:t}=e.session;return e.lgv.displayedRegions.map((n=>{const a=t.get(n.assemblyName);let o,s;const{end:l,refName:i,start:c}=n;for(const[,t]of e.seenFeatures)i!==a?.getCanonicalRefName(t.refSeq)||!r.doesIntersect2(c,l,t.min,t.max)||t.length>e.featuresMinMaxLimit||(void 0===o&&({min:o}=t),void 0===s&&({max:s}=t),t.minWithChildren<o&&({min:o}=t),t.maxWithChildren>s&&({max:s}=t));if(void 0!==o&&void 0!==s)return[o,s]}))}}))).actions((e=>({addSeenFeature(t){e.seenFeatures.set(t._id,t)},deleteSeenFeature(t){e.seenFeatures.delete(t)}}))).views((e=>({get featureLayouts(){const{assemblyManager:t}=e.session;return e.lgv.displayedRegions.map(((n,a)=>{const o=t.get(n.assemblyName),s=new Map,l=e.featuresMinMax[a];if(!l)return s;const[c,u]=l,d=[],{end:f,refName:m,start:g}=n;for(const[t,n]of e.seenFeatures.entries()){if(!i.isAlive(n)){e.deleteSeenFeature(t);continue}if(m!==o?.getCanonicalRefName(n.refSeq)||!r.doesIntersect2(g,f,n.min,n.max))continue;const a=ca(n).getRowCount(n,e.lgv.bpPerPx);let l=0,p=!1;for(;!p;){let e=d.slice(l,l+a);if(e.length<a){for(let t=0;t<a-e.length;t++){const e=d.length;d[e]=Array.from({length:u-c}),s.set(e,[])}e=d.slice(l,l+a)}if(e.map((e=>{const t=n.max-n.min==0?n.min+1:n.max;let a=n.min-c,o=t-c;return n.min-c<0&&(a=0,o=t-n.min),e.slice(a,o).some(Boolean)})).some(Boolean))l+=1;else{for(let e=l;e<l+a;e++){let t=n.min-c,a=n.max-c;n.min-c<0&&(t=0,a=n.max-n.min),d[e].fill(!0,t,a);const o=s.get(e);o?.push([e-l,n])}p=!0}}}return s}))},getFeatureLayoutPosition(e){const{featureLayouts:t}=this;for(const[n,a]of t.entries())for(const[t,o]of a)for(const[a,r]of o)if(0===a){if(e._id===r._id)return{layoutIndex:n,layoutRow:t,featureRow:a};if(r.hasDescendant(e._id)){const a=ca(r).getRowForFeature(r,e);if(void 0!==a)return{layoutIndex:n,layoutRow:t,featureRow:a}}}}}))).views((e=>({get highestRow(){return Math.max(0,...e.featureLayouts.map((e=>Math.max(...e.keys()))))}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(e.lgv.initialized&&!e.regionCannotBeRendered())for(const t of e.regions){const n=e.session.apolloDataStore.assemblies.get(t.assemblyName),a=n?.getByRefName(t.refName),o=a?.features;if(o)for(const[,n]of o)r.doesIntersect2(t.start,t.end,n.min,n.max)&&!e.seenFeatures.has(n._id)&&e.addSeenFeature(n)}}),{name:"LinearApolloDisplaySetSeenFeatures",delay:1e3}))}})))}(0,t).named("LinearApolloDisplayRendering").props({sequenceRowHeight:15,apolloRowHeight:20,detailsMinHeight:200,detailsHeight:200,lastRowTooltipBufferHeight:40,isShown:!0}).volatile((()=>({canvas:null,overlayCanvas:null,collaboratorCanvas:null,seqTrackCanvas:null,seqTrackOverlayCanvas:null,theme:void 0}))).views((e=>({get featuresHeight(){return(e.highestRow+1)*e.apolloRowHeight+e.lastRowTooltipBufferHeight}}))).actions((e=>({toggleShown(){e.isShown=!e.isShown},setDetailsHeight(t){e.detailsHeight=e.isShown?Math.max(Math.min(t,e.height-100),Math.min(e.height,e.detailsMinHeight)):t},setCanvas(t){e.canvas=t},setOverlayCanvas(t){e.overlayCanvas=t},setCollaboratorCanvas(t){e.collaboratorCanvas=t},setSeqTrackCanvas(t){e.seqTrackCanvas=t},setSeqTrackOverlayCanvas(t){e.seqTrackOverlayCanvas=t},setTheme(t){e.theme=t},afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.collaboratorCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const n of e.session.collaborators){const{locations:a}=n;if(0===a.length)continue;let o=0;for(const r of e.lgv.displayedRegions){for(const s of a){if(s.refSeq!==r.refName)continue;const{end:a,refSeq:l,start:i}=s,c=e.lgv.bpToPx({refName:l,coord:i,regionNumber:o});if(!c)continue;const u=c.offsetPx-e.lgv.offsetPx,d=(a-i)/e.lgv.bpPerPx;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(u,1,d,100),t.fillStyle="black",t.fillText(n.name,u+1,11,d-2)}o++}}}}),{name:"LinearApolloDisplayRenderCollaborators"}))}})))}(0,t);return o.actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;if(e.lgv.bpPerPx>3)return;const t=e.seqTrackCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const n=e.lgv.bpPerPx<=1?[3,2,1,0,0,-1,-2,-3]:[3,2,1,-1,-2,-3];let a=0;for(const o of n){const n=e.theme?.palette.framesCDS.at(o)?.main;n&&(t.fillStyle=n,t.fillRect(0,a,e.lgv.dynamicBlocks.totalWidthPx,e.sequenceRowHeight)),a+=e.sequenceRowHeight}for(const[n,a]of e.regions.entries()){const o=e.session.apolloDataStore.getBackendDriver(a.assemblyName);if(!o)throw new Error("Failed to get the backend driver");const{seq:s}=await o.getSequence(a);if(!s)return;for(const[o,l]of[...s].entries()){const i=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,c=3/e.lgv.bpPerPx,u=e.lgv.displayedRegions[n].reversed?i-c:i;for(let n=2;n>=0;n--)(a.start+o)%3===n&&Dn(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*(2-n),c,e.sequenceRowHeight,s,o,!1);if(e.lgv.bpPerPx<=1){const s=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,i=1/e.lgv.bpPerPx,c=e.lgv.displayedRegions[n].reversed?s-i:s;t.beginPath(),t.fillStyle=Nn(l,e.theme),t.rect(c,3*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Rn(t,c,i,l,3*e.sequenceRowHeight));const u=r.revcom(l);t.beginPath(),t.fillStyle=Nn(u,e.theme),t.rect(c,4*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Rn(t,c,i,u,4*e.sequenceRowHeight))}for(let n=0;n<=2;n++)(a.start+o)%3===n&&Dn(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*((e.lgv.bpPerPx<=1?5:3)+n),c,e.sequenceRowHeight,s,o,!0)}}}),{name:"LinearApolloDisplayRenderSequence"}))}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{const{canvas:t,featureLayouts:n,featuresHeight:a,lgv:o}=e;if(!o.initialized||e.regionCannotBeRendered())return;const{displayedRegions:s,dynamicBlocks:l}=o,i=t?.getContext("2d");if(i){i.clearRect(0,0,l.totalWidthPx,a);for(const[t,a]of n.entries()){const n=s[t];for(const[o,s]of a.entries())for(const[a,l]of s)a>0||r.doesIntersect2(n.start,n.end,l.min,l.max)&&ca(l).draw(i,l,o,e,t)}}}),{name:"LinearApolloDisplayRenderFeatures"}))}})))}(0,t);return o.named("LinearApolloDisplayMouseEvents").volatile((()=>({apolloDragging:null,cursor:void 0,apolloHover:void 0}))).views((e=>({getMousePosition(t){const n=function(e,t){const n=e.currentTarget,{clientX:a,clientY:o}=e,{left:r,top:s}=n.getBoundingClientRect(),l=a-r,i=o-s,{coord:c,index:u,refName:d}=t.pxToBp(l);return{x:l,y:i,refName:d,bp:c,regionNumber:u}}(t,e.lgv),{bp:a,regionNumber:o,y:r}=n,s=Math.floor(r/e.apolloRowHeight),l=e.featureLayouts[o].get(s);if(!l)return n;const i=l.find((e=>a>=e[1].min&&a<=e[1].max));if(!i)return n;const[c,u]=i,d=ca(u),f=d.getFeatureFromLayout(u,a,c);return f?{...n,featureAndGlyphUnderMouse:{feature:f,topLevelFeature:u,glyph:d}}:n}}))).actions((e=>({continueDrag(t,n){if(!e.apolloDragging)throw new Error("continueDrag() called with no current drag in progress");n.stopPropagation(),e.apolloDragging={...e.apolloDragging,current:t}},setDragging(t){e.apolloDragging=t??null}}))).actions((e=>({setApolloHover(t){e.apolloHover=t},setCursor(t){e.cursor!==t&&(e.cursor=t)}}))).actions((()=>({onClick(){}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.seqTrackOverlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const{apolloHover:n,lgv:a,regions:o,sequenceRowHeight:s,theme:l}=e;if(!n)return;const{feature:i}=n;for(const[e,n]of o.entries())if("CDS"===i.type){const o=i.parent;if(!o)continue;const c=o.cdsLocations.find((e=>i.min===e.at(0)?.min&&i.max===e.at(-1)?.max));if(!c)continue;for(const o of c){const c=Mn(r.getFrame(o.min,o.max,i.strand??1,o.phase),a.bpPerPx),u=(a.bpToPx({refName:n.refName,coord:o.min,regionNumber:e})?.offsetPx??0)-a.offsetPx,d=(o.max-o.min)/a.bpPerPx;Ln(t,l,a.displayedRegions[e].reversed?u-d:u,s,c,d)}}else{const o=In(i.strand,a.bpPerPx),r=(a.bpToPx({refName:n.refName,coord:i.min,regionNumber:e})?.offsetPx??0)-a.offsetPx,c=i.length/a.bpPerPx;Ln(t,l,a.displayedRegions[e].reversed?r-c:r,s,o,c)}}),{name:"LinearApolloDisplayRenderSeqHighlight"}))}})))}(0,o);return s.views((e=>({contextMenuItems(t){const{apolloHover:n}=e;if(!n||!t)return[];const{topLevelFeature:a}=n;return ca(a).getContextMenuItems(e)}}))).actions((e=>({startDrag(t,n,a){e.apolloDragging={start:t,current:t,feature:n,edge:a}},endDrag(){if(!e.apolloDragging)throw new Error("endDrag() called with no current drag in progress");const{current:n,edge:a,feature:o,start:r}=e.apolloDragging;if(Math.abs(n.x-r.x)<=4)return e.setDragging(),void e.setCursor();const{displayedRegions:s}=e.lgv,l=e.getAssemblyId(s[r.regionNumber].assemblyName);let i;if("max"===a){const e=o._id;i=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[e],featureId:e,oldEnd:o.max,newEnd:n.bp,assembly:l})}else{const e=o._id;i=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[e],featureId:e,oldStart:o.min,newStart:n.bp,assembly:l})}e.changeManager.submit(i),e.setDragging(),e.setCursor()}}))).actions((e=>({onMouseDown(t){const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseDown(e,n,t)},onMouseMove(t){const n=e.getMousePosition(t);if(e.apolloDragging)return e.setCursor("col-resize"),void e.continueDrag(n,t);Fn(n)?n.featureAndGlyphUnderMouse.glyph.onMouseMove(e,n,t):(e.setApolloHover(),e.setCursor())},onMouseLeave(t){e.setDragging(),e.setApolloHover();const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseLeave(e,n,t)},onMouseUp(t){const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseUp(e,n,t),e.apolloDragging&&e.endDrag()}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.overlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);const{apolloDragging:n,apolloHover:a}=e;if(!a)return;const{glyph:o}=a;o.drawHover(e,t),o.drawTooltip(e,t),n&&ca(n.feature.topLevelFeature).drawDragPreview(e,t)}),{name:"LinearApolloDisplayRenderMouseoverAndDrag"}))}})))}(0,o).props({tabularEditor:i.types.optional(va,{})}).named("LinearApolloDisplay")}const Ea=w.makeStyles()((e=>({canvasContainer:{position:"relative",left:0},canvas:{position:"absolute",left:0},ellipses:{textOverflow:"ellipsis",overflow:"hidden"},avatar:{position:"absolute",color:e.palette.warning.light,backgroundColor:e.palette.warning.contrastText}}))),xa=S.observer((function(e){const t=f.useTheme(),{model:n}=e,{apolloRowHeight:a,contextMenuItems:o,cursor:s,featuresHeight:l,isShown:i,onMouseDown:c,onMouseLeave:u,onMouseMove:d,onMouseUp:m,regionCannotBeRendered:g,session:p,setCanvas:b,setCollaboratorCanvas:S,setOverlayCanvas:w,setSeqTrackCanvas:v,setSeqTrackOverlayCanvas:C,setTheme:E}=n,{classes:x}=Ea(),A=r.getContainingView(n);h.useEffect((()=>{E(t)}),[t,E]);const[T,k]=h.useState(),[N,R]=h.useState([]),D=g();if(!i)return null;const{assemblyManager:F}=p;return re.default.createElement(re.default.Fragment,null,A.bpPerPx<=3?re.default.createElement("div",{className:x.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95}},re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),v(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:x.canvas,"data-testid":"seqTrackCanvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),C(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:x.canvas,"data-testid":"seqTrackOverlayCanvas"})):null,re.default.createElement("div",{className:x.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:l},onContextMenu:e=>{if(e.preventDefault(),N.length>0)R([]);else{const t=[e.clientX,e.clientY];k(t),R(o(t))}}},D?re.default.createElement(f.Alert,{severity:"warning",classes:{message:x.ellipses}},re.default.createElement(f.Tooltip,{title:D},re.default.createElement("div",null,D))):re.default.createElement(re.default.Fragment,null,re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),S(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:x.canvas,"data-testid":"collaboratorCanvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),b(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:x.canvas,"data-testid":"canvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),w(e)},width:A.dynamicBlocks.totalWidthPx,height:l,onMouseMove:d,onMouseLeave:u,onMouseDown:c,onMouseUp:m,className:x.canvas,style:{cursor:s??"default"},"data-testid":"overlayCanvas"}),A.displayedRegions.flatMap(((e,t)=>{const o=F.get(e.assemblyName);return[...p.apolloDataStore.checkResults.values()].filter((t=>o?.isValidRefName(t.refSeq)&&o.getCanonicalRefName(t.refSeq)===e.refName&&r.doesIntersect2(e.start,e.end,t.start,t.end))).map((o=>{const r=(A.bpToPx({refName:e.refName,coord:o.start,regionNumber:t})?.offsetPx??0)-A.offsetPx,[s]=o.ids;if(!s)return null;const{topLevelFeature:l}=s,i=parent?n.getFeatureLayoutPosition(l)?.layoutRow??0:0;return re.default.createElement(f.Tooltip,{key:o._id,title:o.message},re.default.createElement(f.Avatar,{className:x.avatar,style:{top:i*a,left:r,height:a,width:a}},re.default.createElement(Ee.default,null)))}))})),re.default.createElement(y.Menu,{open:N.length>0,onMenuItemClick:(e,t)=>{t(),R([])},onClose:()=>{R([])},TransitionProps:{onExit:()=>{R([])}},anchorReference:"anchorPosition",anchorPosition:T?{top:T[1],left:T[0]}:void 0,style:{zIndex:t.zIndex.tooltip},menuItems:N}))))})),Aa=S.observer((function({model:e}){const{height:t}=e;return re.default.createElement("div",{style:{position:"absolute",left:0,top:t/2,width:"100%"}},re.default.createElement("hr",{style:{margin:0,top:0,color:"black"}}))})),Ta=w.makeStyles()((e=>({shading:{background:f.alpha(e.palette.primary.main,.2),overflowY:"scroll",overflowX:"hidden"},details:{background:e.palette.background.paper},accordionControl:{height:12,width:"100%","&:hover":{background:e.palette.action.hover},display:"flex",alignItems:"center",justifyContent:"center"},accordionRoot:{background:e.palette.divider},resizeHandle:{width:"100%",height:4,position:"absolute",cursor:"row-resize",zIndex:100},expandIcon:{},title:{userSelect:"none"},alertContainer:{display:"flex",alignItems:"center",justifyContent:"center"}}))),ka=({onResize:e})=>{const{classes:t}=Ta(),n=h.useCallback((t=>{t.stopPropagation(),t.preventDefault(),e(t.movementY)}),[e]),a=h.useCallback((e=>{e.stopPropagation(),e.preventDefault(),globalThis.removeEventListener("mousemove",n),globalThis.removeEventListener("mouseup",a),globalThis.removeEventListener("mouseleave",a)}),[n]);return re.default.createElement("div",{onMouseDown:e=>{e.stopPropagation(),globalThis.addEventListener("mousemove",n),globalThis.addEventListener("mouseup",a),globalThis.addEventListener("mouseleave",a)},onClick:e=>{e.stopPropagation(),e.preventDefault()},className:t.resizeHandle})},Na=S.observer((function({onClick:e,onResize:t,open:n,title:a}){const{classes:o}=Ta();return re.default.createElement("div",{className:o.accordionRoot},n&&t?re.default.createElement(ka,{onResize:t}):null,re.default.createElement("div",{className:o.accordionControl,onClick:e},re.default.createElement(n?ve.default:Ce.default,{className:o.expandIcon}),a?re.default.createElement(f.Typography,{className:o.title,variant:"caption",component:"span"},a):null))})),Ra=S.observer((function({model:e,...t}){const n=r.getSession(e),{ontologyManager:a}=n.apolloDataStore,{featureTypeOntology:o}=a,s=o?.dataStore,{classes:l}=Ta(),{detailsHeight:i,graphical:c,height:u,isShown:d,selectedFeature:m,table:g,tabularEditor:p,toggleShown:y}=e,b=h.useRef(null);h.useEffect((()=>{!function(e,t){const{apolloRowHeight:n,selectedFeature:a}=e;if(t.current&&a){const o=e.getFeatureLayoutPosition(a);o&&t.current.scroll({top:(o.layoutRow+o.featureRow)*n,behavior:"smooth"})}}(e,b)}),[e,m]);const S=t=>{e.setDetailsHeight(i-t)};if(!s)return re.default.createElement("div",{className:l.alertContainer},re.default.createElement(f.Alert,{severity:"error"},"Could not load feature type ontology."));if(c&&g){const n=p.isShown?i:0,a=d?u-i-24:0;return re.default.createElement("div",{style:{height:u}},re.default.createElement(Na,{open:d,title:"Graphical",onClick:y}),re.default.createElement("div",{className:l.shading,ref:b,style:{height:a}},re.default.createElement(xa,{model:e,...t})),re.default.createElement(Na,{title:"Table",open:p.isShown,onClick:p.togglePane,onResize:S}),re.default.createElement("div",{className:l.details,style:{height:n}},re.default.createElement(wa,{model:e})))}return c?re.default.createElement("div",{className:l.shading,ref:b,style:{height:u}},re.default.createElement(xa,{model:e,...t})):re.default.createElement("div",{className:l.details,style:{height:u}},re.default.createElement(wa,{model:e}))})),Da=i.types.model("JobsManager",{}).views((e=>({get jobStatusWidget(){const{widgets:t}=r.getSession(e);let n=t.get("JobsList");return n||(n=r.getSession(e).addWidget("JobsListWidget","JobsList")),n}}))).actions((e=>({update(t,n,a){e.jobStatusWidget.updateJobStatusMessage(t,n),a&&e.jobStatusWidget.updateJobProgressPct(t,a)},abortJob(t,n){const a=r.getSession(e);if(r.isSessionModelWithWidgets(a)){a.showWidget(e.jobStatusWidget),e.jobStatusWidget.updateJobStatusMessage(t,n??"Aborted unexpectedly");const o=e.jobStatusWidget.jobs.findIndex((e=>e.name===t));e.jobStatusWidget.addAbortedJob({...e.jobStatusWidget.jobs[o]}),e.jobStatusWidget.removeJob(t),a.notify("Job aborted","info")}},runJob(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.addJob(t))},done(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.removeJob(t.name),e.jobStatusWidget.addFinishedJob({name:t.name,statusMessage:"All operations successful",progressPct:100,cancelCallback:t.cancelCallback}))}})));class Fa{clientStore;constructor(e){this.clientStore=e}}class Ma{dataStore;constructor(e){this.dataStore=e}recentChanges=[];async submit(n,a={}){const{addToRecents:o=!0,submitToBackend:s=!0,updateJobsManager:l=!1}=a,i=r.getSession(this.dataStore),c=new AbortController,{jobsManager:u}=r.getSession(this.dataStore),d={name:n.typeName,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{c.abort()}};l&&u.runJob(d);const f=await t.validationRegistry.frontendPreValidate(n);if(!f.ok){const e=`Pre-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),void i.notify(e,"error")}try{await n.execute(this.dataStore)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),void i.notify(String(e),"error")}if((await t.validationRegistry.frontendPostValidate(n,this.dataStore)).ok||await this.revert(n),s){l&&u.update(d.name,"Submitting to driver");const{collaborationServerDriver:t,getBackendDriver:o}=this.dataStore,r=e.isAssemblySpecificChange(n)?o(n.assembly):t;let s;try{s=await r.submitChange(n,a)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),i.notify(String(e),"error"),void await this.revert(n,!1)}if(!s.ok){const e=`Post-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),i.notify(e,"error"),void await this.revert(n,!1)}n.notification&&i.notify(n.notification,"success")}o&&this.recentChanges.push(n),l&&u.done(d)}async revert(e,t=!0){const n=e.getInverse();return this.submit(n,{submitToBackend:t,addToRecents:!1})}async revertLastChange(){const e=this.recentChanges.pop();if(e)return this.revert(e);r.getSession(this.dataStore).notify("No changes to undo!","warning")}}class Ia extends Fa{inFlight=new Map;async fetch(e,t,n){return e.getFetcher({locationType:"UriLocation",uri:t.toString()})(t,n)}async searchFeatures(e,t){const n=this.clientStore.getInternetAccount(t[0]),{baseURL:a}=n,o=new URL("features/searchFeatures",a),r=new URLSearchParams({assemblies:t.join(","),term:e});o.search=r.toString();const s=o.toString(),l=await this.fetch(n,s);if(!l.ok){const e=await Ne(l,"searchFeatures failed");throw new Error(e)}return l.json()}async getFeatures(e){const{assemblyName:t,end:a,refName:o,start:s}=e,{assemblyManager:l}=r.getSession(this.clientStore),i=l.get(t);if(!i)throw new Error(`Could not find assembly with name "${t}"`);const{ids:c}=n.getConf(i,["sequence","metadata"]),u=c[o];if(!u)throw new Error(`Could not find refSeq "${o}"`);const d=this.clientStore.getInternetAccount(t),{baseURL:f}=d,m=new URL("features/getFeatures",f),g=new URLSearchParams({refSeq:u,start:String(s),end:String(a)});m.search=g.toString();const p=m.toString(),h=await this.fetch(d,p);if(!h.ok){const e=await Ne(h,"getFeatures failed");throw new Error(e)}return this.checkSocket(t,o,d),h.json()}checkSocket(t,n,a){const{socket:o}=a,r=a.retrieveToken(),s=`${t}-${n}`,l=new Ma(this.clientStore);o.hasListeners(s)||o.on(s,(async t=>{if(a.setLastChangeSequenceNumber(Number(t.changeSequence)),t.userSessionId!==r&&t.channel===s){const n=e.Change.fromJSON(t.changeInfo);await l.submit(n,{submitToBackend:!1})}}))}async getSequence(e){const t=`${e.refName}:${e.start}-${e.end}`,a=this.inFlight.get(t),{assemblyName:o,end:s,refName:l,start:i}=e,{assemblyManager:c}=r.getSession(this.clientStore),u=c.get(o);if(!u)throw new Error(`Could not find assembly with name "${o}"`);const{ids:d}=n.getConf(u,["sequence","metadata"]),f=d[l];if(!f)throw new Error(`Could not find refSeq "${l}"`);if(a)return{seq:await a,refSeq:f};let m=this.clientStore.assemblies.get(o);m||(m=this.clientStore.addAssembly(o));let g=m.refSeqs.get(f);g||(g=m.addRefSeq(f,l));const p=g.getSequence(i,s);if(p.length===s-i)return{seq:p,refSeq:f};const h=this.clientStore.getInternetAccount(o),{baseURL:y}=h,b=new URL("sequence",y),S=new URLSearchParams({refSeq:f,start:String(i),end:String(s)});b.search=S.toString();const w=b.toString(),v=this.getSeqFromServer(h,w,g,i,s);this.inFlight.set(t,v);const C=await v;return this.checkSocket(o,l,h),this.inFlight.delete(t),{seq:C,refSeq:f}}async getSeqFromServer(e,t,n,a,o){const r=await this.fetch(e,t);if(!r.ok){let e;try{e=await r.text()}catch{e=""}throw new Error(`getSequence failed: ${r.status} (${r.statusText})${e?` (${e})`:""}`)}const s=await r.text();return n.addSequence({sequence:s,start:a,stop:o}),s}async getRefNameAliases(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRefNameAliases failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,aliases:[e._id,...e.aliases],uniqueId:`alias-${e._id}`})))}async getRegions(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRegions failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,start:0,end:e.length})))}getAssemblies(e){const{assemblyManager:t}=r.getSession(this.clientStore);return t.assemblies.filter((t=>{const a=n.getConf(t,["sequence","metadata"]);return!(!(a&&a.apollo&&a.internetAccountConfigId)||e&&a.internetAccountConfigId!==e)}))}async submitChange(e,n={}){const{internetAccountId:a}=n,o=this.clientStore.getInternetAccount("assembly"in e?e.assembly:void 0,a),{baseURL:r}=o,s=new URL("changes",r).href,l=await this.fetch(o,s,{method:"POST",body:JSON.stringify(e.toJSON()),headers:{"Content-Type":"application/json"}});if(!l.ok){const e=await Ne(l,"submitChange failed");throw new Error(e)}const i=new t.ValidationResultSet;return l.ok||(i.ok=!1),i}}class La extends Fa{async getFeatures(){return[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=this.clientStore.assemblies.get(t);if(!r)return{seq:"",refSeq:a};const s=r.refSeqs.get(a);return s?{seq:s.getSequence(o,n),refSeq:a}:{seq:"",refSeq:a}}async getRefNameAliases(e){const t=this.clientStore.assemblies.get(e),n=[];if(!t)return n;for(const[,e]of t.refSeqs)n.push({refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`});return n}async getRegions(e){const t=this.clientStore.assemblies.get(e);if(!t)return[];const n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.file&&!t.internetAccountConfigId)}))}async submitChange(e,n={}){return new t.ValidationResultSet}async searchFeatures(e,t){return[]}}class qa extends Fa{async loadAssembly(e){const{assemblyManager:t}=r.getSession(this.clientStore),a=t.get(e);if(!a)throw new Error(`Assembly ${e} not found`);const{file:o}=n.getConf(a,["sequence","metadata"]),s=require("node:fs");return Te(e,await s.promises.readFile(o,"utf8"),this.clientStore)}async getAssembly(e){let t=this.clientStore.assemblies.get(e);return t||(t=await this.loadAssembly(e)),t}async getRefNameAliases(e){const t=await this.getAssembly(e),n=[];for(const[,e]of t.refSeqs)n.push({refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`});return n}async getFeatures(e){return await this.getAssembly(e.assemblyName),[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=(await this.getAssembly(t)).refSeqs.get(a);if(!r)throw new Error(`refSeq ${a} not found in client data store`);return{seq:r.getSequence(o,n),refSeq:a}}async getRegions(e){const t=await this.getAssembly(e),n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.internetAccountConfigId&&t.file)}))}async submitChange(a){if(!e.isAssemblySpecificChange(a))throw new Error(`Cannot use this type of change with local file: "${a.typeName}"`);const{assemblyManager:o}=r.getSession(this.clientStore),s=o.get(a.assembly);if(!s)throw new Error(`Could not find assembly with name "${a.assembly}"`);const{file:l}=n.getConf(s,["sequence","metadata"]),c=this.clientStore.assemblies.get(a.assembly);if(!c)throw new Error(`Could not find assembly in client with name "${a.assembly}"`);const u=new Set(...c.refSeqs.keys()),{checkResults:d}=this.clientStore;for(const e of d.values())u.has(e.refSeq)&&d.delete(e._id);const f=await ke(c);this.clientStore.addCheckResults(f);const m=[{directive:"gff-version",value:"3"}];for(const[,e]of c.refSeqs)m.push({directive:"sequence-region",value:`${e.name} 1 ${e.sequence[0].stop}`});for(const e of c.comments)m.push({comment:e});for(const[,e]of c.refSeqs){const{features:n}=e;for(const[,e]of n)m.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const[,e]of c.refSeqs){const[n]=e.sequence,a=t.splitStringIntoChunks(n.sequence,80).join("\n");m.push({id:e.name,description:e.description,sequence:a})}const g=ee.default.formatSync(m),p=require("node:fs");return await p.promises.writeFile(l,g,"utf8"),new t.ValidationResultSet}async searchFeatures(e,t){return[]}}function Pa(e,a){const o=new AbortController,{signal:s}=o,c=e.evaluateExtensionPoint("Apollo-extendAnnotationFeature",$.AnnotationFeatureModel),u=function(e){return i.types.model("ClientDataStore",{typeName:i.types.optional(i.types.literal("Client"),"Client"),assemblies:i.types.map($.ApolloAssembly),checkResults:i.types.map($.CheckResult),ontologyManager:i.types.optional(Qe,{})}).views((t=>({get internetAccounts(){return i.getRoot(t).internetAccounts},get pluginConfiguration(){return i.getRoot(t).jbrowse.configuration.ApolloPlugin},getFeature:n=>i.resolveIdentifier(e,t.assemblies,n)}))).actions((e=>({addAssembly(t,n){const a={_id:t,refSeqs:{}};return n&&(a.backendDriverType=n),e.assemblies.put(a)},addFeature(t,n){const a=e.assemblies.get(t);if(!a)throw new Error(`Could not find assembly "${t}" to add feature "${n._id}"`);const o=a.refSeqs.get(n.refSeq);if(!o)throw new Error(`Could not find refSeq "${n.refSeq}" to add feature "${n._id}"`);o.features.put(n)},deleteFeature(t){const n=e.getFeature(t);if(!n)throw new Error(`Could not find feature "${t}" to delete`);const{_id:a,parent:o}=n;o?o.deleteChild(t):i.getParentOfType(n,$.ApolloRefSeq).deleteFeature(a)},deleteAssembly(t){e.assemblies.delete(t)},addCheckResult(t){e.checkResults.put(t)},addCheckResults(t){for(const n of t)e.checkResults.has(n._id)||e.checkResults.put(n)},deleteCheckResult(t){e.checkResults.delete(t)}}))).volatile((e=>({changeManager:new Ma(e),collaborationServerDriver:new Ia(e),inMemoryFileDriver:new La(e),desktopFileDriver:r.isElectron?new qa(e):void 0}))).actions((e=>({afterCreate(){i.addDisposer(e,l.autorun((()=>{const{ontologyManager:t,pluginConfiguration:a}=e,o=a.ontologies;for(const e of o||[]){const[a,o,r,s]=[n.readConfObject(e,"name"),n.readConfObject(e,"version"),n.readConfObject(e,"source"),n.readConfObject(e,"textIndexFields")];t.findOntology(a)||t.addOntology(a,o,r,{textIndexing:{indexFields:s}})}})))}}))).views((e=>({getBackendDriver(t){if(!t)return e.collaborationServerDriver;const a=r.getSession(e),{assemblyManager:o}=a,s=o.get(t);if(!s)return e.collaborationServerDriver;const{file:l,internetAccountConfigId:i}=n.getConf(s,["sequence","metadata"]);return r.isElectron&&l?e.desktopFileDriver:i?e.collaborationServerDriver:e.inMemoryFileDriver},getInternetAccount(t,a){if(!(t??a))throw new Error("Must provide either assemblyName or internetAccountId");let o=a;if(t&&!o){const{assemblyManager:a}=r.getSession(e),s=a.get(t);if(!s)throw new Error(`No assembly found with name ${t}`);({internetAccountConfigId:o}=n.getConf(s,["sequence","metadata"]))}const{internetAccounts:s}=e,l=s.find((e=>e.internetAccountId===o));if(!l)throw new Error(`No InternetAccount found with config id ${a}`);return l}}))).actions((e=>({loadFeatures:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const[a,o]=yield t.getFeatures(n);if(0===a.length)continue;const{assemblyName:r,refName:s}=n;let l=e.assemblies.get(r);l||(l=e.assemblies.put({_id:r,refSeqs:{}}));const[i]=a;let c=l.refSeqs.get(i.refSeq);c||(c=l.refSeqs.put({_id:i.refSeq,name:s,features:{}}));for(const e of a)c.features.has(e._id)||c.features.put(e);e.addCheckResults(o)}})),loadRefSeq:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const{refSeq:a,seq:o}=yield t.getSequence(n),{assemblyName:r,end:s,refName:l,start:i}=n;let c=e.assemblies.get(r);c||(c=e.assemblies.put({_id:r,refSeqs:{}}));let u=c.refSeqs.get(a);u||(u=c.refSeqs.put({_id:a,name:l,sequence:[]})),u.addSequence({start:i,stop:s,sequence:o})}}))})))}(c),d=a.props({apolloDataStore:i.types.optional(u,{typeName:"Client"}),apolloSelectedFeature:i.types.safeReference(c),jobsManager:i.types.optional(Da,{})}).extend((()=>{const e=l.observable.array([]);return{views:{get collaborators(){return e}},actions:{addOrUpdateCollaborator(t){const n=e.find((e=>e.id===t.id));n?n.locations=t.locations:e.push(t)}}}})).actions((e=>({apolloSetSelectedFeature(t){e.apolloSelectedFeature=t},addApolloTrackConfig(t,a){const o=`apollo_track_${t.name}`;e.tracks.some((e=>e.trackId===o))||e.addTrackConf({type:"ApolloTrack",trackId:o,name:`Annotations (${n.getConf(t,"displayName")||t.name})`,assemblyNames:[t.name],textSearching:{textSearchAdapter:{type:"ApolloTextSearchAdapter",trackId:o,assemblyNames:[t.name],textSearchAdapterId:`apollo_search_${t.name}`,...a?{baseURL:{uri:a,locationType:"UriLocation"}}:{}}},displays:[{type:"LinearApolloDisplay",displayId:`${o}-LinearApolloDisplay`},{type:"SixFrameFeatureDisplay",displayId:`${o}-SixFrameFeatureDisplay`}]})},broadcastLocations(){const{internetAccounts:t}=i.getRoot(e),n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const e=t;if(e.initialized){const{dynamicBlocks:t}=e;t.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:t,end:a,refName:o,start:r}=e;n.push({assemblyName:t,refName:o,start:r,end:a})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}}))).actions((e=>({afterCreate:i.flow((function*(){const t=i.getSnapshot(e),{id:n,name:a}=t;i.applySnapshot(e,{name:a,id:n});const{internetAccounts:o,jbrowse:r}=i.getRoot(e);l.autorun((()=>{const t=[];for(const n of e.views){if("LinearGenomeView"!==n.type)return;const e=n;if(e.initialized){const{dynamicBlocks:n}=e;n.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:n,end:a,refName:o,start:r}=e;t.push({assemblyName:n,refName:o,start:r,end:a})}}))}}if(0===t.length){for(const e of o)"baseURL"in e&&e.postUserLocation([]);return}const n=[];for(const e of o)if("baseURL"in e){for(const e of t)n.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(n)}}),{name:"ApolloSession"});for(const n of o){if("ApolloInternetAccount"!==n.type)continue;const{baseURL:a}=n,o=new URL("jbrowse/config.json",a).href,l=n.getFetcher({locationType:"UriLocation",uri:o});let c,u;try{c=yield l(o,{signal:s})}catch(e){console.error(e);continue}if(c.ok){try{u=yield c.json()}catch(e){console.error(e);continue}i.applySnapshot(r,u),i.applySnapshot(e,t)}else{const e=yield Ne(c,"Failed to fetch assemblies");console.error(e)}}})),beforeDestroy(){o.abort("destroying session model")}}))).views((e=>{const a=e.getTrackActionMenuItems;return{getTrackActionMenuItems(o){if("ApolloTrack"===o.type||"ReferenceSequenceTrack"===o.type)return a?.(o);const r=n.readConfObject(o,"trackId");return r.endsWith("-sessionTrack")?[...a?.(o)??[],{label:"Save track to Apollo",onClick:async()=>{const{internetAccounts:n,jbrowse:a}=i.getRoot(e),s=i.getSnapshot(a);let l;l=t.filterJBrowseConfig(s),0===Object.keys(l).length&&(l=void 0);const c={...i.getSnapshot(o),trackId:r.slice(0,r.length-13)};for(const a of n){if("ApolloInternetAccount"!==a.type)continue;const n=new t.ImportJBrowseConfigChange({typeName:"ImportJBrowseConfigChange",oldJBrowseConfig:l,newJBrowseConfig:{...l,tracks:l?.tracks&&[...l.tracks,c]}}),{internetAccountId:o}=a;await e.apolloDataStore.changeManager.submit(n,{internetAccountId:o});const{notify:r}=e;r("Track added","success")}e.deleteTrackConf(o),a.addTrackConf(c)},icon:xe.default}]:[...a?.(o)??[],{label:"Remove track from Apollo",onClick:async()=>{const{internetAccounts:n,jbrowse:a}=i.getRoot(e),s=i.getSnapshot(a);let l;l=t.filterJBrowseConfig(s),0===Object.keys(l).length&&(l=void 0);const c=l?.tracks?.filter((e=>e.trackId!==r));for(const a of n){if("ApolloInternetAccount"!==a.type)continue;const n=new t.ImportJBrowseConfigChange({typeName:"ImportJBrowseConfigChange",oldJBrowseConfig:l,newJBrowseConfig:{...l,tracks:c}}),{internetAccountId:o}=a;await e.apolloDataStore.changeManager.submit(n,{internetAccountId:o});const{notify:r}=e;r("Track removed","success")}e.deleteTrackConf(o),a.deleteTrackConf(o)},icon:xe.default}]}}}));return i.types.snapshotProcessor(d,{postProcessor(e){e.apolloSelectedFeature=void 0;const t=Object.fromEntries(Object.entries(e.apolloDataStore.assemblies).filter((([,e])=>"InMemoryFileDriver"===e.backendDriverType)));return e.apolloDataStore={typeName:"Client",assemblies:t,checkResults:{}},e}})}const Ua={0:2,1:1,2:0},Ba={3:0,4:1,5:2};function _a(e,t){const a=e.getPlugin("LinearGenomeViewPlugin"),{BaseLinearDisplay:o}=a.exports;return o.named("SixFrameFeatureDisplay").props({type:i.types.literal("SixFrameFeatureDisplay"),configuration:n.ConfigurationReference(t),apolloRowHeight:20,detailsMinHeight:200,showStartCodons:!1,showStopCodons:!0,showIntronLines:!0}).volatile((()=>({apolloFeatureUnderMouse:void 0,apolloRowUnderMouse:void 0}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...G.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get regions(){let t;try{({blockDefinitions:t}=e)}catch{return[]}return t.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))},regionCannotBeRendered(){const t=r.getContainingView(e);if(t&&t.bpPerPx>=200)return"Zoom in to see annotations"},get session(){return r.getSession(e)}}))).actions((e=>{let t=[];return{afterAttach(){i.addDisposer(e,l.autorun((()=>{const n=r.getSession(e);if(r.getContainingView(e).initialized){if(e.regionCannotBeRendered())return;const a=[],o=[];for(const n of e.blockDefinitions.contentBlocks)a.push(n.key),t.includes(n.key)||o.push(n);n.apolloDataStore.loadFeatures(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),n.apolloDataStore.loadRefSeq(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),t=a}}),{name:"SixFrameFeatureDisplay"}))}}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get changeManager(){return r.getSession(e).apolloDataStore.changeManager},get sequence(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName),r=o?.getSequence(e.start,e.end);a.set(e.start,r??"")}return a},get features(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName);let r=a.get(e.refName);r||(r=new Map,a.set(e.refName,r));for(const[t,n]of o?.features.entries()??new Map)e.start<n.end&&e.end>n.start&&r.set(t,n)}return a},get featuresMinMax(){const e={};for(const[t,n]of this.features||[]){let a,o;for(const[,e]of n)void 0===a&&({min:a}=e),void 0===o&&({max:o}=e),e.min<a&&({min:a}=e),e.max>o&&({max:o}=e);void 0!==a&&void 0!==o&&(e[t]=[a,o])}return e},get codonLayout(){const e=new Map;let t="",n=0;for(const[e,a]of this.sequence||[])a&&(t||(n=e),t+=a);for(let a=0;a<6;a++){const o=[],s=[],l=a in Ba;let i,c,u;l?(i=(t.length+n)%3,c=(Ba[a]+i+3)%3,u=r.reverse(t).slice(c)):(i=3-n%3,c=(Ua[a]+i+3)%3,u=t.slice(c));for(let e=0;e<u.length;e+=3){const t=u.slice(e,e+3),a=l?r.reverse(r.revcom(t)):t,i=l?n+u.length-(3+e):n+e+c;r.defaultStarts.includes(a.toUpperCase())?o.push(i):r.defaultStops.includes(a.toUpperCase())&&s.push(i)}e.set(a,{starts:o,stops:s})}return e},get featureLayout(){const e=new Map;for(const[t,n]of this.features||[]){if(!n)continue;const a=this.featuresMinMax[t];if(!a)continue;const[o,r]=a,s=[],l=6;for(let t=0;t<l;t++){const t=s.length;s[t]=Array.from({length:r-o}),e.set(t,[])}for(const t of[...n.values()].sort(((e,t)=>{const{max:n,min:a}=e,{max:o,min:r}=t;return a-r||n-o})))for(const[,n]of t.children??new Map)if("mRNA"===n.type)for(const[,a]of n.children||new Map){let o;if("CDS"===a.type){let r;a.discontinuousLocations.length>0?({discontinuousLocations:r}=a):r=[a];for(const a of r){const r=a.start+3,s=a.end-3;for(const[l,{stops:i}]of this.codonLayout)if((l<3&&1===t.strand||l>=3&&-1===t.strand)&&0===i.filter((e=>e>=r&&e<=s)).length){o=l;const t=e.get(o);t?.push([n.featureId,a]);break}}}}}return e},getAssemblyId(t){const{assemblyManager:n}=r.getSession(e),a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return r.getSession(e).apolloSelectedFeature},get setSelectedFeature(){return r.getSession(e).apolloSetSelectedFeature}}))).actions((e=>({setSelectedFeature(t){r.getSession(e).apolloSetSelectedFeature(t)},setApolloFeatureUnderMouse(t){e.apolloFeatureUnderMouse=t},setApolloRowUnderMouse(t){e.apolloRowUnderMouse=t},toggleShowStartCodons(){e.showStartCodons=!e.showStartCodons},toggleShowStopCodons(){e.showStopCodons=!e.showStopCodons},toggleShowIntronLines(){e.showIntronLines=!e.showIntronLines}}))).views((e=>({get highestRow(){return 0===e.featureLayout.size?0:Math.max(...e.featureLayout.keys())},get featuresHeight(){return(this.highestRow+1)*e.apolloRowHeight},get detailsHeight(){return Math.max(e.detailsMinHeight,e.height-this.featuresHeight)},trackMenuItems:()=>[{label:"Show start codons",type:"checkbox",checked:e.showStartCodons,onClick:()=>{e.toggleShowStartCodons()}},{label:"Show stop codons",type:"checkbox",checked:e.showStopCodons,onClick:()=>{e.toggleShowStopCodons()}},{label:"Show intron lines",type:"checkbox",checked:e.showIntronLines,onClick:()=>{e.toggleShowIntronLines()}}]})))}var ja=n.ConfigurationSchema("ApolloRefNameAliasAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});const Oa="undefined"==typeof sessionStorage;class $a extends B.BaseAdapter{refNameAliases;async getRefNameAliases(){const e=n.readConfObject(this.config,"assemblyId");if(!Oa){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)throw new Error("No Apollo data store found");const n=t.getBackendDriver(e);return await n.getRefNameAliases(e)}const t=await new Promise(((t,n)=>{const a=setTimeout((()=>{n(new Error("timeout"))}),2e4),o=q.nanoid(),r=e=>{const n=e.data;(function(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo&&"refNameAliases"in e})(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),t(n.refNameAliases))};addEventListener("message",r),rpcServer.emit("apollo",{apollo:!0,method:"getRefNameAliases",assembly:e,messageId:o})}));return this.refNameAliases=t,t}freeResources(){}}const Ga="WorkerGlobalScope"in globalThis;for(const[n,a]of Object.entries(t.changes))e.changeRegistry.registerChange(n,a);const Wa=new t.CDSCheck;e.checkRegistry.registerCheck(Wa.name,Wa),t.validationRegistry.registerValidation(new t.CoreValidation),t.validationRegistry.registerValidation(new t.ParentChildValidation),exports.default=class extends Z.default{name="ApolloPlugin";version="0.2.1";configurationSchema=Qt;install(e){!function(e){e.addAdapterType((()=>new he.default({name:"ApolloSequenceAdapter",configSchema:zt,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:Ht})))}(e),function(e){e.addAdapterType((()=>new he.default({name:"ApolloRefNameAliasAdapter",configSchema:ja,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:$a})))}(e),function(e){e.addTextSearchAdapterType((()=>new a.TextSearchAdapterType({name:"ApolloTextSearchAdapter",displayName:"Apollo text search adapter",configSchema:Zt,AdapterClass:Kt,description:"Apollo Text Search adapter"})))}(e),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloFeatureDetailsWidget",{});return new a.WidgetType({name:"ApolloFeatureDetailsWidget",heading:"Apollo feature details",configSchema:e,stateModel:gn,ReactComponent:mn})})),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloTranscriptDetails",{});return new a.WidgetType({name:"ApolloTranscriptDetails",heading:"Apollo transcript details",configSchema:e,stateModel:pn,ReactComponent:vn})})),e.addTrackType((()=>{const t=n.ConfigurationSchema("ApolloTrack",{adapter:""},{baseConfiguration:a.createBaseTrackConfig(e),explicitIdentifier:"trackId"});return new a.TrackType({name:"ApolloTrack",configSchema:t,stateModel:a.createBaseTrackModel(e,"ApolloTrack",t)})})),e.addInternetAccountType((()=>new a.InternetAccountType({name:"ApolloInternetAccount",configSchema:Ae,stateModel:$t(Ae)}))),e.addDisplayType((()=>new a.DisplayType({name:"LinearApolloDisplay",configSchema:Cn,stateModel:Ca(0,Cn),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:Ra}))),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("SixFrameFeatureDisplay",{renderer:Xt,height:{type:"number",defaultValue:120}},{baseConfiguration:a,explicitlyTyped:!0})}(e),o=function(e){const t=e.getPlugin("LinearGenomeViewPlugin");if(!t)throw new Error("LinearGenomeView plugin not found");const{BaseLinearDisplayComponent:n}=t.exports;return S.observer((function({model:e,...t}){const{classes:a}=Ta(),{height:o,selectedFeature:r}=e;let{detailsHeight:s}=e;return r||(s=0),re.default.createElement("div",{style:{height:e.height}},re.default.createElement("div",{className:a.shading,style:{height:o-s}},re.default.createElement(n,{model:e,...t})),re.default.createElement("div",{className:"testTrackLines"},re.default.createElement(Aa,{model:e})))}))}(e);return new a.DisplayType({name:"SixFrameFeatureDisplay",configSchema:t,stateModel:_a(e,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:o})})),e.addRendererType((()=>new Yt({name:"ApolloSixFrameRenderer",ReactComponent:Jt,configSchema:Xt,pluginManager:e}))),e.addToExtensionPoint("Core-extendSession",Pa.bind(this,e)),e.addToExtensionPoint("Core-extendPluggableElement",(e=>{if("LinearGenomeView"===e.name){const{stateModel:t}=e,n=t.views((e=>{const t=e.rubberBandMenuItems;return{rubberBandMenuItems:()=>[...t(),{label:"Add new feature",icon:Q.default,onClick:()=>{const t=r.getSession(e),{leftOffset:n,rightOffset:a}=e,o=e.getSelectedRegions(n,a);t.queueDialog((e=>[lt,{session:t,handleClose:()=>{e()},region:o[0],changeManager:t.apolloDataStore.changeManager}]))}}]}}));e.stateModel=n}return e})),e.addToExtensionPoint("Core-extendPluggableElement",en),Ga||e.addToExtensionPoint("Core-extendWorker",(t=>"on"in t&&t.on?(t.on("apollo",(async n=>{if("object"!=typeof(a=n)||null===a||!("apollo"in a)||!0!==a.apollo)return;var a;const{apollo:o,messageId:r,method:s}=n;switch(s){case"getSequence":{const{region:a}=n,{assemblyName:s}=a,l=e.rootModel?.session?.apolloDataStore;if(!l)break;const i=l.getBackendDriver(s),{seq:c}=await i.getSequence(a);t.workers[0].postMessage({apollo:o,messageId:r,sequence:c});break}case"getRegions":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRegions(a);t.workers[0].postMessage({apollo:o,messageId:r,regions:i});break}case"getRefNameAliases":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRefNameAliases(a);t.workers[0].postMessage({apollo:o,messageId:r,refNameAliases:i});break}}})),t):t))}configure(e){r.isAbstractMenuManager(e.rootModel)&&(e.rootModel.appendToMenu("Apollo",{label:"Download GFF3",onClick:e=>{e.queueDialog((t=>[ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Manage Checks",onClick:e=>{e.queueDialog((t=>[pt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View Change Log",onClick:e=>{e.queueDialog((t=>[Nt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Open local GFF3 file",onClick:e=>{e.queueDialog((t=>[Tt,{session:e,handleClose:()=>{t()},inMemoryFileDriver:e.apolloDataStore.inMemoryFileDriver}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View check results",onClick:e=>{e.queueDialog((t=>[Mt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Log out",onClick:e=>{e.queueDialog((t=>[gt,{session:e,handleClose:()=>{t()}}]))}}))}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@apollo-annotation/common"),t=require("@apollo-annotation/shared"),n=require("@jbrowse/core/configuration"),a=require("@jbrowse/core/pluggableElementTypes"),o=require("@jbrowse/core/Plugin"),r=require("@jbrowse/core/util"),s=require("@mui/icons-material/Add"),l=require("mobx"),i=require("mobx-state-tree"),c=require("socket.io-client"),u=require("@gmod/gff"),d=require("@mui/icons-material/Link"),f=require("@mui/material"),m=require("@mui/material/InputAdornment"),g=require("@mui/material/LinearProgress"),p=require("bson-objectid"),h=require("react"),y=require("@jbrowse/core/ui"),b=require("@mui/icons-material/Close"),S=require("mobx-react"),w=require("tss-react/mui"),v=require("@jbrowse/core/util/types/mst"),C=require("idb/with-async-ittr"),E=require("@jbrowse/core/util/aborting"),x=require("jsonpath"),A=require("@jbrowse/core/util/io"),T=require("fast-deep-equal/es6"),k=require("file-saver"),N=require("@mui/material/Checkbox"),R=require("@mui/material/FormControlLabel"),D=require("@mui/icons-material/Delete"),F=require("@mui/x-data-grid"),M=require("@mui/material/utils"),I=require("autosuggest-highlight/match"),L=require("autosuggest-highlight/parse"),q=require("nanoid"),P=require("@mui/icons-material/AccountCircle"),U=require("@jbrowse/core/pluggableElementTypes/AdapterType"),B=require("@jbrowse/core/data_adapters/BaseAdapter"),_=require("@jbrowse/core/util/rxjs"),j=require("@jbrowse/core/util/simpleFeature"),O=require("@jbrowse/core/TextSearch/BaseResults"),$=require("@apollo-annotation/mst"),G=require("@jbrowse/core/util/tracks"),W=require("@mui/icons-material/Clear"),H=require("@mui/icons-material/UnfoldLess"),z=require("@mui/icons-material/ExpandLess"),V=require("@mui/icons-material/ExpandMore"),J=require("@mui/icons-material/Error"),X=require("@mui/icons-material/Save");function Y(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function K(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,a.get?a:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var Z=Y(o),Q=Y(s),ee=Y(u),te=Y(d),ne=Y(m),ae=Y(g),oe=Y(p),re=Y(h),se=K(h),le=Y(b),ie=Y(x),ce=Y(T),ue=Y(N),de=Y(R),fe=Y(D),me=Y(I),ge=Y(L),pe=Y(P),he=Y(U),ye=Y(j),be=Y(O),Se=Y(W),we=Y(H),ve=Y(z),Ce=Y(V),Ee=Y(J),xe=Y(X);const Ae=n.ConfigurationSchema("ApolloInternetAccount",{baseURL:{description:"Location of Apollo server",type:"string",defaultValue:""},tokenType:{description:"A custom name for a token to include in the header",type:"string",defaultValue:"Bearer"}},{baseConfiguration:a.BaseInternetAccountConfig,explicitlyTyped:!0});async function Te(e,n,a){const o=ee.default.parseStringSync(n,{parseSequences:!0,parseComments:!0,parseDirectives:!1,parseFeatures:!0});if(0===o.length)throw new Error("No features found in GFF3 file");let r=0,s=a.assemblies.get(e);s||(s=a.addAssembly(e,"InMemoryFileDriver"));for(const e of o)if(Array.isArray(e)){const n=t.gff3ToAnnotationFeature(e),a=s.refSeqs.get(n.refSeq)??s.addRefSeq(n.refSeq,n.refSeq);a.features.has(n._id)||a.addFeature(n)}else if("comment"in e)s.addComment(e.comment);else{r++;let t=s.refSeqs.get(e.id);t||(t=s.addRefSeq(e.id,e.id,e.description)),e.description&&!t.description&&t.setDescription(e.description),t.addSequence({start:0,stop:e.sequence.length,sequence:e.sequence})}if(0===r)throw new Error("No embedded FASTA section found in GFF3");const l=await ke(s);return a.addCheckResults(l),s}async function ke(t){const n=[];for(const a of t.refSeqs.values())for(const t of a.features.values())for(const o of e.checkRegistry.getChecks().values()){const e=await o.checkFeature(i.getSnapshot(t),((e,t)=>Promise.resolve(a.getSequence(e,t))));n.push(...e)}return n}async function Ne(e,t){let n;try{n=await e.text()}catch{n=""}return`${t?`${t} — `:""}${e.status} ${e.statusText}${n?` (${n})`:""}`}const Re=w.makeStyles()((e=>({dialogTitle:{background:e.palette.primary.main,color:e.palette.primary.contrastText,padding:e.spacing(2)},closeButton:{position:"absolute",right:e.spacing(1),top:e.spacing(1.5),color:e.palette.primary.contrastText}}))),De=S.observer((function(e){const{classes:t}=Re(),{handleClose:n,title:a,...o}=e;return re.default.createElement(y.Dialog,{...o,header:re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogTitle,{className:t.dialogTitle},a),re.default.createElement(f.IconButton,{"aria-label":"close",onClick:n,className:t.closeButton},re.default.createElement(le.default,null)))})}));var Fe;function Me({changeManager:e,handleClose:a,session:o}){const{internetAccounts:r}=i.getRoot(o),{notify:s}=o,l=r.filter((e=>"ApolloInternetAccount"===e.type));if(0===l.length)throw new Error("No Apollo internet account found");const[c,u]=h.useState(""),[d,m]=h.useState(""),[g,p]=h.useState(!1),[y,b]=h.useState(null),[S,w]=h.useState(Fe.GFF3),[v,C]=h.useState(!0),[E,x]=h.useState(!1),[A,T]=h.useState(l[0]),[k,N]=h.useState(""),[R,D]=h.useState(""),[F,M]=h.useState(""),[I,L]=h.useState(!1);let q=!1;try{const e=new URL(k);"http:"!==e.protocol&&"https:"!==e.protocol||(q=!0)}catch{}let P=!1;try{const e=new URL(R);"http:"!==e.protocol&&"https:"!==e.protocol||(P=!0)}catch{}let U=!1;try{const e=new URL(F);"http:"!==e.protocol&&"https:"!==e.protocol||(U=!0)}catch{}return re.default.createElement(De,{open:!0,maxWidth:!1,"data-testid":"add-assembly-dialog",title:"Add new assembly",handleClose:a},I?re.default.createElement(ae.default,null):null,re.default.createElement("form",{onSubmit:async function(n){n.preventDefault(),m(""),x(!0),L(!0),s(`Assembly "${c}" is being added`,"info"),a(),n.preventDefault();const{jobsManager:r}=o,l=new AbortController,i={name:`UploadAssemblyFile for ${c}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{l.abort(),r.abortJob(i.name)}};r.runJob(i);let u="";const{baseURL:d,getFetcher:f,internetAccountId:g}=A;if(S!==Fe.EXTERNAL&&y){const e=new URL("files",d);e.searchParams.set("type",S);const t=e.href,n=new FormData;n.append("file",y),n.append("fileName",y.name),n.append("type",S);const a=f({locationType:"UriLocation",uri:t});if(a){r.update(i.name,"Uploading file, this may take awhile");const{signal:e}=l,o=await a(t,{method:"POST",body:n,signal:e});if(!o.ok){const e=await Ne(o,"Error when inserting new assembly (while uploading file)");return r.abortJob(i.name,e),void m(e)}u=(await o.json())._id}}let p;if(S===Fe.EXTERNAL)p=new t.AddAssemblyFromExternalChange({typeName:"AddAssemblyFromExternalChange",assembly:(new oe.default).toHexString(),assemblyName:c,externalLocation:{fa:k,fai:R,...F?{gzi:F}:{}}});else{const e={assembly:(new oe.default).toHexString(),assemblyName:c,fileIds:{fa:u}};p=S===Fe.GFF3&&v?new t.AddAssemblyAndFeaturesFromFileChange({typeName:"AddAssemblyAndFeaturesFromFileChange",...e}):new t.AddAssemblyFromFileChange({typeName:"AddAssemblyFromFileChange",...e})}r.done(i),await e.submit(p,{internetAccountId:g,updateJobsManager:!0}),x(!1),L(!1)}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},l.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:A.internetAccountId,onChange:function(e){x(!1);const t=l.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);T(t)},disabled:E&&!d},r.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.TextField,{margin:"dense",id:"name",label:"Assembly name",type:"TextField",fullWidth:!0,variant:"outlined",onChange:e=>{x(!1),u(e.target.value),function(e){const{assemblies:t}=o;t.find((t=>n.readConfObject(t,"displayName")===e))?(p(!1),m(`Assembly ${e} already exists.`)):(p(!0),m(""))}(e.target.value)},disabled:E&&!d}),re.default.createElement(f.FormControl,{style:{marginTop:20}},re.default.createElement(f.FormLabel,null,"Select GFF3, FASTA or EXTERNAL option"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:Fe.GFF3,name:"radio-buttons-group",onChange:function(e){w(e.target.value),C(e.target.value===Fe.GFF3),N(""),D(""),b(null)},value:S},re.default.createElement(f.FormControlLabel,{value:Fe.GFF3,control:re.default.createElement(f.Radio,null),label:"GFF3",disabled:E&&!d}),re.default.createElement(f.FormControlLabel,{value:Fe.FASTA,control:re.default.createElement(f.Radio,null),label:"FASTA",disabled:E&&!d}),re.default.createElement(f.FormControlLabel,{value:Fe.EXTERNAL,control:re.default.createElement(f.Radio,null),label:"External",disabled:E&&!d}))),S===Fe.EXTERNAL?re.default.createElement(f.Box,{style:{marginTop:20}},re.default.createElement(f.Typography,{variant:"caption"},"Enter FASTA and FASTA index(es) URL"),re.default.createElement(f.TextField,{margin:"dense",helperText:"Can be bgz-compressed",id:"fasta",label:"FASTA",type:"TextField",fullWidth:!0,variant:"outlined",error:!q,onChange:e=>{N(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}}),re.default.createElement(f.TextField,{margin:"dense",id:"fasta-index",label:"FASTA Index",helperText:".fai or .gz.fai",type:"TextField",fullWidth:!0,variant:"outlined",error:!P,onChange:e=>{D(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}}),re.default.createElement(f.TextField,{margin:"dense",id:"fasta-gzi-index",label:"FASTA GZI Index",helperText:"Only for bgz-compressed FASTA, .gz.gzi",type:"TextField",fullWidth:!0,variant:"outlined",error:Boolean(F)&&!U,onChange:e=>{M(e.target.value)},disabled:E&&!d,InputProps:{startAdornment:re.default.createElement(ne.default,{position:"start"},re.default.createElement(te.default,null))}})):re.default.createElement(f.Box,{style:{marginTop:20}},re.default.createElement("input",{type:"file",onChange:function(e){if(!e.target.files)return;const t=e.target.files.item(0);if(b(t),!t)return;const n=t.name.toLowerCase();n.endsWith(".fasta")||n.endsWith(".fna")||n.endsWith(".fa")?w(Fe.FASTA):(n.endsWith(".gff3")||n.endsWith(".gff"))&&w(Fe.GFF3)},disabled:E&&!d}),re.default.createElement(f.FormGroup,null,re.default.createElement(f.FormControlLabel,{control:re.default.createElement(f.Checkbox,{checked:S===Fe.GFF3&&v,onChange:()=>{C(!v)},disabled:S!==Fe.GFF3||E&&!d}),label:"Also load features from GFF3 file"})))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!g||!((c&&y)??(c&&k&&R&&q&&P))||E,variant:"contained",type:"submit"},E?"Submitting...":"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),d?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},d)):null)}!function(e){e.GFF3="text/x-gff3",e.FASTA="text/x-fasta",e.EXTERNAL="text/x-external"}(Fe||(Fe={}));const Ie=new Set(["i","me","my","myself","we","our","ours","ourselves","you","your","yours","yourself","yourselves","he","him","his","himself","she","her","hers","herself","it","its","itself","they","them","their","theirs","themselves","what","which","who","whom","this","that","these","those","am","is","are","was","were","be","been","being","have","has","had","having","do","does","did","doing","a","an","the","and","but","if","or","because","as","until","while","of","at","by","for","with","about","against","between","into","through","during","before","after","above","below","to","from","up","down","in","out","on","off","over","under","again","further","then","once","here","there","when","where","why","how","all","any","both","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","s","t","can","will","just","don","should","now",..."1234567890"]);function Le(e,t){for(const[n,a]of t.entries())if(e.startsWith(a))return e.replace(a,String(n));return e}const qe="$PREFIXED_ID";function Pe(e,t,n){return t===qe?[Le(e.id,n)]:ie.default.query(e,t)}function Ue(e){return e.toLowerCase().split(/[^\d:A-Za-z]+/).filter((e=>e&&!Ie.has(e)))}function*Be(e){for(const t of e)yield*Ue(t)}function*_e(e){for(const t of e)if("string"==typeof t)yield t;else if("object"==typeof t){const e=ie.default.query(t,"$..*");yield*_e(e)}}function*je(e,t,n){for(const a of t){const t=Pe(e,a,n);if(t.length>0)for(const e of Be(_e(t)))yield[a,e]}}async function Oe(e,t,n){const a=await this.db,o=t??a.transaction(["nodes"]);E.checkAbortSignal(n);const r=[...Ue(e)],s=[],l=new Map;s.push(...r.map((async(e,t)=>{E.checkAbortSignal(n);const a=o.objectStore("nodes").index("full-text-words");for await(const o of a.iterate(IDBKeyRange.bound(e,`${e}￿`,!1,!1))){E.checkAbortSignal(n);const e=o.value,a=l.get(e.id)??[e,new Set];a[1].add(t),l.set(e.id,a)}}))),await Promise.all(s),E.checkAbortSignal(n);const i=[];for(const[,[e,t]]of l)E.checkAbortSignal(n),i.push(...$e(this.textIndexFields,e,t,r,this.prefixes));return i.sort(((e,t)=>t.score-e.score)),i.slice(0,this.options.maxSearchResults??this.DEFAULT_MAX_SEARCH_RESULTS)}function $e(e,t,n,a,o){const r=[...n].sort().map((e=>a[e])),s=r.map((e=>{const t=e.replaceAll(/[$()*+./?[\\\]^{|}-]/g,String.raw`\$&`);return new RegExp(`\\b${t}`,"gi")}));let l=[],i=0;for(const[n,r]of e.entries()){const c=new Set,u=e.length-n-1,d=[..._e(Pe(t,r.jsonPath,o))];for(const e of d){let n=0;const o=[];for(const[t,r]of s.entries())for(const s of e.matchAll(r)){n+=1+1*u,c.add(t);const r=s.index,l=a[t];void 0!==r&&(n+=.01*l.length,n+=l.length/e.length*100*.05,o.push({wordIndex:t,position:r}))}n+=100*c.size,i<n&&(i=n),o.sort(((e,t)=>e.position-t.position)),o.length>0&&l.push({term:t,field:r,str:e,score:n,wordMatches:o})}}l=l.filter((e=>e.score===i));for(const e of l){const{wordMatches:t}=e;for(let n=0;n<t.length-1;n++){const a=t[n],o=t[n+1],s=o.wordIndex-a.wordIndex;if(1===s||-1===s){e.score+=1,1===s&&(e.score+=1);const t=Math.abs(o.position-(a.position+r[a.wordIndex].length))-1;e.score-=.05*t}}}return l}function Ge(e){return"string"==typeof e.id}function We(e){return"string"==typeof e.sub&&"string"==typeof e.pred&&"string"==typeof e.obj}function He(e){return Boolean(e.meta?.deprecated)}async function ze(e){return C.openDB(e,2,{upgrade(e,t,n,a,o){if(t<2&&(e.objectStoreNames.contains("meta")&&e.deleteObjectStore("meta"),e.objectStoreNames.contains("nodes")&&e.deleteObjectStore("nodes"),e.objectStoreNames.contains("edges")&&e.deleteObjectStore("edges")),e.objectStoreNames.contains("meta")||e.createObjectStore("meta"),!e.objectStoreNames.contains("nodes")){e.createObjectStore("nodes",{keyPath:"id"});const t=a.objectStore("nodes");t.createIndex("by-label","lbl"),t.createIndex("by-type","type"),t.createIndex("by-synonym",["meta","synonyms","val"]),t.createIndex("full-text-words","fullTextWords",{multiEntry:!0})}if(!e.objectStoreNames.contains("edges")){e.createObjectStore("edges",{autoIncrement:!0});const t=a.objectStore("edges");t.createIndex("by-subject","sub"),t.createIndex("by-object","obj"),t.createIndex("by-predicate","pred")}}})}function Ve(e){const t=new Set;for(const[,n]of e)t.add(n);return[...t]}async function Je(e){const t=Date.now();let n;try{n=JSON.parse(await A.openLocation(this.sourceLocation).readFile("utf8"))}catch{throw new Error("Error in loading ontology")}const a=Date.now(),[o,...r]=n.graphs??[];if(o){if(r.length>0)throw new Error("multiple graphs not supported");try{const n=e.transaction(["meta","nodes","edges"],"readwrite");await n.objectStore("meta").clear(),await n.objectStore("nodes").clear(),await n.objectStore("edges").clear();const r=n.objectStore("nodes"),s=Xe.call(this).map((e=>e.jsonPath));for(const e of o.nodes??[])Ge(e)&&await r.add({...e,fullTextWords:Ve(je(e,s,this.prefixes))});const l=n.objectStore("edges");for(const e of o.edges??[])We(e)&&await l.add(e);await n.done;const i=e.transaction("meta","readwrite");await i.objectStore("meta").add({ontologyRecord:{name:this.ontologyName,version:this.ontologyVersion,sourceLocation:this.sourceLocation},storeOptions:this.options,graphMeta:o.meta,timestamp:String(new Date),schemaVersion:2,timings:{overall:Date.now()-t,load:Date.now()-a}},"meta"),await i.done}catch(t){throw await e.transaction("meta","readwrite").objectStore("meta").clear(),t}}}function Xe(){return[{displayName:"ID",jsonPath:qe},...this.options.textIndexing?.indexFields??et]}async function Ye(e){const[t]=await e.transaction("meta").objectStore("meta").getAll();return!!t&&ce.default(this.options.prefixes,t.storeOptions.prefixes)&&ce.default(this.options.textIndexing,t.storeOptions.textIndexing)}class Ke{ontologyName;ontologyVersion;sourceLocation;db;options;loadOboGraphJson=Je;getTermsByFulltext=Oe;openDatabase=ze;isDatabaseCurrent=Ye;get textIndexFields(){return Xe.call(this)}get prefixes(){return this.options.prefixes??new Map}DEFAULT_MAX_SEARCH_RESULTS=100;constructor(e,t,n,a){this.ontologyName=e,this.ontologyVersion=t,this.sourceLocation=n,this.db=this.prepareDatabase(),this.options=a??{}}validate(){const e=[],{sourceLocation:t,sourceType:n}=this;return n?"obo-graph-json"!==n&&e.push(new Error(`ontology source file ${JSON.stringify(t)} has type ${n}, which is not yet supported`)):e.push(new Error(`unable to determine format of ontology source file ${JSON.stringify(t)}, file name must end with ".json", ".obo", or ".owl"`)),e}get sourceType(){if(r.isUriLocation(this.sourceLocation)){if(this.sourceLocation.uri.endsWith(".json"))return"obo-graph-json"}else if(r.isLocalPathLocation(this.sourceLocation)&&this.sourceLocation.localPath.endsWith(".json"))return"obo-graph-json"}get dbName(){return`Apollo Ontology "${this.ontologyName}" "${this.ontologyVersion}"`}async prepareDatabase(){const e=this.validate();if(e.length>0)throw e;const t=await this.openDatabase(this.dbName);if(await this.isDatabaseCurrent(t))return t;try{const{sourceLocation:e,sourceType:n}=this;if("obo-graph-json"!==n)throw new Error(`ontology source file ${JSON.stringify(e)} has type ${n}, which is not yet supported`);return await this.loadOboGraphJson(t),t}catch(e){throw t.close(),await C.deleteDB(this.dbName),e}}async termCount(e){const t=await this.db;return(e??t.transaction("nodes")).objectStore("nodes").count()}unique(e){const t=new Map,n=[];for(const a of e)t.has(a.id)||(t.set(a.id,!0),n.push(a));return n}async getTermsWithLabelOrSynonym(e,t,n){const a=t?.includeSubclasses??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=r.objectStore("nodes"),l=[...await s.index("by-label").getAll(e),...await s.index("by-synonym").getAll(e)];if(a){const e=await this.recurseEdges("by-object",l.map((e=>e.id)),(e=>"is_a"===e.pred),"sub",r);for(const t of e){const e=await s.get(t);e&&l.push(e)}}return l}async getPropertiesByLabel(e,t,n){const a=t?.includeSubProperties??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=(await this.getTermsWithLabelOrSynonym(e,{includeSubclasses:!1},r)).filter((e=>at(e)));if(a){const e=await this.recurseEdges("by-object",s.map((e=>e.id)),(e=>"subPropertyOf"===e.pred),"sub",r),t=r.objectStore("nodes");for(const n of e){const e=await t.get(n);e&&at(e)&&s.push(e)}}return s}async recurseEdges(e,t,n,a,o){const r=new Set;return await async function t(s){await Promise.all([...s].map((async s=>{const l=(await o.objectStore("edges").index(e).getAll(s)).filter((e=>n(e))).map((e=>e[a]));if(l.length>0){for(const e of l)r.add(e);await t(l)}})))}(t),r.values()}async*expandNodeSet(e,t="is_a",n,a){const o=await this.db,r=a??o.transaction(["edges"]),s=[...e],l=await this.recurseEdges("subclasses"===n?"by-object":"by-subject",s,(e=>e.pred===t),"subclasses"===n?"sub":"obj",r);for(const e of s)yield e;for(const e of l)yield e}expandSubclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"subclasses",n)}expandSuperclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"superclasses",n)}async getClassesThat(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=await this.getPropertiesByLabel(e,{includeSubProperties:!0},o),s=new Set(r.map((e=>e.id))),l=await async function(e){const t=[];for await(const n of e)t.push(n);return t}(this.expandSuperclasses(t.map((e=>e.id)),"is_a",o)),i=await this.recurseEdges("by-object",l,(e=>s.has(e.pred)),"sub",o),c=this.expandSubclasses(i,"is_a",o),u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&nt(t)&&!He(t)&&u.push(t)}return u}async getClassesWithoutPropertyLabeled(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=o.objectStore("nodes"),s=o.objectStore("edges"),l=(await this.getPropertiesByLabel(e,t,o)).map((e=>e.id)),i=await(async()=>{const e=new Set;for(const t of l)for await(const n of s.index("by-predicate").iterate(t))e.add(n.value.sub);const t=new Set;for await(const n of this.expandSubclasses(e,"is_a",o))t.add(n);return t})(),c=[];for await(const e of r){const t=e.value;nt(t)&&!i.has(t.id)&&c.push(t.id)}const u=[];for(const e of c){const t=await o.objectStore("nodes").get(e);t&&nt(t)&&!He(t)&&u.push(t)}return u}async getAllClasses(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").index("by-type").getAll("CLASS")).filter((e=>!He(e)))}async getAllTerms(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").getAll()).filter((e=>!He(e)))}}const Ze=i.types.model("OntologyRecord",{name:i.types.string,version:"unversioned",source:i.types.union(v.LocalPathLocation,v.UriLocation,v.BlobLocation),options:i.types.frozen()}).volatile((e=>({dataStore:void 0}))).actions((e=>({ping(){},initDataStore(){e.dataStore=new Ke(e.name,e.version,i.getSnapshot(e.source),e.options)},afterCreate(){i.addDisposer(e,l.autorun((()=>{this.initDataStore()})))}}))),Qe=i.types.model("OntologyManager",{ontologies:i.types.array(Ze),prefixes:i.types.optional(i.types.map(i.types.string),{"GO:":"http://purl.obolibrary.org/obo/GO_","SO:":"http://purl.obolibrary.org/obo/SO_"})}).views((e=>({get featureTypeOntologyName(){const t=i.getRoot(e).jbrowse.configuration;return n.readConfObject(t.ApolloPlugin,"featureTypeOntologyName")}}))).views((e=>({get featureTypeOntology(){return this.findOntology(e.featureTypeOntologyName)},findOntology:(t,n)=>e.ontologies.find((e=>e.name===t&&(void 0===n||e.version===n))),openOntology(e,t){return this.findOntology(e,t)?.dataStore},applyPrefixes:t=>Le(t,e.prefixes),expandPrefixes:t=>function(e,t){for(const[n,a]of t.entries())if(e.startsWith(String(n)))return e.replace(String(n),a);return e}(t,e.prefixes)}))).actions((e=>({addOntology(t,n,a,o){const r=e.ontologies.push({name:t,version:n,source:a,options:{prefixes:new Map(e.prefixes.entries()),...o}});e.ontologies[r-1].ping()}}))),et=[{displayName:"Label",jsonPath:"$.lbl"},{displayName:"Synonym",jsonPath:"$.meta.synonyms[*].val"},{displayName:"Definition",jsonPath:"$.meta.definition.val"}],tt=n.ConfigurationSchema("OntologyRecord",{name:{type:"string",description:'the full name of the ontology, e.g. "Gene Ontology"',defaultValue:"My Ontology"},version:{type:"string",description:"the ontology's version string",defaultValue:"unversioned"},source:{type:"fileLocation",description:"the download location for the ontology's source file",defaultValue:{locationType:"UriLocation",uri:"http://example.com/myontology.json"}},textIndexFields:{type:"frozen",description:"JSON paths for text fields that will be indexed for text searching",defaultValue:et}});function nt(e){return"CLASS"===e.type}function at(e){return"PROPERTY"===e.type}async function ot(e,t,n){if(!e)return;const a=await t.getTermsWithLabelOrSynonym(e.type,{includeSubclasses:!1}),o=a.filter(nt);if(0===a.length)return;const r=await t.getClassesThat("part_of",o);return 0!==r.length?r:void 0}function rt({fetchValidTerms:e,filterTerms:t,includeDeprecated:n,onChange:a,ontologyName:o,ontologyVersion:r,renderInput:s,session:l,style:i,value:c}){const[u,d]=h.useState(!1),[m,g]=h.useState(),[p,y]=h.useState(""),[b,S]=h.useState(),{ontologyManager:w}=l.apolloDataStore,v=w.findOntology(o,r)?.dataStore,C=v&&u&&!m,x=v&&!b,A=h.useCallback((e=>(n||!He(e))&&(!t||t(e))),[t,n]);h.useEffect((()=>{u||g(void 0)}),[u]),h.useEffect((()=>{const e=new AbortController,{signal:t}=e;return x&&(y(""),async function(e,t,n,a){if(!t)return;const o=(await e.getTermsWithLabelOrSynonym(t,{includeSubclasses:!1})).find((e=>(n??(()=>!0))(e)));if(!o)throw new Error(`not a valid ${e.ontologyName} term`);return o}(v,c,A).then((e=>{t.aborted||S(e)}),(e=>{t.aborted||E.isAbortException(e)||y(String(e))}))),()=>{e.abort()}}),[l,c,A,v,x]),h.useEffect((()=>{const t=new AbortController,{signal:n}=t;return C&&async function(e,t,n,a){let o;if(t){const n=await t(e,a);n&&(o=n)}return o||(o=await e.getAllTerms()),n?o.filter((e=>n(e))):o}(v,e,A,n).then((e=>{e&&!n.aborted&&g(e)}),(e=>{n.aborted||E.isAbortException(e)||l.notify(e instanceof Error?e.message:String(e),"error")})),()=>{t.abort()}}),[C,A,v,l,e]);const T={};return p&&(T.error=!0,T.helperText=p),re.default.createElement(f.Autocomplete,{style:i,autoComplete:!0,filterSelectedOptions:!0,disableClearable:!0,selectOnFocus:!0,clearOnBlur:!0,handleHomeEndKeys:!0,freeSolo:!0,value:c,options:m??[],onOpen:()=>{d(!0)},onClose:()=>{d(!1)},loading:C,renderInput:s??(e=>re.default.createElement(f.TextField,{...e,...T})),getOptionLabel:e=>"string"==typeof e?e:e.lbl??"",isOptionEqualToValue:(e,t)=>e.lbl===t.lbl,onChange:(e,t)=>{t&&("string"==typeof t?(S(void 0),a(c,t)):t.lbl!==c&&(y(""),S(t),a(c,t.lbl)))}})}function st({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,[l,i]=h.useState(String(r.max)),[c,u]=h.useState(String(r.min+1)),[d,m]=h.useState(""),[g,p]=h.useState(""),[y,b]=h.useState(""),S=Number(l)<=Number(c);return re.default.createElement(De,{open:!0,title:"Add new child feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},re.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),p("");const i=new t.AddFeatureChange({changedIds:[r._id],typeName:"AddFeatureChange",assembly:o,addedFeature:{_id:(new oe.default).toHexString(),refSeq:r.refSeq,min:Number(c)-1,max:Number(l),type:d},parentFeatureId:r._id});await e.submit(i),s("Feature added successfully","success"),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:c,onChange:e=>{u(e.target.value)}}),re.default.createElement(f.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:l,onChange:e=>{i(e.target.value)},error:S,helperText:S?'"End" must be greater than "Start"':null}),re.default.createElement(rt,{session:a,ontologyName:"Sequence Ontology",style:{width:170},value:d,filterTerms:nt,fetchValidTerms:async function(e,t,n){const a=await ot(e,t);if(a)return a;b(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,r),renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(y),helperText:y}),onChange:(e,t)=>{var n;t&&(n=t,p(""),m(n))}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:S||!(c&&l&&d)},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),g?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},g)):null)}function lt({changeManager:e,handleClose:n,region:a,session:o}){const{notify:r}=o,[s,l]=h.useState(String(a.end)),[i,c]=h.useState(String(a.start+1)),[u,d]=h.useState(""),[m,g]=h.useState(),[p,y]=h.useState(""),b=Number(s)<=Number(i);return re.default.createElement(De,{open:!0,title:"Add new feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},re.default.createElement("form",{onSubmit:async function(l){let c;l.preventDefault(),y("");for(const[,e]of o.apolloDataStore.assemblies??new Map)if(e._id===a.assemblyName)for(const[,t]of e.refSeqs??new Map)t.name===a.refName&&(c=t._id);if(!c)return void y("Invalid refseq id");const d=(new oe.default).toHexString(),f=new t.AddFeatureChange({changedIds:[d],typeName:"AddFeatureChange",assembly:a.assemblyName,addedFeature:{_id:d,refSeq:c,min:Number(i)-1,max:Number(s),type:u,strand:m}});await e.submit(f),r("Feature added successfully","success"),n(),l.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:Number(i),onChange:e=>{c(e.target.value)}}),re.default.createElement(f.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:s,onChange:e=>{l(e.target.value)},error:b,helperText:b?'"End" must be greater than "Start"':null}),re.default.createElement(rt,{session:o,ontologyName:"Sequence Ontology",style:{width:170},value:u,filterTerms:nt,renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0}),onChange:(e,t)=>{var n;t&&(n=t,y(""),d(n))}}),re.default.createElement(f.FormControl,null,re.default.createElement(f.InputLabel,{id:"demo-simple-select-label"},"Strand"),re.default.createElement(f.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Strand",value:m?.toString(),onChange:function(e){switch(y(""),Number(e.target.value)){case 1:g(1);break;case-1:g(-1);break;default:g(void 0)}}},re.default.createElement(f.MenuItem,{value:void 0}),re.default.createElement(f.MenuItem,{value:1},"+"),re.default.createElement(f.MenuItem,{value:-1},"-")))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:b||!(i&&s&&u)},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),p?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},p)):null)}function it(e,t){const n=(new oe.default).toHexString();t.push(n);const a={};if(e.children)for(const n of Object.values(e.children)){const e=it(n,t);a[e._id]=e}const o="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString();return{...e,refSeq:o,children:e.children&&a,_id:n}}function ct({changeManager:e,handleClose:a,session:o,sourceAssemblyId:r,sourceFeature:s}){const{assemblyManager:l,notify:c}=o,u=l.assemblyList,[d,m]=h.useState(u.find((e=>e.name!==r))?.name),[g,p]=h.useState([]),[y,b]=h.useState(""),[S,w]=h.useState(s.min),[v,C]=h.useState("");function E(e,t){const n={};if(e.children)for(const a of Object.values(e.children)){const e=E(a,t);e.refSeq=y,e.min=e.min+t,e.max=e.max+t,n[e._id]=e}const a="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString(),o="string"==typeof e._id?e._id:e._id.toHexString();return{...e,refSeq:a,children:e.children&&n,_id:o}}return h.useEffect((()=>{b(""),async function(){if(!d)return void C("No assemblies to copy to");const e=await l.waitForAssembly(d);if(!e)return;const{refNameAliases:t}=e;if(!t)return;const n=[...Object.entries(t)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""})));p(n),b(n[0]?._id||"")}().catch((e=>{C(String(e))}))}),[d,l]),re.default.createElement(De,{open:!0,title:"Copy features and annotations",handleClose:a,maxWidth:!1,"data-testid":"copy-feature"},re.default.createElement("form",{onSubmit:async function(n){if(!d)return;n.preventDefault(),C("");const o=s.length,r=await l.waitForAssembly(d);if(!r)return void C(`Assembly not found: ${d}.`);const u=r.getCanonicalRefName(y),f=r.regions?.find((e=>e.refName===u));if(!f)return void C(`RefSeq not found: ${y}.`);const m=S+o;if(m>f.end)return void C(`Feature would extend beyond the bounds of the selected reference sequence. (Feature would end at ${m}, but reference sequence ends at ${f.end})`);if(S<f.start)return void C(`Reference sequence starts at ${f.start}, feature cannot start before that.`);const g=[],p=it(i.getSnapshot(s),g),h={...p.attributes};"Parent"in h&&delete h.Parent,p.refSeq=y;const b=S-p.min;p.min=S,p.max=S+o;const w=E(p,b),v=new t.AddFeatureChange({changedIds:[p._id],typeName:"AddFeatureChange",assembly:d,addedFeature:{_id:p._id,refSeq:p.refSeq,min:p.min,max:p.max,type:p.type,children:w.children,attributes:h,strand:p.strand},copyFeature:!0,allIds:g});await e.submit(v),c("Feature copied successfully","success"),a(),n.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Target assembly"),re.default.createElement(f.Select,{labelId:"label",value:d,onChange:function(e){m(e.target.value)}},u.filter((e=>e.name!==r)).map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},n.readConfObject(e,"displayName"))))),re.default.createElement(f.DialogContentText,null,"Target reference sequence"),re.default.createElement(f.Select,{labelId:"label",value:y,onChange:function(e){b(e.target.value)}},g.map((e=>re.default.createElement(f.MenuItem,{key:e._id,value:e._id},e.name)))),re.default.createElement(f.DialogContentText,null,"Start position in target reference sequence"),re.default.createElement(f.TextField,{margin:"dense",type:"number",fullWidth:!0,variant:"outlined",value:S,onChange:e=>{w(Number(e.target.value))}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!d||!y||!S,variant:"contained",type:"submit"},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),v?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},v)):null)}function ut({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),[r,s]=h.useState(),[l,c]=h.useState(""),[u,d]=h.useState(!1),[m,g]=h.useState(!1),p=o.filter((e=>"ApolloInternetAccount"===e.type));if(0===p.length)throw new Error("No Apollo internet account found");const[y,b]=h.useState(p[0]),{collaborationServerDriver:S}=a.apolloDataStore,w=S.getAssemblies();return h.useEffect((()=>{w.length>0&&void 0===r&&s(w[0])}),[w,r]),re.default.createElement(De,{open:!0,title:"Delete Assembly",handleClose:n,maxWidth:!1,"data-testid":"delete-assembly"},re.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),g(!0),c(""),!r)return void c("Must select assembly!");const o=new t.DeleteAssemblyChange({typeName:"DeleteAssemblyChange",assembly:r.name});await e.submit(o,{internetAccountId:y.internetAccountId}),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},p.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:y.internetAccountId,onChange:function(e){g(!1);const t=p.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);b(t)},disabled:m&&!l},o.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:r?.name??"",onChange:function(e){const t=w.find((t=>t.name===e.target.value));s(t)},disabled:0===w.length},w.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContentText,null,re.default.createElement("strong",{style:{color:"red"}},"NOTE: All assembly data will be deleted and this operation cannot be undone!")),re.default.createElement(f.FormGroup,null,re.default.createElement(f.FormControlLabel,{control:re.default.createElement(f.Checkbox,{checked:u,onChange:()=>{d(!u)}}),label:"I understand that all assembly data will be deleted"}))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!r||!u,variant:"contained",type:"submit"},"Delete"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),l?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},l)):null)}function dt({changeManager:e,handleClose:n,selectedFeature:a,session:o,setSelectedFeature:r,sourceAssemblyId:s,sourceFeature:l}){const{notify:c}=o,[u,d]=h.useState("");return re.default.createElement(De,{open:!0,title:"Delete feature",handleClose:n,maxWidth:!1,"data-testid":"delete-feature"},re.default.createElement("form",{onSubmit:async function(o){o.preventDefault(),d(""),a?._id===l._id&&r();const u=new t.DeleteFeatureChange({changedIds:[l._id],typeName:"DeleteFeatureChange",assembly:s,deletedFeature:i.getSnapshot(l),parentFeatureId:l.parent?._id});await e.submit(u),c("Feature deleted successfully","success"),n(),o.preventDefault()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Are you sure you want to delete the selected feature?")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit"},"Yes"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),u?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},u)):null)}function ft({handleClose:e,session:a}){const[o,r]=h.useState(),[s,l]=h.useState(""),{collaborationServerDriver:c,getInternetAccount:u,inMemoryFileDriver:d}=a.apolloDataStore,m=[...c.getAssemblies(),...d.getAssemblies()];return re.default.createElement(De,{open:!0,title:"Export GFF3",handleClose:e,maxWidth:!1,"data-testid":"download-gff3"},re.default.createElement("form",{onSubmit:async function(r){if(r.preventDefault(),l(""),!o)return void l("Must select assembly to download");const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]);s?await async function(e){if(!o)return void l("Must select assembly to download");const t=u(o.configuration.name,e),n=new URL("export/getID",t.baseURL),a=new URLSearchParams({assembly:o.name});n.search=a.toString();const r=n.toString(),s=t.getFetcher({locationType:"UriLocation",uri:r}),i=await s(r,{method:"GET"});if(!i.ok){const e=await Ne(i,"Error when exporting ID");return void l(e)}const{exportID:c}=await i.json(),d=new URL("export",t.baseURL),f=new URLSearchParams({exportID:c});d.search=f.toString();const m=d.toString();window.open(m,"_blank")}(s):function(e){if(!o)return void l("Must select assembly to download");const{assemblies:a}=e.apolloDataStore,r=a.get(o.name),s=r?.refSeqs;if(!s)return void l(`No refSeqs found for assembly "${o.name}"`);const c=[{directive:"gff-version",value:"3"}],u=n.getConf(o,["sequence","adapter","features"]);for(const e of u){const{end:t,refName:n,start:a}=e;c.push({directive:"sequence-region",value:`${n} ${a+1} ${t}`})}for(const[,e]of s){const{features:n}=e;if(n)for(const[,e]of n)c.push(t.annotationFeatureToGFF3(i.getSnapshot(e)))}for(const e of u){const{refName:t,seq:n}=e;c.push({id:t,description:"",sequence:n})}const d=ee.default.formatSync(c),f=new Blob([d],{type:"text/plain;charset=utf-8"});k.saveAs(f,`${o.displayName??o.name}.gff3`)}(a),e()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:o?.name??"",onChange:function(e){const t=m.find((t=>t.name===e.target.value));r(t)},disabled:0===m.length},m.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContentText,null,"Select assembly to export to GFF3")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!o,variant:"contained",type:"submit"},"Download"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function mt({changeManager:e,handleClose:a,session:o}){const{apolloDataStore:r}=o,[s,l]=h.useState(),[i,c]=h.useState(),[u,d]=h.useState(""),[m,g]=h.useState(!1),[p,y]=h.useState(),[b,S]=h.useState(!1),[w,v]=h.useState(!1),{collaborationServerDriver:C,getInternetAccount:E}=r,x=C.getAssemblies();return h.useEffect((()=>{i&&(async()=>{const{internetAccountConfigId:e}=n.getConf(i,["sequence","metadata"]),t=E(i.name,e);if(!t)throw new Error("No Apollo internet account found");const{baseURL:a}=t,o=new URL("features/count",a),r=new URLSearchParams({assemblyId:i.name});o.search=r.toString();const s=t.getFetcher({locationType:"UriLocation",uri:o.toString()});v(!0);const l=await s(o.toString(),{method:"GET"});if(!l.ok)throw new Error(await Ne(l));{const e=await l.json();y(e.count)}v(!1)})().catch((e=>{console.error(e),d(e.message??e)}))}),[E,o,i]),re.default.createElement(De,{open:!0,title:"Import Features from GFF3 file",handleClose:a,maxWidth:!1,"data-testid":"import-features-dialog"},w?re.default.createElement(ae.default,null):null,re.default.createElement("form",{onSubmit:async function(r){r.preventDefault(),d(""),v(!0),g(!0);let l="";if(!s)return void d("must select a file");if(!i)return void d("Must select assembly to download");const{internetAccountConfigId:c}=n.getConf(i,["sequence","metadata"]),u=E(i.name,c),{baseURL:f}=u,m=new URL("files",f);m.searchParams.set("type","text/x-gff3");const p=m.href,h=new FormData;h.append("file",s),h.append("fileName",s.name),h.append("type","text/x-gff3");const y=u.getFetcher({locationType:"UriLocation",uri:p});a();const{jobsManager:S}=o,w=new AbortController,C={name:`Importing features for ${i.displayName}`,statusMessage:"Uploading file, this may take awhile",progressPct:0,cancelCallback:()=>{w.abort(),S.abortJob(C.name)}};if(S.runJob(C),y){const{signal:e}=w,t=await y(p,{method:"POST",body:h,signal:e});if(!t.ok){const e=await Ne(t,"Error when inserting new features (while uploading file)");return S.abortJob(C.name,e),void d(e)}l=(await t.json())._id}const x=new t.AddFeaturesFromFileChange({typeName:"AddFeaturesFromFileChange",assembly:i.name,fileId:l,deleteExistingFeatures:b});S.done(C),await e.submit(x,{updateJobsManager:!0})}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{labelId:"label",value:i?.name??"",onChange:function(e){const t=x.find((t=>t.name===e.target.value));c(t),g(!1)},disabled:m&&!u},x.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name))))),re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.DialogContentText,null,"Upload GFF3 to load features"),re.default.createElement("input",{type:"file",onChange:function(e){g(!1),e.target.files&&l(e.target.files[0])},disabled:m&&!u})),p&&p>0?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,null,"This assembly already has ",p," features, would you like to delete the existing features before importing new ones?"),re.default.createElement(de.default,{label:"Yes, delete existing features",disabled:m&&!u,control:re.default.createElement(ue.default,{checked:b,onChange:function(e){S(e.target.checked)},inputProps:{"aria-label":"controlled"},color:"warning"})})):null,re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!(i&&s&&void 0!==p)||m,variant:"contained",type:"submit"},m?"Submitting...":"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:a},"Close"))),u?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},u)):null)}function gt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=h.useState(""),r=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=h.useState(r[0]);return re.default.createElement(De,{open:!0,title:"Log out",handleClose:e,maxWidth:!1,"data-testid":"log-out"},re.default.createElement("form",{onSubmit:function(e){e.preventDefault(),o(""),s.removeToken(),globalThis.location.reload()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},r.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:s.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);l(t)}},n.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Are you sure you want to log out?")),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!s,variant:"contained",type:"submit"},"Log Out"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),a?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},a)):null)}function pt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=h.useState(),[r,s]=h.useState(""),[l,c]=h.useState(!1),u=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===u.length)throw new Error("No Apollo internet account found");const[d,m]=h.useState(u[0]),[g,p]=h.useState([]),[y,b]=h.useState([]),{collaborationServerDriver:S}=t.apolloDataStore,w=S.getAssemblies();function v(e,t){const n=[...y],a=e.target.value;if(t)n.includes(a)||(n.push(a),b(n));else{const e=n.indexOf(a,0);-1!==e&&n.splice(e,1),b(n)}}return h.useEffect((()=>{(async function(){const{baseURL:e,getFetcher:t}=d,n=new URL("checks/types",e).href,a=t({locationType:"UriLocation",uri:n}),o=await a(n,{method:"GET"});if(!o.ok){const e=await Ne(o,"Error when retrieving checks from server");return void s(e)}const r=await o.json();p(r)})().catch((e=>{s(String(e))}))}),[d]),h.useEffect((()=>{w.length>0&&void 0===a&&o(w[0])}),[w,a]),h.useEffect((()=>{(async function(){if(!a)return;const{baseURL:e,getFetcher:t}=d,n=new URL(`/assemblies/${a.name}`,e).href,o=t({locationType:"UriLocation",uri:n}),r=await o(n,{method:"GET"});if(!r.ok){const e=await Ne(r,"Error when retrieving assembly from server");return void s(e)}const l=await r.json();b(l.checks)})().catch((e=>{s(String(e))}))}),[a,d]),re.default.createElement(De,{open:!0,title:"Manage Checks",handleClose:e,"data-testid":"manage-checks"},re.default.createElement("form",{onSubmit:async function(n){if(n.preventDefault(),!a)return void s("Must select assembly!");const{notify:o}=t,{baseURL:r,getFetcher:l}=d,i=new URL("assemblies/checks",r).href,c=l({locationType:"UriLocation",uri:i}),u=await c(i,{method:"POST",body:JSON.stringify({_id:a.name,checks:y,name:""}),headers:{"Content-Type":"application/json"}});if(u.ok)o("Assembly checks updated successfully","success"),e();else{const e=await Ne(u,"Error when updating assembly checks");s(e)}}},re.default.createElement(f.DialogContent,null,u.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:d.internetAccountId,onChange:function(e){c(!1);const t=u.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);m(t)},disabled:l&&!r},n.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement(f.DialogContentText,null,"Select assembly"),re.default.createElement(f.Select,{style:{width:300},labelId:"label",value:a?.name??"",onChange:function(e){const t=w.find((t=>t.name===e.target.value));o(t)},disabled:0===w.length},w.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement("br",null),re.default.createElement("br",null),re.default.createElement(f.TableContainer,{component:f.Paper},re.default.createElement(f.Table,null,re.default.createElement(f.TableHead,null,re.default.createElement(f.TableRow,null,re.default.createElement(f.TableCell,null,"Check name"),re.default.createElement(f.TableCell,null,"Use check"))),re.default.createElement(f.TableBody,null,g.map((e=>re.default.createElement(f.TableRow,{key:e._id},re.default.createElement(f.TableCell,null,e.name),re.default.createElement(f.TableCell,null,re.default.createElement(f.Checkbox,{value:e._id,checked:y.includes(e._id),onChange:v}))))))))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit"},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),r?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},r)):null)}function ht({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),r=o.filter((e=>"ApolloInternetAccount"===e.type&&e.role?.includes("admin")));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=h.useState(""),[c,u]=h.useState(r[0]),[d,m]=h.useState([]),g=h.useCallback((async()=>{const{baseURL:e}=c,t=new URL("users",e).href,n=c.getFetcher({locationType:"UriLocation",uri:t});if(n){const e=await n(t,{method:"GET"});if(!e.ok){const t=await Ne(e,"Error when getting user data from db");return void l(t)}const a=await e.json();m(a.map((e=>void 0===e.role?{...e,role:""}:e)))}}),[c]);function p(e){return e===c.getUserId()}h.useEffect((()=>{g().catch((e=>{l(String(e))}))}),[g]);const y=[{field:"username",headerName:"User",width:140},{field:"email",headerName:"Email",width:160},{field:"role",headerName:"Role",width:140,type:"singleSelect",valueOptions:["readOnly","user","admin","none"],getOptionLabel(e){switch(e){case"readOnly":return"Read-only";case"user":return"User";case"admin":return"Admin";case"none":return"None";default:return"unknown"}},editable:!0},{field:"actions",type:"actions",getActions:n=>[re.default.createElement(F.GridActionsCellItem,{key:`delete-${n.id}`,icon:re.default.createElement(fe.default,null),onClick:async()=>{globalThis.confirm("Delete this user?")&&await async function(n){const a=new t.DeleteUserChange({typeName:"DeleteUserChange",userId:n});await e.submit(a,{internetAccountId:c.internetAccountId}),m((e=>e.filter((e=>e._id!==n))))}(n.id)},disabled:p(n.id),label:"Delete"})]}];return re.default.createElement(De,{open:!0,fullScreen:!0,title:"Manage users",handleClose:n,"data-testid":"manage-users"},re.default.createElement(f.DialogContent,null,r.length>1?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.DialogContentText,null,"Select account"),re.default.createElement(f.Select,{value:c.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);u(t)},disabled:!s},o.map((e=>re.default.createElement(f.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,re.default.createElement("div",{style:{height:"100%",width:"100%"}},re.default.createElement(F.DataGrid,{pagination:!0,rows:d,columns:y,getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},getRowHeight:()=>"auto",isCellEditable:e=>!p(e.id),processRowUpdate:async function(n){const a=new t.UserChange({typeName:"UserChange",role:n.role,userId:n._id});return await e.submit(a,{internetAccountId:c.internetAccountId}),n},onProcessRowUpdateError:e=>{l(String(e))}}))),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function yt({getTagProps:e,index:t,ontology:n,termId:a}){const o=i.getParent(n,2),[r,s]=se.useState(""),[l,c]=se.useState("");return se.useEffect((()=>{const e=new AbortController,{signal:t}=e;return async function(){const e=o.expandPrefixes(a),r=await(n.dataStore?.db);if(!r||t.aborted)return;const l=await r.transaction("nodes").objectStore("nodes").get(e);l&&l.lbl&&!t.aborted&&s(l.lbl||"no label")}().catch((e=>{t.aborted||c(String(e))})),()=>{e.abort()}}),[a,n,o]),se.createElement(f.Tooltip,{title:r},se.createElement("div",null,se.createElement(f.Chip,{label:l||o.applyPrefixes(a),color:l?"error":"default",size:"small",...e({index:t})})))}function bt({includeDeprecated:e,onChange:t,ontologyName:n,ontologyVersion:a,session:o,value:r}){const{ontologyManager:s}=o.apolloDataStore,l=s.findOntology(n,a),[i,c]=se.useState(r.map((e=>({term:{id:e,type:"CLASS"}})))),[u,d]=se.useState(""),[m,g]=se.useState([]),[p,h]=se.useState(!1),[y,b]=se.useState(""),S=se.useMemo((()=>M.debounce((async(t,n)=>{if(!l)return;const{dataStore:a}=l;if(!a)return;const{input:o,signal:r}=t;try{const t=await a.getTermsByFulltext(o,void 0,r),s=new Map,l=[];for(const n of t){if(!nt(n.term)||!e&&He(n.term))continue;let t=s.get(n.term.id);t||(t={term:n.term,matches:[]},s.set(n.term.id,t),l.push(t)),t.matches.push(n)}n(l)}catch(e){E.isAbortException(e)||b(String(e))}}),400)),[e,l]);if(se.useEffect((()=>{const e=new AbortController,{signal:t}=e;if(""!==u)return h(!0),S({input:u,signal:t},(e=>{let t=[];i.length>0&&(t=i),e&&(t=[...t,...e]),g(t),h(!1)})),()=>{e.abort()};g([])}),[S,l,e,u,i]),!l)return null;const w={};return y&&(w.error=!0,w.helperText=y),se.createElement(f.Autocomplete,{getOptionLabel:e=>s.applyPrefixes(e.term.id),filterOptions:e=>e.filter((e=>nt(e.term))),options:m,autoComplete:!0,includeInputInList:!0,filterSelectedOptions:!0,value:i,loading:p,isOptionEqualToValue:(e,t)=>s.applyPrefixes(e.term.id)===s.applyPrefixes(t.term.id),noOptionsText:u?"No matches":"Start typing to search",onChange:(e,n)=>{g(n?[...n,...m]:m),t(n.map((e=>s.applyPrefixes(e.term.id)))),c(n)},onInputChange:(e,t)=>{t&&h(!0),g([]),d(t)},multiple:!0,renderInput:e=>se.createElement(f.TextField,{...e,...w,variant:"outlined",fullWidth:!0}),renderOption:(e,t)=>se.createElement(wt,{...e,ontologyManager:s,option:t,inputValue:u}),renderTags:(e,t)=>e.map(((e,n)=>se.createElement(yt,{termId:e.term.id,index:n,ontology:l,getTagProps:t,key:e.term.id})))})}function St(e){const{search:t,str:n}=e,a=me.default(n,t,{insideWords:!0,findAllOccurrences:!0}),o=ge.default(n,a);return se.createElement(se.Fragment,null,o.map(((e,t)=>se.createElement(f.Typography,{key:t,component:"span",sx:{fontWeight:e.highlight?"bold":"regular"},variant:"body2",color:"text.secondary"},e.text))))}function wt(e){const{inputValue:t,ontologyManager:n,option:a,...o}=e,r=(a.matches??[]).filter((e=>"$.lbl"!==e.field.jsonPath)).map((e=>se.createElement(se.Fragment,{key:`option-${e.term.id}-${e.str}`},se.createElement(f.Typography,{component:"dt",variant:"body2",color:"text.secondary"},e.field.displayName),se.createElement("dd",null,se.createElement(St,{str:e.str,search:t})))));return se.createElement("li",{...o},se.createElement(f.Grid,{container:!0},se.createElement(f.Grid,{item:!0},se.createElement(f.Typography,{component:"span"},n.applyPrefixes(a.term.id))," ",se.createElement(St,{str:a.term.lbl??"(no label)",search:t})," ",se.createElement("dl",null,r))))}const vt=new Map([["Gene Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Sequence Ontology"})]]),Ct=w.makeStyles()((e=>({attributeInput:{maxWidth:600},newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}}))),Et=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"];function xt(e){const{onChange:t,value:n}=e;return re.default.createElement(f.TextField,{type:"text",value:n,onChange:e=>{t(e.target.value.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}function At({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,{internetAccounts:l}=i.getRoot(a),c=h.useMemo((()=>l.find((e=>"ApolloInternetAccount"===e.type))),[l]),u=["admin","user"].includes((c?c.role:"admin")??""),[d,m]=h.useState(""),[g,p]=h.useState(Object.fromEntries([...r.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})))),[y,b]=h.useState(!1),[S,w]=h.useState(""),{classes:v}=Ct(),C=Object.values(g).some((e=>0===e.length||e.includes("")));return re.default.createElement(De,{open:!0,title:"Feature attributes",handleClose:n,maxWidth:!1,"data-testid":"modify-feature-attribute"},re.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),m("");const l={};if(g)for(const[e,t]of Object.entries(g))if(t&&"parent"!==e.toLowerCase())if([...vt.keys()].includes(e))l[e]=t;else switch(e){case"ID":l._id=t;break;case"Name":l.gff_name=t;break;case"Alias":l.gff_alias=t;break;case"Target":l.gff_target=t;break;case"Gap":l.gff_gap=t;break;case"Derives_from":l.gff_derives_from=t;break;case"Note":l.gff_note=t;break;case"Dbxref":l.gff_dbxref=t;break;case"Ontology_term":l.gff_ontology_term=t;break;case"Is_circular":l.gff_is_circular=t;break;default:l[e.toLowerCase()]=t}const i=new t.FeatureAttributeChange({changedIds:[r._id],typeName:"FeatureAttributeChange",assembly:o,featureId:r._id,attributes:l});await e.submit(i),s("Feature attributes modified successfully","success"),n(),a.preventDefault()}},re.default.createElement(f.DialogContent,null,re.default.createElement(f.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const n=vt.get(e)??xt;return re.default.createElement(f.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},re.default.createElement(f.Grid,{item:!0,xs:"auto"},re.default.createElement(f.Paper,{variant:"outlined",className:v.attributeName},re.default.createElement(f.Typography,null,e))),re.default.createElement(f.Grid,{item:!0,flexGrow:1},re.default.createElement(n,{session:a,value:t,onChange:(o=e,e=>{p({...g,[o]:e})})})),re.default.createElement(f.Grid,{item:!0,xs:1},re.default.createElement(f.IconButton,{"aria-label":"delete",size:"medium",disabled:!u,onClick:()=>{!function(e){m("");const{[e]:t,...n}=g;p(n)}(e)}},re.default.createElement(fe.default,{fontSize:"medium",key:e}))));var o})),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Button,{color:"primary",variant:"contained",disabled:y||!u,onClick:()=>{b(!0)}},"Add new")),y?re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Paper,{elevation:8,className:v.newAttributePaper},re.default.createElement(f.Grid,{container:!0,direction:"column"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.FormControl,null,re.default.createElement(f.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?w(""):vt.has(t)?w(t):m("Unknown attribute type")}},re.default.createElement(f.FormControlLabel,{value:"custom",control:re.default.createElement(f.Radio,null),disableTypography:!0,label:re.default.createElement(f.Grid,{container:!0,spacing:1,alignItems:"center"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Typography,null,"Custom")),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.TextField,{label:"Custom attribute key",variant:"outlined",value:vt.has(S)?"":S,disabled:vt.has(S),onChange:e=>{w(e.target.value)}})))}),[...vt.keys()].map((e=>re.default.createElement(f.FormControlLabel,{key:e,value:e,control:re.default.createElement(f.Radio,null),label:e})))))),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{key:"addButton",color:"primary",variant:"contained",style:{margin:2},onClick:function(){m(""),0!==S.trim().length?"Parent"!==S?S in g?m(`Attribute "${S}" already exists`):!/^[A-Z]/.test(S)||Et.includes(S)||[...vt.keys()].includes(S)?(p({...g,[S]:[]}),b(!1),w("")):m(`Key cannot starts with uppercase letter unless key is one of these: ${Et.join(", ")}`):m('"Parent" -key is handled internally and it cannot be modified manually'):m("Attribute key is mandatory")},disabled:!S},"Add"),re.default.createElement(f.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{b(!1),w(""),m("")}},"Cancel")))))):null),d?re.default.createElement(f.DialogContentText,{color:"error"},d):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:y||C||!u},"Submit changes"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",disabled:y,onClick:n},"Cancel"))))}function Tt({handleClose:e,session:t}){const{apolloDataStore:n}=t,{addAssembly:a,addSessionAssembly:o,assemblyManager:s,notify:l}=t,[i,c]=h.useState(null),[u,d]=h.useState(""),[m,g]=h.useState(""),[p,y]=h.useState(!1),b=f.useTheme();return re.default.createElement(De,{open:!0,title:"Open local GFF3 file",handleClose:e,maxWidth:!1,"data-testid":"open-local-file"},re.default.createElement("form",{onSubmit:async function(c){if(c.preventDefault(),g(""),y(!0),!i)throw new Error("No file selected");const d=await new Response(i).text(),f=`${u}-${i.name}-${q.nanoid(8)}`;try{await Te(f,d,n)}catch(t){return console.error(t),l(`Error loading GFF3 ${i.name}, ${String(t)}`,"error"),void e()}const m={name:f,aliases:[u],displayName:u,sequence:{trackId:`sequenceConfigId-${u}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:f},metadata:{apollo:!0,...r.isElectron?{file:i.path}:{}}}};await(o||a)(m);const p=await s.waitForAssembly(m.name);p?(t.addApolloTrackConfig(p),l(`Loaded GFF3 ${i.name}`,"success")):l(`Error loading GFF3 ${i.name}`,"error"),e()}},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.FormControl,null,re.default.createElement("div",{style:{flexDirection:"row"}},re.default.createElement(f.Button,{variant:"contained",component:"label",style:{marginRight:b.spacing()}},"Choose File",re.default.createElement("input",{type:"file",required:!0,hidden:!0,onChange:function(e){const t=e.target.files?.item(0);if(t&&(g(""),c(t),!u)){const e=t.name,n=e.lastIndexOf(".");d(-1===n?e:e.slice(0,n))}}})),i?i.name:"No file chosen"),re.default.createElement(f.FormHelperText,null,"Make sure your GFF3 has an embedded FASTA section")),re.default.createElement(f.TextField,{required:!0,label:"Assembly name",value:u,onChange:function(e){d(e.target.value)}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{disabled:!1,variant:"contained",type:"submit"},p?"Submitting...":"Submit"),re.default.createElement(f.Button,{disabled:p,variant:"outlined",type:"submit",onClick:e},"Cancel"))),m?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},m)):null)}const kt=w.makeStyles()((e=>({changeTextarea:{fontFamily:"monospace",width:600,resize:"none",border:`1px solid ${e.palette.divider}`,borderRadius:e.shape.borderRadius}})));function Nt({handleClose:t,session:n}){const{internetAccounts:a}=i.getRoot(n),o=a.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,{classes:s}=kt(),[l,c]=h.useState(),[u,d]=h.useState([]),[m,g]=h.useState(""),[p,y]=h.useState([]),b=[{field:"sequence"},{field:"typeName",headerName:"Change type",width:200,type:"singleSelect",valueOptions:[...e.changeRegistry.changes.keys()]},{field:"changes",headerName:"Change JSON",width:600,renderCell:({value:e})=>re.default.createElement("textarea",{className:s.changeTextarea,value:JSON.stringify(e),readOnly:!0}),valueFormatter:({value:e})=>JSON.stringify(e)},{field:"user",headerName:"User",width:140},{field:"createdAt",headerName:"Time",width:160,type:"dateTime",valueGetter:e=>e&&new Date(e)}];return h.useEffect((()=>{(async function(){const e=new URL("assemblies",r).href,t=o?.getFetcher({locationType:"UriLocation",uri:e});if(t){const n=await t(e,{method:"GET"});if(!n.ok){const e=await Ne(n,"Error when retrieving assemblies from server");return void c(e)}const a=await n.json();d(a)}})().catch((e=>{c(String(e))}))}),[o,r]),h.useEffect((()=>{!m&&u.length>0&&g(u[0]._id)}),[m,u]),h.useEffect((()=>{(async function(){if(!m)return;const e=new URL("changes",r),t=new URLSearchParams({assembly:m});e.search=t.toString();const n=e.toString(),a=o?.getFetcher({locationType:"UriLocation",uri:n});if(a){const e=await a(n,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ne(e,"Error when retrieving changes");return void c(t)}const t=await e.json();y(t)}})().catch((e=>{c(String(e))}))}),[m,o,r]),re.default.createElement(De,{open:!0,fullScreen:!0,title:"View change log",handleClose:t,"data-testid":"view-changelog"},re.default.createElement(f.Select,{style:{width:200,marginLeft:40},value:m,onChange:function(e){g(e.target.value)}},u.map((e=>re.default.createElement(f.MenuItem,{key:e._id,value:e._id},e.name)))),re.default.createElement(f.DialogContent,null,re.default.createElement(F.DataGrid,{pagination:!0,rows:p,columns:b,getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},initialState:{sorting:{sortModel:[{field:"sequence",sort:"desc"}]},columns:{columnVisibilityModel:{sequence:!1}}}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:t},"Close")),l?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},l)):null)}const Rt=[{field:"refName",headerName:"Ref Name"},{field:"aliases",headerName:"Aliases",editable:!0}],Dt=e=>/^[\da-f]{24}$/i.test(e);function Ft({changeManager:e,handleClose:n,session:a}){const o=h.useRef(null),[r,s]=h.useState(""),[l,i]=h.useState(!1),[c,u]=h.useState(),[d,m]=h.useState([]),[g,p]=h.useState(new Map),{apolloDataStore:y}=a,{collaborationServerDriver:b}=y,S=b.getAssemblies();h.useEffect((()=>{let e=0;const t=()=>{if(!c)return;const n=new Map;if(e<2&&!c.refNames&&(e++,setTimeout(t,50)),!c.refNames)return;const a=c.refNameAliases;for(const e in a){const t=a[e];if(t&&!Dt(e))if(n.has(t)){const a=n.get(t)??[];n.set(t,[...a,e])}else n.set(t,[e])}p(n)};t()}),[c]);const w=()=>[...g].map(((e,t)=>({id:t,refName:e[0],aliases:e[1].filter((t=>t!==e[0])).join(", ")})));return re.default.createElement(De,{open:!0,title:"Add reference sequence aliases",handleClose:n,maxWidth:"sm","data-testid":"add-refseq-alias",fullWidth:!0},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column"}},re.default.createElement(f.Grid,{container:!0,spacing:2},re.default.createElement(f.Grid,{item:!0,xs:4},re.default.createElement(f.FormControl,{disabled:l&&!r,fullWidth:!0},re.default.createElement(f.InputLabel,{id:"demo-simple-select-label"},"Assembly"),re.default.createElement(f.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Assembly",value:c?.name??"",onChange:e=>{const t=S.find((t=>t.name===e.target.value));u(t),i(!1),s(""),o.current&&(o.current.value="")}},S.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))))),re.default.createElement(f.Grid,{item:!0,xs:1}),re.default.createElement(f.Grid,{item:!0,xs:7},re.default.createElement(f.InputLabel,null,"Load RefName alias"),re.default.createElement("input",{type:"file",onChange:e=>{(async e=>{if(!e.target.files)return;const t=e.target.files[0],n=(await t.text()).split("\n"),a=new Map(g);s("");for(const e of n){const t=e.split("\t");for(const e of t)a.has(e)&&a.set(e,[...a.get(e)??[],...t])}p(a)})(e).catch((()=>{s("Error reading file")}))},ref:o,disabled:l&&!r||!c}))),c&&g.size>0?re.default.createElement("div",{style:{height:200,width:"100%",marginTop:20}},re.default.createElement(f.InputLabel,null,"Refname aliases found for selected assembly."),re.default.createElement(F.DataGrid,{rows:w(),columns:Rt,initialState:{pagination:{paginationModel:{page:0,pageSize:5}}},pageSizeOptions:[5,10],onRowSelectionModelChange:e=>{(e=>{if(e.length>0){i(!0);const t=e.flatMap((e=>w().filter((t=>t.id===e))));m(t)}else i(!1),m([])})(e)},processRowUpdate:(e,t)=>{const n=new Map(g);return n.set(e.refName,e.aliases.split(",")),p(n),e},checkboxSelection:!0})):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"contained",type:"submit",disabled:!l,onClick:()=>{const a=[];for(const e of d){const{refName:t}=e,n=e.aliases.split(",").map((e=>e.trim())).filter((e=>e.length>0));a.push({refName:t,aliases:n})}if(s(""),!c)return void s("No assembly selected");const o=new t.AddRefSeqAliasesChange({typeName:"AddRefSeqAliasesChange",assembly:c.name,refSeqAliases:a});e.submit(o).catch((()=>{s("Error submitting change")})),n()}},"Submit"),re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),r?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},r)):null)}function Mt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),{collaborationServerDriver:a}=t.apolloDataStore,o=n.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,[s,l]=h.useState(),[c,u]=h.useState(),[d,m]=h.useState([]),g=a.getAssemblies();return h.useEffect((()=>{!c&&g.length>0&&u(g[0])}),[g,c]),h.useEffect((()=>{(async function(){const e=c?.name;if(!e)return;const t=new URL("checks",r),n=new URLSearchParams({assembly:e});t.search=n.toString();const a=t.toString(),s=o?.getFetcher({locationType:"UriLocation",uri:a});if(s){const e=await s(a,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ne(e,"Error when retrieving checks");return void l(t)}const t=await e.json();m(t)}})().catch((e=>{l(String(e))}))}),[c,o,r]),re.default.createElement(De,{open:!0,fullScreen:!0,title:"View check results",handleClose:e,"data-testid":"view-check-results"},re.default.createElement(f.Select,{style:{width:200,marginLeft:40},value:c?.name??"",onChange:function(e){const t=g.find((t=>t.name===e.target.value));u(t)},disabled:0===g.length},g.map((e=>re.default.createElement(f.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),re.default.createElement(f.DialogContent,null,re.default.createElement(F.DataGrid,{pagination:!0,rows:d,columns:[{field:"_id",headerName:"id",width:50},{field:"name",headerName:"Check name",width:200},{field:"refSeq",headerName:"Reference sequence ID",width:200},{field:"ids",headerName:"Feature IDs",width:200},{field:"message",headerName:"Message",flex:1}],getRowId:e=>e._id,slots:{toolbar:F.GridToolbar},initialState:{sorting:{sortModel:[{field:"name",sort:"asc"}]},columns:{columnVisibilityModel:{name:!0}}}})),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:e},"Close")),s?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},s)):null)}function It(e){const{color:t}=e;return re.default.createElement(f.SvgIcon,{viewBox:"0 0 18 18",style:{fontSize:18,marginRight:4},...e},"disabled"===t?re.default.createElement("path",{d:"M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z"}):re.default.createElement(re.default.Fragment,null,re.default.createElement("path",{d:"M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z",fill:"#4285F4"}),re.default.createElement("path",{d:"M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z",fill:"#34A853"}),re.default.createElement("path",{d:"M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z",fill:"#FBBC05"}),re.default.createElement("path",{d:"M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z",fill:"#EA4335"})))}function Lt(e){const{color:t}=e;return re.default.createElement(f.SvgIcon,{viewBox:"0 0 21 21",style:{fontSize:21},...e},re.default.createElement("rect",{x:"1",y:"1",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#F25022"}),re.default.createElement("rect",{x:"1",y:"11",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#00A4EF"}),re.default.createElement("rect",{x:"11",y:"1",width:"9",height:"9",fill:"disabled"===t?"#939393":"#7FBA00"}),re.default.createElement("rect",{x:"11",y:"11",width:"9",height:"9",fill:"disabled"===t?"#B9B9B9":"#FFB900"}))}const qt=w.makeStyles()((e=>({loginButton:{marginBottom:e.spacing(1),width:"220px",height:"40px",fontSize:"16px",textTransform:"none",justifyContent:"left",padding:"3px 12px"}})));function Pt(e){const{classes:t}=qt(),{disabled:n}=e;return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(It,{color:n?"disabled":void 0}),...e},"Sign in with Google")}function Ut(e){const{classes:t}=qt(),{disabled:n}=e;return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(Lt,{color:n?"disabled":void 0}),...e},"Sign in with Microsoft")}function Bt(e){const{classes:t}=qt();return re.default.createElement(f.Button,{className:t.loginButton,variant:"outlined",startIcon:re.default.createElement(pe.default,{fontSize:"small"}),...e},"Continue as Guest")}const _t=w.makeStyles()((e=>({divider:{marginTop:e.spacing(4),marginBottom:e.spacing(5)}}))),jt=({baseURL:e,handleClose:t,name:n})=>{const{classes:a}=_t(),[o,r]=h.useState(""),[s,l]=h.useState([]);function i(e){t("google"===e?"google":"microsoft"===e?"microsoft":"guest")}h.useEffect((()=>{const t=new AbortController,{signal:n}=t;return async function(){const t=new URL("auth/types",e).href,a=await fetch(t,{method:"GET",signal:n});if(!a.ok){const e=await Ne(a,"Error when retrieving auth types from server");return void r(e)}const o=await a.json();l(o)}().catch((e=>{E.isAbortException(e)||r(String(e))})),()=>{t.abort()}}),[e]);const c=s.includes("google"),u=s.includes("microsoft"),d=s.includes("guest");return re.default.createElement(De,{open:!0,title:`Log in to ${n}`,handleClose:t,maxWidth:!1,"data-testid":"login-apollo"},re.default.createElement(f.DialogContent,{style:{display:"flex",flexDirection:"column",paddingTop:8}},c?re.default.createElement(Pt,{disabled:!c,onClick:()=>{i("google")}}):null,u?re.default.createElement(Ut,{disabled:!u,onClick:()=>{i("microsoft")}}):null,d?re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Divider,{className:a.divider}),re.default.createElement(Bt,{onClick:()=>{i("guest")}})):null),re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{variant:"outlined",type:"submit",onClick:()=>{t()}},"Cancel")),o?re.default.createElement(f.DialogContent,null,re.default.createElement(f.DialogContentText,{color:"error"},o)):null)},Ot="undefined"==typeof sessionStorage,$t=o=>a.InternetAccount.named("ApolloInternetAccount").props({type:i.types.literal("ApolloInternetAccount"),configuration:n.ConfigurationReference(o)}).views((e=>({get baseURL(){return n.getConf(e,"baseURL")},getUserId(){const n=e.retrieveToken();if(n)return t.getDecodedToken(n).id}}))).volatile((()=>({role:void 0}))).actions((e=>{let n=!1;return{setRole(){const a=e.retrieveToken();if(!a)return void(e.role=void 0);const o=t.getDecodedToken(a),{role:r}=o;if(!r&&!n){const{session:t}=i.getRoot(e);t.notify("You have registered as a user but have not been given access. Ask your administrator to enable access for your account.","warning"),n=!0}e.role!==r&&(e.role=r)}}})).actions((e=>{let t;return{addMessageChannel(e,n){t=t=>{this.finishOAuthWindow(t,e,n)},window.addEventListener("message",t)},deleteMessageChannel(){window.removeEventListener("message",t)},finishOAuthWindow(t,n,a){if(t.data.name!==`JBrowseAuthWindow-${e.internetAccountId}`)return void this.deleteMessageChannel();const o=t.data.redirectUri.replace("#","?"),r=new URL(o),s=new URLSearchParams(r.search).get("access_token");this.deleteMessageChannel(),s?(e.storeToken(s),e.setRole(),n(s)):a(new Error("Error with token endpoint"))},async openAuthWindow(t,n,a){const o=r.isElectron?"http://localhost/auth":globalThis.location.origin+globalThis.location.pathname,s=new URL("auth/login",e.baseURL),l=new URLSearchParams({type:t,redirect_uri:o});s.search=l.toString();const i=`JBrowseAuthWindow-${e.internetAccountId}`;if(r.isElectron){const{ipcRenderer:t}=globalThis.require("electron"),r=await t.invoke("openAuthWindow",{internetAccountId:e.internetAccountId,data:{redirect_uri:o},url:s.toString()}),l=new MessageEvent("message",{data:{name:i,redirectUri:r}});this.finishOAuthWindow(l,n,a)}else this.addMessageChannel(n,a),window.open(s,i,"width=500,height=600")}}})).actions((e=>({async getTokenFromUser(t,n){const{baseURL:a}=e,o=await new Promise(((t,n)=>{const{session:a}=i.getRoot(e),{baseURL:o,name:r}=e;a.queueDialog((e=>[jt,{name:r,handleClose:a=>{a?a instanceof Error?n(a):t(a):n(new Error("user cancelled entry")),e()},baseURL:o}]))}));if("guest"!==o)return void e.openAuthWindow(o,t,n);const r=new URL("auth/login",a),s=new URLSearchParams({type:o});r.search=s.toString();const l=r.toString(),c=await fetch(l);if(!c.ok){const e=await Ne(c,"Error when logging in");return void n(new Error(e))}const{token:u}=await c.json();t(u)}}))).volatile((()=>({lastChangeSequenceNumber:void 0}))).actions((e=>({setLastChangeSequenceNumber(t){e.lastChangeSequenceNumber=t}}))).actions((t=>({updateLastChangeSequenceNumber:i.flow((function*(){const{baseURL:e}=t,n=new URL("changes",e),a=new URLSearchParams({limit:"1"});n.search=a.toString();const o=n.toString(),r=t.getFetcher({locationType:"UriLocation",uri:o}),s=yield r(o,{method:"GET"});if(!s.ok){const e=yield Ne(s,"Error when fetching server LastChangeSequence");throw new Error(e)}const l=yield s.json();t.setLastChangeSequenceNumber(l.length>0?l[0].sequence:0)})),getMissingChanges:i.flow((function*(){const{session:n}=i.getRoot(t),{changeManager:a}=n.apolloDataStore;if(!t.lastChangeSequenceNumber)throw new Error("No LastChangeSequence stored in session. Please, refresh you browser to get last updates from server");const{baseURL:o,lastChangeSequenceNumber:r}=t,s=new URL("changes",o),l=new URLSearchParams({since:String(r),sort:"1"});s.search=l.toString();const c=s.toString(),u=t.getFetcher({locationType:"UriLocation",uri:c}),d=yield u(c,{method:"GET"});if(!d.ok)return void console.error(`Error when fetching the last updates to recover socket connection — ${d.status}`);const f=yield d.json();for(const t of f){const n=e.Change.fromJSON(t);a.submit(n,{submitToBackend:!1})}}))}))).volatile((e=>{const{origin:t,pathname:n}=new URL("socket.io/",e.baseURL);return{socket:c.io(t,{path:n})}})).actions((n=>({addSocketListeners(){const{session:a}=i.getRoot(n),{notify:o}=a,r=n.retrieveToken();if(!r)throw new Error("No Token found");const{socket:s}=n,{addCheckResult:l,changeManager:c,deleteCheckResult:u}=a.apolloDataStore;s.on("connect",(async()=>{await n.getMissingChanges()})),s.on("connect_error",(e=>{console.error(e),o("Could not connect to the Apollo server.","error")})),s.on("COMMON",(t=>{if("checkResult"in t)return void(t.deleted?u(t.checkResult._id.toString()):l(t.checkResult));if(sessionStorage.setItem("LastChangeSequence",String(t.changeSequence)),t.userSessionId===r)return;const n=e.Change.fromJSON(t.changeInfo);c.submit(n,{submitToBackend:!1})})),s.on("USER_LOCATION",(e=>{const{channel:n,locations:o,userName:s,userSessionId:l}=e,i=t.getDecodedToken(r),c=t.makeUserSessionId(i);"USER_LOCATION"===n&&l!==c&&a.addOrUpdateCollaborator({name:s,id:l,locations:o})})),s.on("REQUEST_INFORMATION",(e=>{const{channel:t,userSessionId:n}=e;"REQUEST_INFORMATION"===t&&n!==r&&a.broadcastLocations()}))}}))).actions((e=>({postUserLocation:(t=>{let n;return t=>{clearTimeout(n),n=setTimeout((()=>{!async function(t){const{baseURL:n}=e,a=new URL("users/userLocation",n).href,o=new URLSearchParams(JSON.stringify(t)),r=e.getFetcher({locationType:"UriLocation",uri:a});try{if(!(await r(a,{method:"POST",body:o})).ok)throw new Error("ignore")}catch{console.error("Broadcasting user location failed")}}(t)}),300)}})()}))).actions((e=>({initialize:i.flow((function*(t){if("admin"===t){const t=i.getRoot(e);r.isAbstractMenuManager(t)&&function(e){e.appendToMenu("Apollo",{label:"Add Assembly",onClick:e=>{e.queueDialog((t=>[Me,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Delete Assembly",onClick:e=>{e.queueDialog((t=>[ut,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Import Features",onClick:e=>{e.queueDialog((t=>[mt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Add reference sequence aliases",onClick:e=>{e.queueDialog((t=>[Ft,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Manage Users",onClick:e=>{e.queueDialog((t=>[ht,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Undo",onClick:e=>{const{apolloDataStore:t}=e,{notify:n}=e;t.changeManager.recentChanges.length>0?t.changeManager.revertLastChange():n("No changes to undo","info")}})}(t)}yield e.updateLastChangeSequenceNumber(),e.addSocketListeners();const{baseURL:n}=e,a=new URL("users/locations",n).href,o=e.getFetcher({locationType:"UriLocation",uri:a});yield o(a,{method:"GET"}),window.addEventListener("beforeunload",(()=>{e.postUserLocation([])})),document.addEventListener("visibilitychange",(()=>{if("hidden"===document.visibilityState&&e.postUserLocation([]),"visible"===document.visibilityState){const{session:t}=i.getRoot(e);t.broadcastLocations()}}))}))}))).actions((e=>({afterAttach(){e.setRole(),l.autorun((async t=>{if(Ot)return;const{session:n}=i.getRoot(e);n&&e.role&&(await e.initialize(e.role),t.dispose())}),{name:"ApolloInternetAccount"})}})));function Gt(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo}const Wt="undefined"==typeof sessionStorage;class Ht extends B.BaseSequenceAdapter{regions;async getRefNames(e){return(await this.getRegions(e)).map((e=>e.refName))}async getRegions(e){if(this.regions)return this.regions;const t=n.readConfObject(this.config,"assemblyId");if(!Wt){const e=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!e)throw new Error("No Apollo data store found");const n=e.getBackendDriver(t),a=await n.getRegions(t);return this.regions=a,a}const a=await new Promise(((n,a)=>{const o=setTimeout((()=>{a("timeout")}),2e4),r=q.nanoid(),s=e=>{const{data:t}=e;Gt(t)&&t.messageId===r&&(clearTimeout(o),removeEventListener("message",s),n(t.regions))};addEventListener("message",s,e),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getRegions",assembly:t,messageId:r})}));return this.regions=a,a}getFeatures(e,t){const{end:a,refName:o,start:r}=e,s=n.readConfObject(this.config,"assemblyId"),l={...e,assemblyName:s};return _.ObservableCreate((async e=>{if(!Wt){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)return void e.error("No Apollo data store found");const n=t.getBackendDriver(s),{seq:i}=await n.getSequence(l);return e.next(new ye.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:i}})),void e.complete()}const n=await new Promise(((e,n)=>{const a=setTimeout((()=>{n("timeout")}),2e4),o=q.nanoid(),r=t=>{const{data:n}=t;Gt(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),e(n.sequence))};addEventListener("message",r,t),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getSequence",region:l,messageId:o})}));e.next(new ye.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:n}})),e.complete()}))}freeResources(){}}var zt=n.ConfigurationSchema("ApolloSequenceAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});function Vt(e,t,n,a,o,r){const s=a/o;e.fillStyle="black",e.fillRect(t,n,s,r),s>2&&(e.clearRect(t+1,n+1,s-2,r-2),e.fillStyle="rgba(255,255,255,0.75)",e.fillRect(t+1,n+1,s-2,r-2))}var Jt=S.observer((function(e){const[a,o]=h.useState(),[s,c]=h.useState(),u=h.useRef(null),d=h.useRef(null),m=h.useRef(null),[g,p]=h.useState(!1),[y,b]=h.useState(!0),[S,w]=h.useState(),[v,C]=h.useState(!1),[E,x]=h.useState([]),{bpPerPx:A,displayModel:T,regions:k}=e,{session:N}=T,{collaborators:R}=N;h.useEffect((()=>l.autorun((()=>{x(l.toJS(R))}))),[]);const[D]=k,F=(D.end-D.start)/A,{apolloFeatureUnderMouse:M,apolloRowHeight:I,apolloRowUnderMouse:L,changeManager:q,codonLayout:P,featureLayout:U,features:B,featuresHeight:_,getAssemblyId:j,selectedFeature:O,setApolloFeatureUnderMouse:$,setApolloRowUnderMouse:G,setSelectedFeature:W,showIntronLines:H,showStartCodons:z,showStopCodons:V}=T,J=[...B.values()].map((e=>[...e.values()].map((e=>i.getSnapshot(e))))),X=h.useMemo((()=>{const{internetAccounts:e}=i.getRoot(N),{assemblyName:t}=D,{assemblyManager:a}=r.getSession(T),o=a.get(t);if(!o)throw new Error(`No assembly found with name ${t}`);const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]),l=e.find((e=>n.getConf(e,"internetAccountId")===s));if(!l)throw new Error(`No InternetAccount found with config id ${s}`);return l}),[T,D,N]),{role:Y}=X;return h.useEffect((()=>{Y?.includes("admin")&&p(!0),(Y?.includes("admin")??Y?.includes("user"))&&b(!1)}),[Y]),h.useEffect((()=>{const e=u.current;if(!e)return;const t=e.getContext("2d");if(!t)return;const n={};t.clearRect(0,0,F,_);for(const[e,a]of U)for(const[o,r]of a){const a=D.reversed?D.end-r.max:r.min-D.start-1,s=r.max-D.start-1,l=a/A,i=s/A;Vt(t,l,e*I,s-a,A,I);const c=e*I+I/2;n[o]||(n[o]=[]),n[o].some((e=>e[0]===l&&e[1]===c))||n[o].push([l,c]),n[o].some((e=>e[0]===i&&e[1]===c))||n[o].push([i,c])}if(H){let e=-Math.floor(Object.keys(n).length/2);for(const a in n){t.strokeStyle=`hsl(${e*(180*(3-Math.sqrt(5)))+60},100%,50%)`;const o=n[a].sort(((e,t)=>e[0]-t[0]));let[r]=o;for(const[n,a]of o.entries())if(0!==n){if(n%2==0){const n=[(a[0]-r[0])/2+r[0],Math.max(1,Math.min(r[1],a[1])-I/2+2*e)];t.beginPath(),t.moveTo(r[0],r[1]+2*e),t.lineTo(...n),t.stroke(),t.moveTo(...n),t.lineTo(a[0],a[1]+2*e),t.stroke()}r=a}e+=1}}}),[H,D,A,D.start,D.end,D.reversed,F,U,_,B,I,J]),h.useEffect((()=>{const e=m.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,F,_);for(const[e,{starts:n,stops:a}]of P){const o=A;for(const a of n){const n=a/o;D.start/o<=n&&n<=D.end/o&&(t.fillStyle="rgba(255,0,255,1)",z?t.fillRect(Math.round(n-.5-D.start/o),e*I,1,I):t.clearRect(Math.round(n-.5-D.start/o),e*I,1,I))}for(const n of a){const a=n/o;D.start/o<=a&&a<=D.end/o&&(t.fillStyle="black",V?t.fillRect(Math.round(a-.5-D.start/o),e*I,1,I):t.clearRect(Math.round(a-.5-D.start/o),e*I,1,I))}}}}),[z,V,P,F,_,A,I,D,D.start,D.end]),h.useEffect((()=>{const e=d.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,F,_);for(const e of E){const{locations:n}=e;if(0===n.length)return;for(const a of n){const{end:n,start:o}=a,r=(D.reversed?D.end-o:o-D.start)/A,s=(n-o)/A;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(r,1,s,100),t.fillStyle="black",t.fillText(e.name,r+1,11,s-2)}}}}),[M,L,A,_,F,D,D.start,D.end,D.reversed,S,I,E]),re.default.createElement("div",{style:{position:"relative",width:F,height:_}},re.default.createElement(f.Menu,{open:Boolean(s),anchorReference:"anchorPosition",anchorPosition:a?{left:a[0],top:a[1]}:void 0,"data-testid":"base_linear_display_context_menu",onClose:()=>{c(void 0)}},re.default.createElement(f.MenuItem,{disabled:y,key:1,value:1,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[st,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e,internetAccount:X}]))}},"Add child feature"),re.default.createElement(f.MenuItem,{disabled:y,key:2,value:2,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[ct,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e}]))}},"Copy features and annotations"),re.default.createElement(f.MenuItem,{disabled:!g,key:3,value:3,onClick:()=>{if(!s)return;const e=j(D.assemblyName);N.queueDialog((t=>[dt,{session:N,handleClose:()=>{t(),c(void 0)},changeManager:q,sourceFeature:s,sourceAssemblyId:e,selectedFeature:O,setSelectedFeature:W}]))}},"Delete feature")),re.default.createElement("canvas",{ref:u,width:F,height:_,style:{position:"absolute",left:0,top:0}}),re.default.createElement("canvas",{ref:d,width:F,height:_,onMouseLeave:function(){$(),G()},onMouseUp:async function(){if(v){if(S){const e=j(D.assemblyName),{bp:n,edge:a,feature:o}=S;let r;if("end"===a){const a=o._id,s=o.max,l=Math.round(n);r=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[a],featureId:a,oldEnd:s,newEnd:l,assembly:e})}else{const a=o._id,s=o.min,l=Math.round(n);r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[a],featureId:a,oldStart:s,newStart:l,assembly:e})}await q.submit(r)}}else M&&W(M);w(void 0),C(!1)},onContextMenu:function(e){e.preventDefault(),c(M),o([e.pageX,e.pageY])},style:{position:"absolute",left:0,top:0}}),re.default.createElement("canvas",{ref:m,width:F,height:6*I,style:{position:"absolute",left:0,top:0}}))})),Xt=n.ConfigurationSchema("ApolloSixFrameRenderer",{},{explicitlyTyped:!0});class Yt extends a.RendererType{async renderInClient(e,t){return this.render(t)}async freeResourcesInClient(e,t){return 0}}class Kt extends B.BaseAdapter{get baseURL(){return n.readConfObject(this.config,"baseURL").uri}get trackId(){return n.readConfObject(this.config,"trackId")}get assemblyNames(){return n.readConfObject(this.config,"assemblyNames")}mapBaseResult(e,t,n){return e.map((e=>{const a=t.getCanonicalRefName(e.refSeq);return new be.default({label:n,trackId:this.trackId,locString:`${a}:${e.min+1}..${e.max}`})}))}async searchIndex(e){const t=e.queryString,n=[],a=this.pluginManager?.rootModel?.session;if(!a)return n;const{apolloDataStore:o}=a,{assemblyManager:r}=a;for(const a of this.assemblyNames){const s=o.getBackendDriver(a),l=r.get(a);if(!s||!l)continue;const i=await s.searchFeatures(e.queryString,[a]);n.push(...this.mapBaseResult(i,l,t))}return n}freeResources(){}}var Zt=n.ConfigurationSchema("ApolloTextSearchAdapter",{assemblyNames:{type:"stringArray",defaultValue:[],description:"List of assemblies covered by text search adapter"},trackId:{type:"string",defaultValue:""},baseURL:{type:"fileLocation",defaultValue:{uri:"",locationType:"UriLocation"}}},{explicitlyTyped:!0,explicitIdentifier:"textSearchAdapterId"});const Qt=n.ConfigurationSchema("ApolloPlugin",{ontologies:i.types.array(tt),featureTypeOntologyName:{description:"Name of the feature type ontology",type:"string",defaultValue:"Sequence Ontology"}});function en(e){if("LinearPileupDisplay"!==e.name)return e;const{stateModel:n}=e,a=n.views((e=>({getFirstRegion:()=>r.getContainingView(e).dynamicBlocks.contentBlocks[0],getAssembly(){const t=e.getFirstRegion(),n=r.getSession(e),{assemblyManager:a}=n,{assemblyName:o}=t,s=a.get(o);if(!s)throw new Error(`Could not find assembly named ${o}`);return s},getRefSeqId(t){const n=e.getFirstRegion(),{refName:a}=n,{refNameAliases:o}=t;if(!o)throw new Error(`Could not find aliases for ${t.name}`);const r=[...Object.entries(o)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""}))),s=r.find((e=>e.name===a))?._id;if(!s)throw new Error(`Could not find refSeqId named ${a}`);return s},createFeature(){const t=e.contextMenuFeature,n=e.getAssembly(),a=e.getRefSeqId(n),o=(t.get("CIGAR").toUpperCase().match(/\d+\D/g)??[]).map((e=>[(/\D/.exec(e)??[])[0],Number.parseInt(e,10)]));let r=0;const s=t.get("start");let l;const i=[];for(const[e,t]of o)"M"===e||"="===e?void 0===l&&(l=r+s):"N"===e&&void 0!==l&&(i.push({start:l,end:r+l}),l=void 0),"I"!==e&&(r+=t);void 0!==l&&i.push({start:l,end:r+s});const c={_id:oe.default().toHexString(),refSeq:a,min:t.get("start"),max:t.get("end"),type:"mRNA",strand:t.get("strand")};if(0===i.length)return c;c.children={};const[u]=i,d={_id:oe.default().toHexString(),refSeq:a,min:u.start,max:u.end,type:"CDS",strand:t.get("strand")};if(c.children[d._id]=d,1===i.length){const e={_id:oe.default().toHexString(),refSeq:a,min:u.start,max:u.end,type:"exon",strand:t.get("strand")};return c.children[e._id]=e,c}for(const e of i){d.min=Math.min(d.min,e.start),d.max=Math.max(d.max,e.end);const{end:n,start:o}=e,r={_id:oe.default().toHexString(),refSeq:a,min:o,max:n,type:"exon",strand:t.get("strand")};c.children[r._id]=r}return c},async onPileupFeatureContext(){const n=e.createFeature(),a=e.getAssembly(),o=new t.AddFeatureChange({changedIds:[n._id],typeName:"AddFeatureChange",assembly:a.name,addedFeature:n}),s=r.getSession(e);await s.apolloDataStore.changeManager.submit(o),s.notify("Annotation added successfully","success")}}))).views((e=>{const t=e.contextMenuItems;return{contextMenuItems:()=>e.contextMenuFeature?[...t(),{label:"Create Apollo annotation",icon:Q.default,onClick:e.onPileupFeatureContext}]:t()}}));return e.stateModel=a,e}const tn=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=h.useState(String(t)),[r,s]=h.useState(!1),[l,i]=h.useState(null);return h.useEffect((()=>{o(String(t))}),[t]),h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),re.default.createElement(f.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{a!==String(t)&&e(a)},inputRef:e=>{i(e)}})})),nn=new Map([["Gene Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>re.default.createElement(bt,{...e,ontologyName:"Sequence Ontology"})]]),an=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"],on=w.makeStyles()((e=>({newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}})));function rn(e){const{onChange:t,value:n}=e;return re.default.createElement(tn,{value:n,onChangeCommitted:e=>{t(e.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}const sn=S.observer((function({assembly:e,editable:n,feature:a,session:o}){const[r,s]=h.useState(""),[l,c]=h.useState(!1),{classes:u}=on(),[d,m]=h.useState(""),g=Object.fromEntries([...a.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]}))),{notify:p}=o,{changeManager:y}=o.apolloDataStore;async function b(n,o){s("");const r={};if(g){const e=Object.entries({...g,[n]:o});for(const[t,n]of e)if(n&&"parent"!==t.toLowerCase())if([...nn.keys()].includes(t))r[t]=n;else switch(t){case"ID":r._id=n;break;case"Name":r.gff_name=n;break;case"Alias":r.gff_alias=n;break;case"Target":r.gff_target=n;break;case"Gap":r.gff_gap=n;break;case"Derives_from":r.gff_derives_from=n;break;case"Note":r.gff_note=n;break;case"Dbxref":r.gff_dbxref=n;break;case"Ontology_term":r.gff_ontology_term=n;break;case"Is_circular":r.gff_is_circular=n;break;default:r[t.toLowerCase()]=n}}const l=new t.FeatureAttributeChange({changedIds:[a._id],typeName:"FeatureAttributeChange",assembly:e,featureId:a._id,attributes:r});await y.submit(l),p("Feature attributes modified successfully","success")}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Attributes"),re.default.createElement(f.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{if(""===e)return null;const a=nn.get(e)??rn;return re.default.createElement(f.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},re.default.createElement(f.Grid,{item:!0,xs:"auto"},re.default.createElement(f.Paper,{variant:"outlined",className:u.attributeName},re.default.createElement(f.Typography,null,e))),re.default.createElement(f.Grid,{item:!0,flexGrow:1},re.default.createElement(a,{session:o,value:t,onChange:t=>b(e,t)})),re.default.createElement(f.Grid,{item:!0,xs:1},re.default.createElement(f.IconButton,{"aria-label":"delete",size:"medium",disabled:!n,onClick:()=>b(e)},re.default.createElement(fe.default,{fontSize:"medium",key:e}))))})),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Button,{color:"primary",variant:"contained",disabled:l||!n,onClick:()=>{c(!0)}},"Add new")),l?re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Paper,{elevation:8,className:u.newAttributePaper},re.default.createElement(f.Grid,{container:!0,direction:"column"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.FormControl,null,re.default.createElement(f.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),re.default.createElement(f.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?m(""):nn.has(t)?m(t):s("Unknown attribute type")}},re.default.createElement(f.FormControlLabel,{value:"custom",control:re.default.createElement(f.Radio,null),disableTypography:!0,label:re.default.createElement(f.Grid,{container:!0,spacing:1,alignItems:"center"},re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.Typography,null,"Custom")),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.TextField,{label:"Custom attribute key",variant:"outlined",value:nn.has(d)?"":d,disabled:nn.has(d),onChange:e=>{m(e.target.value)}})))}),[...nn.keys()].map((e=>re.default.createElement(f.FormControlLabel,{key:e,value:e,control:re.default.createElement(f.Radio,null),label:e})))))),re.default.createElement(f.Grid,{item:!0},re.default.createElement(f.DialogActions,null,re.default.createElement(f.Button,{key:"addButton",color:"primary",variant:"contained",onClick:function(){s(""),0!==d.trim().length?"Parent"!==d?d in g?s(`Attribute "${d}" already exists`):!/^[A-Z]/.test(d)||an.includes(d)||[...nn.keys()].includes(d)?b(d,[]):s(`Key cannot starts with uppercase letter unless key is one of these: ${an.join(", ")}`):s('"Parent" -key is handled internally and it cannot be modified manually'):s("Attribute key is mandatory")},disabled:!d},"Add"),re.default.createElement(f.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{c(!1),m(""),s("")}},"Cancel")))))):null),r?re.default.createElement(f.Typography,{color:"error"},r):null)})),ln=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=h.useState(String(t)),[r,s]=h.useState(!1),[l,i]=h.useState(null);h.useEffect((()=>{o(String(t))}),[t]),h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]);const c=Number.isNaN(Number(a));return re.default.createElement(f.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{const n=Number(a);a!==String(t)&&(Number.isNaN(n)?o(String(t)):e(n))},inputRef:e=>{i(e)},error:c,helperText:c?"Not a valid number":void 0})})),cn=S.observer((function({assembly:e,feature:n,session:a}){const[o,r]=h.useState(""),[s,l]=h.useState(""),{_id:i,assemblyId:c,max:u,min:d,strand:m,type:g}=n,p=e=>{a.notify(e.message,"error")},{changeManager:y}=a.apolloDataStore;function b(n){const{value:a}=n.target,o=a?Number(a):void 0,r=new t.StrandChange({typeName:"StrandChange",changedIds:[i],featureId:i,oldStrand:m,newStrand:o,assembly:e});return y.submit(r)}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Basic information"),re.default.createElement(ln,{margin:"dense",id:"start",label:"Start",fullWidth:!0,variant:"outlined",value:d+1,onChangeCommitted:function(n){n--;const a=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[i],featureId:i,oldStart:d,newStart:n,assembly:e});return y.submit(a)}}),re.default.createElement(ln,{margin:"dense",id:"end",label:"End",fullWidth:!0,variant:"outlined",value:u,onChangeCommitted:function(n){const a=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[i],featureId:i,oldEnd:u,newEnd:n,assembly:e});return y.submit(a)}}),re.default.createElement(rt,{session:a,ontologyName:"Sequence Ontology",value:g,filterTerms:nt,fetchValidTerms:async function(e,t,n){const a=await ot(e,t);if(a)return a;l(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,n),renderInput:e=>re.default.createElement(f.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(s),helperText:s}),onChange:(e,n)=>{n&&function(e){r("");const n=new t.TypeChange({typeName:"TypeChange",changedIds:[i],featureId:i,oldType:g,newType:e,assembly:c});return y.submit(n)}(n).catch(p)}}),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"1",checked:1===m,onChange:b}),"Positive Strand (+)"),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"-1",checked:-1===m,onChange:b}),"Negative Strand (-)"),re.default.createElement("label",null,re.default.createElement("input",{type:"radio",value:"",checked:void 0===m,onChange:b}),"No Strand Information"),o?re.default.createElement(f.Typography,{color:"error"},o):null)})),un=w.makeStyles()({sequence:{width:"100%",resize:"vertical"}}),dn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const o=a.apolloDataStore.assemblies.get(e),[r,s]=h.useState(!1),{classes:l}=un();if(!t||!o)return null;const i=o.getByRefName(n);if(!i)return null;const{max:c,min:u}=t;let d="";return r&&(d=i.getSequence(u,c),d?d=function(e,t,n,a,o){return`>${t}:${n+1}–${a}\n${e}`}(d,n,u,c):a.apolloDataStore.loadRefSeq([{assemblyName:e,refName:n,start:u,end:c}])),re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Sequence"),re.default.createElement(f.Button,{variant:"contained",onClick:()=>{s(!r)}},r?"Hide sequence":"Show sequence"),re.default.createElement("div",null,r&&re.default.createElement("textarea",{readOnly:!0,rows:20,className:l.sequence,value:d})))})),fn=w.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),mn=S.observer((function(e){const{model:t}=e,{assembly:n,feature:a,refName:o}=t,s=r.getSession(t),l=s.apolloDataStore.assemblies.get(n),{classes:i}=fn();if(!a||!l)return null;const c=l.getByRefName(o);if(!c)return null;const{max:u,min:d}=a;return c.getSequence(d,u)||s.apolloDataStore.loadRefSeq([{assemblyName:n,refName:o,start:d,end:u}]),re.default.createElement("div",{className:i.root},re.default.createElement(cn,{feature:a,session:s,assembly:l._id}),re.default.createElement("hr",null),re.default.createElement(sn,{feature:a,session:s,assembly:l._id,editable:!0}),re.default.createElement("hr",null),re.default.createElement(dn,{feature:a,session:s,assembly:l._id,refName:o}))})),gn=i.types.model("ApolloFeatureDetailsWidget",{id:v.ElementId,type:i.types.literal("ApolloFeatureDetailsWidget"),feature:i.types.maybe(i.types.reference($.AnnotationFeatureModel,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}}))),pn=i.types.model("ApolloTranscriptDetails",{id:v.ElementId,type:i.types.literal("ApolloTranscriptDetails"),feature:i.types.maybe(i.types.reference($.AnnotationFeatureModel,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string,changeManager:i.types.frozen()}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}}))),hn=S.observer((function({assembly:e,feature:n,refName:a,session:o}){const{notify:s}=o,l=o.apolloDataStore.assemblies.get(e),i=l?.getByRefName(a),{changeManager:c}=o.apolloDataStore,u=f.useTheme();function d(n,a,o,r){if(!o.children)throw new Error("Transcript should have child features");for(const[,l]of o.children){if(r&&n-1===l.min){const r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[l._id],featureId:o._id,oldStart:n-1,newStart:a-1,assembly:e});return void c.submit(r).catch((()=>{s("Error updating feature start position","error")}))}if(!r&&a===l.max){const n=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[l._id],featureId:o._id,oldEnd:l.max,newEnd:a,assembly:e});return void c.submit(n).catch((()=>{s("Error updating feature start position","error")}))}}}if(!i)return null;const{strand:m,transcriptParts:g}=n,[p]=g,h=p.map(((e,t)=>{const{max:n,min:a,type:o}=e;let s,l,c,d=o;if("threePrimeUTR"===d?d="3` UTR":"fivePrimeUTR"===d&&(d="5` UTR"),"CDS"===o){const{phase:o}=e,d=r.getFrame(a,n,m??1,o);c=u.palette.framesCDS.at(d)?.main;const f=p.at(t-1),g=p.at(t+1);1===m?("intron"===f?.type&&(s=i.getSequence(a-2,a)),"intron"===g?.type&&(l=i.getSequence(n,n+2))):("intron"===f?.type&&(s=r.revcom(i.getSequence(n,n+2))),"intron"===g?.type&&(l=r.revcom(i.getSequence(a-2,a))))}return{min:a,max:n,label:d,fivePrimeSpliceSite:s,threePrimeSpliceSite:l,frameColor:c}})).filter((e=>"intron"!==e.label));return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Structure"),re.default.createElement(f.Typography,{variant:"h6"},1===m?"Forward":"Reverse"," strand"),re.default.createElement(f.TableContainer,{component:f.Paper},re.default.createElement(f.Table,{size:"small"},re.default.createElement(f.TableBody,null,h.map((e=>re.default.createElement(f.TableRow,{key:`${e.label}:${e.min}-${e.max}`},re.default.createElement(f.TableCell,{component:"th",scope:"row",style:{background:e.frameColor}},e.label),re.default.createElement(f.TableCell,null,e.fivePrimeSpliceSite??""),re.default.createElement(f.TableCell,{padding:"none"},re.default.createElement(ln,{margin:"dense",variant:"outlined",value:1===m?e.min+1:e.max,onChangeCommitted:t=>{d(1===m?e.min+1:e.max,t,n,1===m)}})),re.default.createElement(f.TableCell,{padding:"none"},re.default.createElement(ln,{margin:"dense",variant:"outlined",value:1===m?e.max:e.min+1,onChangeCommitted:t=>{d(1===m?e.max:e.min+1,t,n,1!==m)}})),re.default.createElement(f.TableCell,null,e.threePrimeSpliceSite??""))))))))})),yn=60;function bn(e){switch(e){case"upOrDownstream":return"rgb(255,255,255)";case"UTR":return"rgb(194,106,119)";case"CDS":return"rgb(93,168,153)";case"intron":return"rgb(187,187,187)";case"protein":return"rgb(148,203,236)"}}const Sn=S.observer((function({assembly:e,feature:n,refName:a,session:o}){const s=o.apolloDataStore.assemblies.get(e),l=s?.getByRefName(a),[i,c]=h.useState(!1),[u,d]=h.useState("CDS"),m=f.useTheme(),g=h.useRef(null);if(!s||!l)return null;const p=s.getByRefName(a);if(!p)return null;if("mRNA"!==n.type)return null;const y=i?function(e,n,a){const o=[],{cdsLocations:s,strand:l,transcriptParts:i}=n;switch(e){case"genomic":case"cDNA":{const[n]=i;for(const s of n){if("cDNA"===e&&"intron"===s.type)continue;let n=a(s.min,s.max);-1===l&&(n=r.revcom(n));const i="fivePrimeUTR"===s.type||"threePrimeUTR"===s.type?"UTR":s.type,c=o.at(-1);if(c)if(c.type===i){const[e,...a]=c.sequenceLines,o=a.join("")+n;c.sequenceLines=[e,...t.splitStringIntoChunks(o,yn)],c.locs.push({min:s.min,max:s.max})}else{const e=o.reduce(((e,t)=>e+t.sequenceLines.reduce(((e,t)=>e+t.length),0)),0),a=yn-e%yn,r=n.slice(0,a),l=t.splitStringIntoChunks(n.slice(a),yn);o.push({type:i,sequenceLines:[r,...l],locs:[{min:s.min,max:s.max}]})}else{const e=t.splitStringIntoChunks(n,yn);o.push({type:i,sequenceLines:e,locs:[{min:s.min,max:s.max}]})}}return o}case"CDS":{let e="";const[n]=s,i=[];for(const t of n){let n=a(t.min,t.max);-1===l&&(n=r.revcom(n)),e+=n,i.push({min:t.min,max:t.max})}const c=t.splitStringIntoChunks(e,yn);return o.push({type:"CDS",sequenceLines:c,locs:i}),o}}}(u,n,((e,t)=>l.getSequence(e,t))):[],b=[];if(i){const e=y.flatMap((e=>e.locs));let[t]=e;for(let n=1;n<e.length;n++)t.min===e[n].max||t.max===e[n].min?t={min:Math.min(t.min,e[n].min),max:Math.max(t.max,e[n].max)}:(b.push(t),t=e[n]);b.push(t)}return re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Typography,{variant:"h5"},"Sequence"),re.default.createElement("div",null,re.default.createElement(f.Button,{variant:"contained",onClick:()=>{c(!i)}},i?"Hide sequence":"Show sequence")),i&&re.default.createElement(re.default.Fragment,null,re.default.createElement(f.Select,{defaultValue:"CDS",value:u,onChange:function(e){d(e.target.value)}},re.default.createElement(f.MenuItem,{value:"CDS"},"CDS"),re.default.createElement(f.MenuItem,{value:"cDNA"},"cDNA"),re.default.createElement(f.MenuItem,{value:"genomic"},"Genomic")),re.default.createElement(f.Paper,{style:{fontFamily:"monospace",padding:m.spacing(),overflowX:"auto"},ref:g},">",p.name,":",b.map((e=>1===n.strand?`${e.min+1}-${e.max}`:`${e.max}-${e.min+1}`)).join(";"),"(",1===n.strand?"+":"-",")",re.default.createElement("br",null),y.map(((e,t)=>re.default.createElement("span",{key:`${e.type}-${t}`,style:{background:bn(e.type),color:m.palette.getContrastText(bn(e.type))}},e.sequenceLines.map(((t,n)=>re.default.createElement(re.default.Fragment,{key:`${t.slice(0,5)}-${n}`},t,n===e.sequenceLines.length-1&&t.length!==yn?null:re.default.createElement("br",null)))))))),re.default.createElement(f.Button,{variant:"contained",onClick:()=>{const e=g.current;if(!e)return;const t=new Blob([e.outerText],{type:"text/plain"}),n=new Blob([e.outerHTML],{type:"text/html"}),a=new ClipboardItem({[t.type]:t,[n.type]:n});navigator.clipboard.write([a])}},"Copy sequence")))})),wn=w.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),vn=S.observer((function(e){const{classes:t}=wn(),{model:n}=e,{assembly:a,feature:o,refName:s}=n,l=r.getSession(n),c=r.getSession(n),u=c.apolloDataStore.assemblies.get(a),{internetAccounts:d}=i.getRoot(l),f=d.find((e=>"ApolloInternetAccount"===e.type)),m=["admin","user"].includes((f?f.role:"admin")??"");if(!o||!u)return null;const g=u.getByRefName(s);if(!g)return null;const{max:p,min:h}=o;return g.getSequence(h,p)||c.apolloDataStore.loadRefSeq([{assemblyName:a,refName:s,start:h,end:p}]),re.default.createElement("div",{className:t.root},re.default.createElement(hn,{feature:o,session:c,assembly:u._id||"",refName:s}),re.default.createElement("hr",null),re.default.createElement(sn,{feature:o,session:c,assembly:u._id||"",editable:m}),re.default.createElement("hr",null),re.default.createElement(Sn,{feature:o,session:c,assembly:u._id||"",refName:s}))})),Cn=n.ConfigurationSchema("LinearApolloDisplay",{},{explicitIdentifier:"displayId",explicitlyTyped:!0}),En=w.makeStyles()({highlighted:{background:"orange"}}),xn=({highlight:e,text:t})=>{const{classes:n}=En();if(!e)return re.default.createElement(re.default.Fragment,null,t);const a=t.split(e);if(1===a.length)return re.default.createElement(re.default.Fragment,null,t);const o=[];for(let t=0;t<a.length-1;t++)o.push(a[t],re.default.createElement("span",{className:n.highlighted},e));return re.default.createElement(re.default.Fragment,null,o,a.at(-1))},An=S.observer((function({feature:e,filterText:t}){const n=[...e.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})).filter((([e])=>e)).map((([e,t])=>`${e}=${Array.isArray(t)?t.join(", "):t}`)).join(", ");return re.default.createElement(xn,{text:n,highlight:t})})),Tn=w.makeStyles()((e=>({inputWrapper:{position:"relative"},hiddenWidthSpan:{padding:e.spacing(.5),color:"transparent"},numberTextInput:{border:"none",background:"inherit",font:"inherit",position:"absolute",width:"100%",left:0}}))),kn=S.observer((function({initialValue:e,notifyError:t,onChangeCommitted:n}){const[a,o]=h.useState(e),[r,s]=h.useState(!1),[l,i]=h.useState(null),{classes:c}=Tn();return h.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),re.default.createElement("span",{className:c.inputWrapper},re.default.createElement("span",{className:c.hiddenWidthSpan,"aria-hidden":!0},a),re.default.createElement("input",{type:"text",value:a,className:c.numberTextInput,onChange:function(e){const t=Number(e.target.value);Number.isNaN(t)||o(t)},onKeyDown:t=>{"Enter"===t.key?l?.blur():"Escape"===t.key&&(o(e),s(!0))},onBlur:()=>{a!==e&&n(a).catch(t)},ref:e=>{i(e)}}))}));function Nn(e,t){return t?.palette.bases[e.toUpperCase()].main.toString()??"lightgray"}function Rn(e,t,n,a,o){const r=Math.min(n,10);e.fillStyle="#000",e.font=`${r}px`;const s=e.measureText(a).width;e.fillText(a,t+(n-s)/2,o+10)}function Dn(e,t,n,a,o,s,l,i,c){let u=l.slice(i,i+3).toUpperCase();c&&(u=function(e){return[...e].map((e=>r.revcom(e))).reverse().join("")}(u));const d=r.defaultCodonTable[u];if(!d)return;const f={M:"#33ee33","*":"#f44336"}[d.toUpperCase()];f&&(e.fillStyle=f,e.fillRect(n,a,o,s)),t<=.1&&(e.rect(n,a,o,s),e.stroke(),Rn(e,n,o,d,a))}function Fn(e){return"featureAndGlyphUnderMouse"in e}function Mn(e,t){const n=t<=1?2:0;switch(e){case 3:return 0;case 2:return 1;case 1:return 2;case-1:return 3+n;case-2:return 4+n;case-3:return 5+n}}function In(e,t){if(!(t>1||void 0===e))return 1===e?3:4}function Ln(e,t,n,a,o,r){void 0!==o&&(e.fillStyle=t?.palette.action.focus??"rgba(0,0,0,0.04)",e.fillRect(n,a*o,r,a))}function qn(e,t){return Boolean(t&&e._id===t._id)}function Pn(e,t){return t?e?.palette.text.primary??"black":e?.palette.background.default??"white"}function Un(e,t,n,a,o,r){e.fillStyle=r,e.fillRect(t,n,a,o)}function Bn(e,t,n){const{refName:a,regionNumber:o,x:r}=e,{lgv:s}=n,{offsetPx:l}=s,i=s.bpToPx({refName:a,coord:t.min,regionNumber:o}),c=s.bpToPx({refName:a,coord:t.max,regionNumber:o});if(void 0!==i&&void 0!==c){const e=i.offsetPx-l,t=c.offsetPx-l;if(Math.abs(t-e)<8)return;if(Math.abs(e-r)<4)return"min";if(Math.abs(t-r)<4)return"max"}}const _n={draw:function(e,t,n,a,o){const{apolloRowHeight:r,lgv:s,session:l,theme:i}=a,{bpPerPx:c,displayedRegions:u,offsetPx:d}=s,f=u[o],m=(s.bpToPx({refName:f.refName,coord:t.min,regionNumber:o})?.offsetPx??0)-d,{reversed:g}=f,{apolloSelectedFeature:p}=l,h=t.length/c,y=g?m-h:m,b=n*r,S=qn(t,p),w=Pn(i,S),v=function(e,t){return t?e?.palette.getContrastText(Pn(e,t))??"white":e?.palette.text.primary??"black"}(i,S);!function(e,t,n,a,o,r){Un(e,t,n,a,o,r),a<=2||e.clearRect(t+1,n+1,a-2,o-2)}(e,y,b,h,r,v),h<=2||(function(e,t,n,a,o,r){Un(e,t+1,n+1,a-2,o-2,r)}(e,y,b,h,r,w),function(e,t,n,a,o,r){e.fillStyle=o;const s=Math.max(t+1,0);e.fillText(r,s,n+11,t-1+a-s)}(e,y,b,h,v,t.type))},drawDragPreview:function(e,t){const{apolloDragging:n,apolloRowHeight:a,lgv:o,theme:r}=e,{bpPerPx:s,displayedRegions:l,offsetPx:i}=o;if(!n)return;const{current:c,edge:u,feature:d,start:m}=n,g=Math.floor(m.y/a),p=l[m.regionNumber],h=(p.reversed?p.end-d[u]:d[u]-p.start)/s-i,y=Math.min(c.x,h),b=g*a,S=Math.abs(c.x-h),w=1*a;t.strokeStyle=r?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(y,b,S,w),t.fillStyle=f.alpha(r?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(y,b,S,w)},drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{bpPerPx:i,displayedRegions:c,offsetPx:u}=o,{layoutIndex:d,layoutRow:f}=l,m=c[d],{refName:g,reversed:p}=m,{length:h,max:y,min:b}=s,S=(o.bpToPx({refName:g,coord:p?y:b,regionNumber:d})?.offsetPx??0)-u,w=f*a,v=h/i;t.fillStyle=r?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(S,w,v,a)},drawTooltip:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{featureRow:i,layoutIndex:c,layoutRow:u}=l,{bpPerPx:d,displayedRegions:m,offsetPx:g}=o,p=m[c],{refName:h,reversed:y}=p;let b="Loc: ";const{length:S,max:w,min:v}=s;b+=`${v+1}–${w}`;let C=(o.bpToPx({refName:h,coord:y?w:v,regionNumber:c})?.offsetPx??0)-g;const E=(u+i)*a,x=S/d,A=`Type: ${s.type}`,{attributes:T}=s,k=T.get("gff_name")?.find((e=>""!==e)),N=[t.measureText(A).width,t.measureText(b).width];k&&N.push(t.measureText(`Name: ${k}`).width);const R=Math.max(...N);C=C+x+5,t.fillStyle=f.alpha(r?.palette.text.primary??"rgb(1, 1, 1)",.7),t.fillRect(C,E,R+4,3===N.length?45:35),t.beginPath(),t.moveTo(C,E),t.lineTo(C-5,E+5),t.lineTo(C,E+10),t.fill(),t.fillStyle=r?.palette.background.default??"rgba(255, 255, 255)";let D=E+12;t.fillText(A,C+2,D),k&&(D+=12,t.fillText(`Name: ${k}`,C+2,D)),D+=12,t.fillText(b,C+2,D)},getContextMenuItems:function(e){const{apolloHover:t,apolloInternetAccount:n,changeManager:a,regions:o,selectedFeature:s,session:l}=e,i=[];if(!t)return i;const{feature:c}=t,u=n?n.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),[m]=o,g=e.getAssemblyId(m.assemblyName),p=e.getAssemblyId(m.assemblyName);return i.push({label:"Add child feature",disabled:f,onClick:()=>{l.queueDialog((e=>[st,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:g,internetAccount:n}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{l.queueDialog((e=>[ct,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:p}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{l.queueDialog((t=>[dt,{session:l,handleClose:()=>{t()},changeManager:a,sourceFeature:c,sourceAssemblyId:p,selectedFeature:s,setSelectedFeature:t=>{e.setSelectedFeature(t)}}]))}},{label:"Modify feature attribute",disabled:f,onClick:()=>{l.queueDialog((e=>[At,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:p}]))}},{label:"Edit feature details",onClick:()=>{const e=l.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:c,assembly:p,refName:m.refName});l.showWidget(e)}}),"mRNA"===c.type&&r.isSessionModelWithWidgets(l)&&i.push({label:"Edit transcript details",onClick:()=>{const e=l.addWidget("ApolloTranscriptDetails","apolloTranscriptDetails",{feature:c,assembly:p,changeManager:a,refName:m.refName});l.showWidget(e)}}),i},getFeatureFromLayout:function(e,t,n){return e},getRowCount:function(e){return 1},getRowForFeature:function(e,t){return 0},onMouseDown:function(e,t,n){const{featureAndGlyphUnderMouse:a}=t,{feature:o}=a,r=Bn(t,o,e);r&&(n.stopPropagation(),e.startDrag(t,o,r))},onMouseLeave:function(){},onMouseMove:function(e,t){if(Fn(t)){const{featureAndGlyphUnderMouse:n}=t;e.setApolloHover(n);const{feature:a}=n;if(Bn(t,a,e))return void e.setCursor("col-resize")}e.setCursor()},onMouseUp:function(e,t){if(e.apolloDragging)return;const{featureAndGlyphUnderMouse:n}=t;n?.feature&&e.setSelectedFeature(n.feature)}};let jn=null,On=null,$n=null,Gn=null;if("document"in globalThis)for(const e of["forward","backward"])for(const t of["light","dark"]){const n=document.createElement("canvas"),a=10;n.width=n.height=a;const o=n.getContext("2d");if(o){const r="light"===t?"rgba(0,0,0,0)":"rgba(0,0,0,0.75)",s="light"===t?"rgba(255,255,255,0.25)":"rgba(0,0,0,0.50)",l="forward"===e?o.createLinearGradient(0,a,a,0):o.createLinearGradient(0,0,a,a);l.addColorStop(0,r),l.addColorStop(.25,r),l.addColorStop(.25,s),l.addColorStop(.5,s),l.addColorStop(.5,r),l.addColorStop(.75,r),l.addColorStop(.75,s),l.addColorStop(1,s),o.fillStyle=l,o.fillRect(0,0,10,10),"forward"===e?"light"===t?jn=o.createPattern(n,"repeat"):$n=o.createPattern(n,"repeat"):"light"===t?On=o.createPattern(n,"repeat"):Gn=o.createPattern(n,"repeat")}}function Wn(e,t){const{children:n,type:a}=e;if(!n)return 1;let o=0;if("mRNA"===a){for(const[,e]of n)"CDS"===e.type&&(o+=1);return o}for(const[,e]of n)o+=Wn(e);return o}function Hn(e){if("gene"!==e.type)throw new Error('Top level feature for GeneGlyph must have type "gene"');const{children:t}=e;if(!t)return[[e]];const n=[];for(const[,a]of t){if("mRNA"!==a.type){n.push([a,e]);continue}if(!a.children)continue;const t=[],o=[];for(const[,e]of a.children)"CDS"===e.type?t.push(e):"exon"===e.type&&o.push(e);for(const r of t)n.push([r,...o,a,e])}return n}function zn(e,t,n){if("gene"===t.type||"mRNA"===t.type)return;const{bp:a,refName:o,regionNumber:s,x:l}=e,{lgv:i}=n,{offsetPx:c}=i,u=i.bpToPx({refName:o,coord:t.min,regionNumber:s}),d=i.bpToPx({refName:o,coord:t.max,regionNumber:s});if(void 0===u||void 0===d)return;const f=u.offsetPx-c,m=d.offsetPx-c;if(!(Math.abs(m-f)<8)){if(Math.abs(f-l)<4)return{feature:t,edge:"min"};if(Math.abs(m-l)<4)return{feature:t,edge:"max"};if("CDS"===t.type){const e=t.parent;if(!e?.children)return;const n=[...e.children.values()].filter((e=>"exon"===e.type)).find((e=>{const[t,n]=r.intersection2(a,a+1,e.min,e.max);return void 0!==t&&void 0!==n}));if(!n)return;const u=i.bpToPx({refName:o,coord:n.min,regionNumber:s}),d=i.bpToPx({refName:o,coord:n.max,regionNumber:s});if(void 0===u||void 0===d)return;const f=u.offsetPx-c,m=d.offsetPx-c;if(Math.abs(m-f)<8)return;if(Math.abs(f-l)<4)return{feature:n,edge:"min"};if(Math.abs(m-l)<4)return{feature:n,edge:"max"}}}}const{drawTooltip:Vn,getContextMenuItems:Jn,onMouseLeave:Xn}=_n,Yn={draw:function(e,t,n,a,o){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=a,{bpPerPx:u,displayedRegions:d,offsetPx:m}=l,g=d[o],{refName:p,reversed:h}=g,y=s,b=Math.round(.6*y),S=Math.round(.9*y),{children:w,min:v,strand:C}=t;if(!w)return;const{apolloSelectedFeature:E}=i,x=(l.bpToPx({refName:p,coord:v,regionNumber:o})?.offsetPx??0)-m,A=t.length/u,T=h?x-A:x,k=n*y,N=Wn(t)*y;e.fillStyle=f.alpha(c?.palette.background.paper??"#ffffff",.6),e.fillRect(T,k,A,N);let R=0;for(const[,t]of w){if("mRNA"!==t.type){R+=1;continue}const{children:a,min:r}=t;if(a)for(const[,s]of a){if("CDS"!==s.type)continue;const a=(l.bpToPx({refName:p,coord:r,regionNumber:o})?.offsetPx??0)-m,i=t.length/u,d=h?a-i:a,f=Math.round((R+.5)*y)+n*y;e.strokeStyle=c?.palette.text.primary??"black",e.beginPath(),e.moveTo(d,f),e.lineTo(d+i,f),e.stroke(),R+=1}}const D="dark"===c?.palette.mode?$n:jn,F="dark"===c?.palette.mode?Gn:On;R=0;for(const[,t]of w)if("mRNA"===t.type)for(const a of t.cdsLocations){const{_id:s,children:i}=t;if(i){for(const[,t]of i){if("exon"!==t.type)continue;const a=(l.bpToPx({refName:p,coord:t.min,regionNumber:o})?.offsetPx??0)-m,r=t.length/u,s=h?a-r:a,i=(n+R)*y+(y-b)/2;if(e.fillStyle=c?.palette.text.primary??"black",e.fillRect(s,i,r,b),r>2&&(e.clearRect(s+1,i+1,r-2,b-2),e.fillStyle=E&&t._id===E._id?"rgb(0,0,0)":"rgb(211,211,211)",e.fillRect(s+1,i+1,r-2,b-2),D&&F&&C)){const t=h?-1:1,[n,a]=C*t==1?[D,F]:[F,D];e.fillStyle=n,e.fillRect(s+1,i+1,r-2,(b-2)/2),e.fillStyle=a,e.fillRect(s+1,i+1+(b-2)/2,r-2,(b-2)/2)}}for(const i of a){const a=(i.max-i.min)/u,d=(l.bpToPx({refName:p,coord:i.min,regionNumber:o})?.offsetPx??0)-m,f=h?d-a:d;e.fillStyle=c?.palette.text.primary??"black";const g=(n+R)*y+(y-S)/2;if(e.fillRect(f,g,a,S),a>2){e.clearRect(f+1,g+1,a-2,S-2);const n=r.getFrame(i.min,i.max,t.strand??1,i.phase),o=c?.palette.framesCDS.at(n)?.main,l=o??"rgb(171,71,188)";if(e.fillStyle=E&&s===E._id?"rgb(0,0,0)":l,e.fillStyle=l,e.fillRect(f+1,g+1,a-2,S-2),D&&F&&C){const t=h?-1:1,[n,o]=C*t==1?[D,F]:[F,D];e.fillStyle=n,e.fillRect(f+1,g+1,a-2,(S-2)/2),e.fillStyle=o,e.fillRect(f+1,g+(S-2)/2,a-2,(S-2)/2)}}}R+=1}}else _n.draw(e,t,n,a,o),R+=1},drawDragPreview:function(e,t){const{apolloDragging:n,apolloRowHeight:a,lgv:o,theme:r}=e,{bpPerPx:s,displayedRegions:l,offsetPx:i}=o;if(!n)return;const{current:c,edge:u,feature:d,start:m}=n,g=Math.floor(m.y/a),p=l[m.regionNumber],h=(p.reversed?p.end-d[u]:d[u]-p.start)/s-i,y=Math.min(c.x,h),b=g*a,S=Math.abs(c.x-h),w=1*a;t.strokeStyle=r?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(y,b,S,w),t.fillStyle=f.alpha(r?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(y,b,S,w)},drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o,theme:r}=e;if(!n)return;const{feature:s}=n,l=e.getFeatureLayoutPosition(s);if(!l)return;const{bpPerPx:i,displayedRegions:c,offsetPx:u}=o,{featureRow:d,layoutIndex:f,layoutRow:m}=l,g=c[f],{refName:p,reversed:h}=g,{length:y,max:b,min:S}=s,w=(o.bpToPx({refName:p,coord:h?b:S,regionNumber:f})?.offsetPx??0)-u,v=(m+d)*a,C=y/i;t.fillStyle=r?.palette.action.selected??"rgba(0,0,0,04)",t.fillRect(w,v,C,a*Wn(s))},drawTooltip:Vn,getContextMenuItems:Jn,getFeatureFromLayout:function(e,t,n){const a=Hn(e)[n]||[];for(const e of a){let n;if(t>=e.min&&t<=e.max&&e.parent&&(n=e),n){if("CDS"===n.type&&n.parent&&"mRNA"===n.parent.type){const{cdsLocations:e}=n.parent;for(const a of e)for(const e of a)if(t>=e.min&&t<=e.max)return n;return n.parent}return n}}return e},getRowCount:Wn,getRowForFeature:function(e,t){const n=Hn(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e},onMouseDown:function(e,t,n){const{featureAndGlyphUnderMouse:a}=t,{feature:o}=a,r=zn(t,o,e);r&&(n.stopPropagation(),e.startDrag(t,r.feature,r.edge))},onMouseLeave:Xn,onMouseMove:function(e,t){if(Fn(t)){const{featureAndGlyphUnderMouse:n}=t;e.setApolloHover(n);const{feature:a}=n;if(zn(t,a,e))return void e.setCursor("col-resize")}e.setCursor()},onMouseUp:function(e,t){if(e.apolloDragging)return;const{featureAndGlyphUnderMouse:n}=t;n?.feature&&e.setSelectedFeature(n.feature)}};function Kn(e){const t=[[e]];if(e.children)for(const[,n]of e.children)t.push(...Kn(n));return t}function Zn(e){return Kn(e).length}function Qn(e,t,n,a,o,r){const s=Kn(t)[n-a];for(const t of s)ea(e,t,n,o,r)}function ea(e,t,n,a,o){const{apolloRowHeight:r,lgv:s,session:l}=a,{bpPerPx:i,displayedRegions:c,offsetPx:u}=s,d=c[o],f=(s.bpToPx({refName:d.refName,coord:t.min,regionNumber:o})?.offsetPx??0)-u,{reversed:m}=d,{apolloSelectedFeature:g}=l,p=t.length/i,h=m?f-p:f,y=n*r,b=Zn(t),S=qn(t,g);b>1&&Un(e,h,y,p,b*r,S?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)"),_n.draw(e,t,n,a,o)}const{drawDragPreview:ta,drawTooltip:na,getContextMenuItems:aa,onMouseDown:oa,onMouseLeave:ra,onMouseMove:sa,onMouseUp:la}=_n,ia={draw:function(e,t,n,a,o){for(let r=0;r<Zn(t);r++)Qn(e,t,n+r,n,a,o)},drawDragPreview:ta,drawHover:function(e,t){const{apolloHover:n,apolloRowHeight:a,lgv:o}=e;if(!n)return;const{feature:r}=n,s=e.getFeatureLayoutPosition(r);if(!s)return;const{featureRow:l,layoutIndex:i,layoutRow:c}=s,{bpPerPx:u,displayedRegions:d,offsetPx:f}=o,m=d[i],{refName:g,reversed:p}=m,{length:h,max:y,min:b}=r,S=(o.bpToPx({refName:g,coord:p?y:b,regionNumber:i})?.offsetPx??0)-f,w=(c+l)*a,v=h/u;t.fillStyle="rgba(0,0,0,0.2)",t.fillRect(S,w,v,a*Zn(r))},drawTooltip:na,getContextMenuItems:aa,getFeatureFromLayout:function(e,t,n){return Kn(e)[n].find((e=>t>=e.min&&t<=e.max))},getRowCount:Zn,getRowForFeature:function(e,t){const n=Kn(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e},onMouseDown:oa,onMouseLeave:ra,onMouseMove:sa,onMouseUp:la};function ca(e){return function(e){const{children:t}=e;if(!t?.size)return!1;for(const[,e]of t)if("mRNA"===e.type){const{children:t}=e;if(!t?.size)return!1;const n=[...t.values()].some((e=>"CDS"===e.type)),a=[...t.values()].some((e=>"exon"===e.type));if(n&&a)return!0}return!1}(e)?Yn:e.children?.size?ia:_n}const ua=w.makeStyles()((e=>({typeContent:{display:"inline-block",width:"174px",height:"100%",cursor:"text"},feature:{td:{position:"relative",verticalAlign:"top",paddingLeft:"0.5em"}},arrow:{display:"inline-block",width:"1.6em",textAlign:"center",cursor:"pointer"},arrowExpanded:{transform:"rotate(90deg)"},hoveredFeature:{backgroundColor:e.palette.action.hover},typeInputElement:{border:"none",background:"none"},typeErrorMessage:{color:"red"}})));function da(e,t){const{changeManager:n,getAssemblyId:a,regions:o,selectedFeature:s,session:l,setSelectedFeature:c}=e;return function(e,t,n,a,o,s,l){const c=function(e){const{internetAccounts:t}=i.getParent(e);return t.find((e=>"ApolloInternetAccount"===e.type))}(s),u=c?c.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),m=[];if(e){const i=n(t.assemblyName),u=n(t.assemblyName);m.push({label:"Edit feature details",onClick:()=>{const n=s.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:e,assembly:u,refName:t.refName});s.showWidget(n)}},{label:"Add child feature",disabled:f,onClick:()=>{s.queueDialog((t=>[st,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:i,internetAccount:c}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{s.queueDialog((t=>[ct,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{s.queueDialog((t=>[dt,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u,selectedFeature:a,setSelectedFeature:o}]))}},{label:"Edit attributes",disabled:f,onClick:()=>{s.queueDialog((t=>[At,{session:s,handleClose:()=>{t()},changeManager:l,sourceFeature:e,sourceAssemblyId:u}]))}}),"mRNA"===e.type&&r.isSessionModelWithWidgets(s)&&m.push({label:"Edit transcript details",onClick:()=>{const n=s.addWidget("ApolloTranscriptDetails","apolloTranscriptDetails",{feature:e,assembly:u,changeManager:l,refName:t.refName});s.showWidget(n)}})}return m}(t,o[0],a,s,c,l,n)}function fa(e){let t=e;for(;t.parent;)t=t.parent;return t}const ma=S.observer((function e({depth:n,feature:a,isHovered:o,isSelected:r,model:s,selectedFeatureClass:l,setContextMenu:i}){const{classes:c}=ua(),{apolloHover:u,changeManager:d,selectedFeature:f,session:m,tabularEditor:g}=s,{featureCollapsed:p,filterText:h}=g,{_id:y,children:b,max:S,min:w,strand:v,type:C}=a,E=!p.get(y),x=e=>{m.notify(e.message,"error")};return re.default.createElement(re.default.Fragment,null,re.default.createElement("tr",{onMouseEnter:e=>{s.setApolloHover({feature:a,topLevelFeature:fa(a),glyph:ca(fa(a))})},className:c.feature+(r?` ${l}`:o?` ${c.hoveredFeature}`:""),onClick:e=>{e.stopPropagation(),s.setSelectedFeature(a)},onContextMenu:e=>(e.preventDefault(),i({position:{left:e.clientX+2,top:e.clientY-6},items:da(s,a)}),!1)},re.default.createElement("td",{style:{whiteSpace:"nowrap",borderLeft:2*n+"em solid transparent"}},b?.size?re.default.createElement("div",{onClick:e=>{e.stopPropagation(),g.setFeatureCollapsed(y,E)},className:c.arrow+(E?` ${c.arrowExpanded}`:"")},"❯"):null,re.default.createElement("div",{className:c.typeContent},re.default.createElement(rt,{session:m,ontologyName:"Sequence Ontology",style:{width:170},value:C,filterTerms:nt,fetchValidTerms:ga.bind(null,a),renderInput:e=>re.default.createElement("div",{ref:e.InputProps.ref},re.default.createElement("input",{type:"text",...e.inputProps,className:c.typeInputElement,style:{width:170}}),e.error?re.default.createElement("div",{className:c.typeErrorMessage},e.errorMessage??"unknown error"):null),onChange:(e,n)=>{n&&function(e,n,a,o){const r=n._id,s=new t.TypeChange({typeName:"TypeChange",changedIds:[r],featureId:r,oldType:String(a),newType:String(o),assembly:n.assemblyId});return e.submit(s)}(d,a,e,n).catch(x)}}))),re.default.createElement("td",null,re.default.createElement(kn,{initialValue:w+1,notifyError:x,onChangeCommitted:e=>function(e,n,a,o){const r=n._id,s=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:a,newStart:o,assembly:n.assemblyId});return e.submit(s)}(d,a,w,e-1)})),re.default.createElement("td",null,re.default.createElement(kn,{initialValue:S,notifyError:x,onChangeCommitted:e=>function(e,n,a,o){const r=n._id,s=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:a,newEnd:o,assembly:n.assemblyId});return e.submit(s)}(d,a,S,e)})),re.default.createElement("td",null,1===v?"+":-1===v?"-":void 0),re.default.createElement("td",null,re.default.createElement(An,{filterText:h,feature:a}))),E&&b?[...b.entries()].filter((e=>{if(!h)return!0;const[,t]=e;return JSON.stringify(t).includes(h)})).map((([t,a])=>re.default.createElement(e,{isHovered:u?.feature._id===a._id,isSelected:f?._id===a._id,selectedFeatureClass:l,key:t,depth:(n||0)+1,feature:a,model:s,setContextMenu:i}))):null)}));async function ga(e,t,n){const{parent:a}=e;if(a){const e=(await t.getTermsWithLabelOrSynonym(a.type,{includeSubclasses:!1})).filter(nt);if(e.length>0)return await t.getClassesThat("part_of",e)}}const pa=w.makeStyles()((e=>({scrollableTable:{width:"100%",height:"100%",th:{position:"sticky",top:0,zIndex:2,textAlign:"left",background:e.palette.background.paper,paddingTop:"3.2em"},td:{whiteSpace:"normal"}},selectedFeature:{backgroundColor:e.palette.action.selected}}))),ha=S.observer((function({model:e}){const{apolloHover:t,seenFeatures:n,selectedFeature:a,tabularEditor:o}=e,r=f.useTheme(),{classes:s}=pa(),l=h.useRef(null),[i,c]=h.useState(null),{filterText:u}=o;return h.useEffect((()=>{const e=l.current;if(e&&a){const t=e.querySelector(`.${s.selectedFeature}`);if(t){const n=e.scrollTop,a=t.offsetTop-25;a>n&&a<n+e.offsetHeight||e.scroll({top:a-40,behavior:"smooth"})}}}),[a,n,s.selectedFeature]),re.default.createElement("div",{ref:l,style:{width:"100%",overflowY:"auto",height:"100%"}},re.default.createElement("table",{className:s.scrollableTable},re.default.createElement("thead",null,re.default.createElement("tr",null,re.default.createElement("th",null,"Type"),re.default.createElement("th",null,"Start"),re.default.createElement("th",null,"End"),re.default.createElement("th",null,"Strand"),re.default.createElement("th",null,"Attributes"))),re.default.createElement("tbody",null,[...n.entries()].filter((e=>{if(!u)return!0;const[,t]=e;return JSON.stringify(t).includes(u)})).sort(((e,t)=>e[1].min-t[1].min)).map((([n,o])=>re.default.createElement(ma,{key:n,isSelected:a?._id===n,isHovered:t?.feature._id===n,selectedFeatureClass:s.selectedFeature,feature:o,model:e,depth:0,setContextMenu:c}))))),re.default.createElement(y.Menu,{open:Boolean(i),onMenuItemClick:(e,t)=>{t(),c(null)},onClose:()=>{c(null)},TransitionProps:{onExit:()=>{c(null)}},style:{zIndex:r.zIndex.tooltip},menuItems:i?.items??[],anchorReference:"anchorPosition",anchorPosition:i?.position}))})),ya=w.makeStyles()({toolbar:{width:"100%",display:"flex",paddingRight:"2em",flexDirection:"row",justifyContent:"space-between",position:"absolute",zIndex:4},filterText:{}}),ba=S.observer((function({model:e}){const t=e.tabularEditor,{classes:n}=ya();return re.default.createElement("div",{className:n.toolbar},re.default.createElement(f.Tooltip,{title:"Collapse all"},re.default.createElement(f.IconButton,{"aria-label":"collapse",sx:{marginTop:0},onClick:t.collapseAllFeatures},re.default.createElement(we.default,null))),re.default.createElement(f.TextField,{className:n.filterText,label:"Filter features",value:t.filterText,sx:{marginTop:0},variant:"outlined",onChange:e=>{t.setFilterText(e.target.value)},InputProps:{endAdornment:re.default.createElement(f.InputAdornment,{position:"end"},re.default.createElement(f.IconButton,{onClick:()=>{t.clearFilterText()}},re.default.createElement(Se.default,null)))}}))}));function Sa(e){e.stopPropagation()}const wa=S.observer((function({model:e}){return e.tabularEditor.isShown?re.default.createElement("div",{onMouseDown:Sa,onClick:Sa,style:{width:"100%",height:"100%",position:"relative"}},re.default.createElement(ba,{model:e}),re.default.createElement(ha,{model:e})):null})),va=i.types.model("TabularEditor",{isShown:!0,featureCollapsed:i.types.map(i.types.boolean),filterText:""}).actions((e=>({setFeatureCollapsed(t,n){e.featureCollapsed.set(t,n)},setFilterText(t){e.filterText=t},clearFilterText(){e.filterText=""},collapseAllFeatures(){const t=i.getParent(e);for(const[n]of t.seenFeatures.entries())e.featureCollapsed.set(n,!0)},togglePane(){e.isShown=!e.isShown},hidePane(){e.isShown=!1},showPane(){e.isShown=!0}})));function Ca(e,o){return function(e,o){const s=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return a.BaseDisplay.named("BaseLinearApolloDisplay").props({type:i.types.literal("LinearApolloDisplay"),configuration:n.ConfigurationReference(t),graphical:!0,table:!1,heightPreConfig:i.types.maybe(i.types.refinement("displayHeight",i.types.number,(e=>e>=20)))}).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...G.getParentRenderProps(e),config:t.renderer})}})).volatile((()=>({scrollTop:0}))).views((e=>({get lgv(){return r.getContainingView(e)},get height(){return e.heightPreConfig?e.heightPreConfig:e.graphical&&e.table?500:e.graphical?200:300}}))).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get session(){return r.getSession(e)},get regions(){return e.lgv.dynamicBlocks.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:Math.round(a),end:Math.round(t)})))},regionCannotBeRendered(){if(e.lgv&&e.lgv.bpPerPx>=200)return"Zoom in to see annotations"}}))).views((e=>({get apolloInternetAccount(){const[t]=e.regions,{internetAccounts:a}=i.getRoot(e),{assemblyName:o}=t,{assemblyManager:r}=e.session,s=r.get(o);if(!s)throw new Error(`No assembly found with name ${o}`);const{internetAccountConfigId:l}=n.getConf(s,["sequence","metadata"]);return a.find((e=>n.getConf(e,"internetAccountId")===l))},get changeManager(){return e.session.apolloDataStore.changeManager},getAssemblyId(t){const{assemblyManager:n}=e.session,a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return e.session.apolloSelectedFeature}}))).actions((e=>({setScrollTop(t){e.scrollTop=t},setHeight:t=>(e.heightPreConfig=Math.max(t,20),e.height),resizeHeight(t){const n=e.height;return this.setHeight(e.height+t)-n},showGraphicalOnly(){e.graphical=!0,e.table=!1},showTableOnly(){e.graphical=!1,e.table=!0},showGraphicalAndTable(){e.graphical=!0,e.table=!0}}))).views((e=>{const{trackMenuItems:t}=e;return{trackMenuItems(){const{graphical:n,table:a}=e;return[...t(),{type:"subMenu",label:"Appearance",subMenu:[{label:"Show graphical display",type:"radio",checked:n&&!a,onClick:()=>{e.showGraphicalOnly()}},{label:"Show table display",type:"radio",checked:a&&!n,onClick:()=>{e.showTableOnly()}},{label:"Show both graphical and table display",type:"radio",checked:a&&n,onClick:()=>{e.showGraphicalAndTable()}}]}]}}})).actions((e=>({setSelectedFeature(t){e.session.apolloSetSelectedFeature(t)},afterAttach(){i.addDisposer(e,l.autorun((()=>{e.lgv.initialized&&!e.regionCannotBeRendered()&&(e.session.apolloDataStore.loadFeatures(e.regions),e.lgv.bpPerPx<=3&&e.session.apolloDataStore.loadRefSeq(e.regions))}),{name:"LinearApolloDisplayLoadFeatures",delay:1e3}))}})))}(0,t);return o.named("LinearApolloDisplayLayouts").props({featuresMinMaxLimit:5e5}).volatile((()=>({seenFeatures:l.observable.map()}))).views((e=>({get featuresMinMax(){const{assemblyManager:t}=e.session;return e.lgv.displayedRegions.map((n=>{const a=t.get(n.assemblyName);let o,s;const{end:l,refName:i,start:c}=n;for(const[,t]of e.seenFeatures)i!==a?.getCanonicalRefName(t.refSeq)||!r.doesIntersect2(c,l,t.min,t.max)||t.length>e.featuresMinMaxLimit||(void 0===o&&({min:o}=t),void 0===s&&({max:s}=t),t.minWithChildren<o&&({min:o}=t),t.maxWithChildren>s&&({max:s}=t));if(void 0!==o&&void 0!==s)return[o,s]}))}}))).actions((e=>({addSeenFeature(t){e.seenFeatures.set(t._id,t)},deleteSeenFeature(t){e.seenFeatures.delete(t)}}))).views((e=>({get featureLayouts(){const{assemblyManager:t}=e.session;return e.lgv.displayedRegions.map(((n,a)=>{const o=t.get(n.assemblyName),s=new Map,l=e.featuresMinMax[a];if(!l)return s;const[c,u]=l,d=[],{end:f,refName:m,start:g}=n;for(const[t,n]of e.seenFeatures.entries()){if(!i.isAlive(n)){e.deleteSeenFeature(t);continue}if(m!==o?.getCanonicalRefName(n.refSeq)||!r.doesIntersect2(g,f,n.min,n.max))continue;const a=ca(n).getRowCount(n,e.lgv.bpPerPx);let l=0,p=!1;for(;!p;){let e=d.slice(l,l+a);if(e.length<a){for(let t=0;t<a-e.length;t++){const e=d.length;d[e]=Array.from({length:u-c}),s.set(e,[])}e=d.slice(l,l+a)}if(e.map((e=>{const t=n.max-n.min==0?n.min+1:n.max;let a=n.min-c,o=t-c;return n.min-c<0&&(a=0,o=t-n.min),e.slice(a,o).some(Boolean)})).some(Boolean))l+=1;else{for(let e=l;e<l+a;e++){let t=n.min-c,a=n.max-c;n.min-c<0&&(t=0,a=n.max-n.min),d[e].fill(!0,t,a);const o=s.get(e);o?.push([e-l,n])}p=!0}}}return s}))},getFeatureLayoutPosition(e){const{featureLayouts:t}=this;for(const[n,a]of t.entries())for(const[t,o]of a)for(const[a,r]of o)if(0===a){if(e._id===r._id)return{layoutIndex:n,layoutRow:t,featureRow:a};if(r.hasDescendant(e._id)){const a=ca(r).getRowForFeature(r,e);if(void 0!==a)return{layoutIndex:n,layoutRow:t,featureRow:a}}}}}))).views((e=>({get highestRow(){return Math.max(0,...e.featureLayouts.map((e=>Math.max(...e.keys()))))}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(e.lgv.initialized&&!e.regionCannotBeRendered())for(const t of e.regions){const n=e.session.apolloDataStore.assemblies.get(t.assemblyName),a=n?.getByRefName(t.refName),o=a?.features;if(o)for(const[,n]of o)r.doesIntersect2(t.start,t.end,n.min,n.max)&&!e.seenFeatures.has(n._id)&&e.addSeenFeature(n)}}),{name:"LinearApolloDisplaySetSeenFeatures",delay:1e3}))}})))}(0,t).named("LinearApolloDisplayRendering").props({sequenceRowHeight:15,apolloRowHeight:20,detailsMinHeight:200,detailsHeight:200,lastRowTooltipBufferHeight:40,isShown:!0}).volatile((()=>({canvas:null,overlayCanvas:null,collaboratorCanvas:null,seqTrackCanvas:null,seqTrackOverlayCanvas:null,theme:void 0}))).views((e=>({get featuresHeight(){return(e.highestRow+1)*e.apolloRowHeight+e.lastRowTooltipBufferHeight}}))).actions((e=>({toggleShown(){e.isShown=!e.isShown},setDetailsHeight(t){e.detailsHeight=e.isShown?Math.max(Math.min(t,e.height-100),Math.min(e.height,e.detailsMinHeight)):t},setCanvas(t){e.canvas=t},setOverlayCanvas(t){e.overlayCanvas=t},setCollaboratorCanvas(t){e.collaboratorCanvas=t},setSeqTrackCanvas(t){e.seqTrackCanvas=t},setSeqTrackOverlayCanvas(t){e.seqTrackOverlayCanvas=t},setTheme(t){e.theme=t},afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.collaboratorCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const n of e.session.collaborators){const{locations:a}=n;if(0===a.length)continue;let o=0;for(const r of e.lgv.displayedRegions){for(const s of a){if(s.refSeq!==r.refName)continue;const{end:a,refSeq:l,start:i}=s,c=e.lgv.bpToPx({refName:l,coord:i,regionNumber:o});if(!c)continue;const u=c.offsetPx-e.lgv.offsetPx,d=(a-i)/e.lgv.bpPerPx;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(u,1,d,100),t.fillStyle="black",t.fillText(n.name,u+1,11,d-2)}o++}}}}),{name:"LinearApolloDisplayRenderCollaborators"}))}})))}(0,t);return o.actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;if(e.lgv.bpPerPx>3)return;const t=e.seqTrackCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const n=e.lgv.bpPerPx<=1?[3,2,1,0,0,-1,-2,-3]:[3,2,1,-1,-2,-3];let a=0;for(const o of n){const n=e.theme?.palette.framesCDS.at(o)?.main;n&&(t.fillStyle=n,t.fillRect(0,a,e.lgv.dynamicBlocks.totalWidthPx,e.sequenceRowHeight)),a+=e.sequenceRowHeight}for(const[n,a]of e.regions.entries()){const o=e.session.apolloDataStore.getBackendDriver(a.assemblyName);if(!o)throw new Error("Failed to get the backend driver");const{seq:s}=await o.getSequence(a);if(!s)return;for(const[o,l]of[...s].entries()){const i=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,c=3/e.lgv.bpPerPx,u=e.lgv.displayedRegions[n].reversed?i-c:i;for(let n=2;n>=0;n--)(a.start+o)%3===n&&Dn(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*(2-n),c,e.sequenceRowHeight,s,o,!1);if(e.lgv.bpPerPx<=1){const s=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,i=1/e.lgv.bpPerPx,c=e.lgv.displayedRegions[n].reversed?s-i:s;t.beginPath(),t.fillStyle=Nn(l,e.theme),t.rect(c,3*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Rn(t,c,i,l,3*e.sequenceRowHeight));const u=r.revcom(l);t.beginPath(),t.fillStyle=Nn(u,e.theme),t.rect(c,4*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Rn(t,c,i,u,4*e.sequenceRowHeight))}for(let n=0;n<=2;n++)(a.start+o)%3===n&&Dn(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*((e.lgv.bpPerPx<=1?5:3)+n),c,e.sequenceRowHeight,s,o,!0)}}}),{name:"LinearApolloDisplayRenderSequence"}))}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{const{canvas:t,featureLayouts:n,featuresHeight:a,lgv:o}=e;if(!o.initialized||e.regionCannotBeRendered())return;const{displayedRegions:s,dynamicBlocks:l}=o,i=t?.getContext("2d");if(i){i.clearRect(0,0,l.totalWidthPx,a);for(const[t,a]of n.entries()){const n=s[t];for(const[o,s]of a.entries())for(const[a,l]of s)a>0||r.doesIntersect2(n.start,n.end,l.min,l.max)&&ca(l).draw(i,l,o,e,t)}}}),{name:"LinearApolloDisplayRenderFeatures"}))}})))}(0,t);return o.named("LinearApolloDisplayMouseEvents").volatile((()=>({apolloDragging:null,cursor:void 0,apolloHover:void 0}))).views((e=>({getMousePosition(t){const n=function(e,t){const n=e.currentTarget,{clientX:a,clientY:o}=e,{left:r,top:s}=n.getBoundingClientRect(),l=a-r,i=o-s,{coord:c,index:u,refName:d}=t.pxToBp(l);return{x:l,y:i,refName:d,bp:c,regionNumber:u}}(t,e.lgv),{bp:a,regionNumber:o,y:r}=n,s=Math.floor(r/e.apolloRowHeight),l=e.featureLayouts[o].get(s);if(!l)return n;const i=l.find((e=>a>=e[1].min&&a<=e[1].max));if(!i)return n;const[c,u]=i,d=ca(u),f=d.getFeatureFromLayout(u,a,c);return f?{...n,featureAndGlyphUnderMouse:{feature:f,topLevelFeature:u,glyph:d}}:n}}))).actions((e=>({continueDrag(t,n){if(!e.apolloDragging)throw new Error("continueDrag() called with no current drag in progress");n.stopPropagation(),e.apolloDragging={...e.apolloDragging,current:t}},setDragging(t){e.apolloDragging=t??null}}))).actions((e=>({setApolloHover(t){e.apolloHover=t},setCursor(t){e.cursor!==t&&(e.cursor=t)}}))).actions((()=>({onClick(){}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.seqTrackOverlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const{apolloHover:n,lgv:a,regions:o,sequenceRowHeight:s,theme:l}=e;if(!n)return;const{feature:i}=n;for(const[e,n]of o.entries())if("CDS"===i.type){const o=i.parent;if(!o)continue;const c=o.cdsLocations.find((e=>i.min===e.at(0)?.min&&i.max===e.at(-1)?.max));if(!c)continue;for(const o of c){const c=Mn(r.getFrame(o.min,o.max,i.strand??1,o.phase),a.bpPerPx),u=(a.bpToPx({refName:n.refName,coord:o.min,regionNumber:e})?.offsetPx??0)-a.offsetPx,d=(o.max-o.min)/a.bpPerPx;Ln(t,l,a.displayedRegions[e].reversed?u-d:u,s,c,d)}}else{const o=In(i.strand,a.bpPerPx),r=(a.bpToPx({refName:n.refName,coord:i.min,regionNumber:e})?.offsetPx??0)-a.offsetPx,c=i.length/a.bpPerPx;Ln(t,l,a.displayedRegions[e].reversed?r-c:r,s,o,c)}}),{name:"LinearApolloDisplayRenderSeqHighlight"}))}})))}(0,o);return s.views((e=>({contextMenuItems(t){const{apolloHover:n}=e;if(!n||!t)return[];const{topLevelFeature:a}=n;return ca(a).getContextMenuItems(e)}}))).actions((e=>({startDrag(t,n,a){e.apolloDragging={start:t,current:t,feature:n,edge:a}},endDrag(){if(!e.apolloDragging)throw new Error("endDrag() called with no current drag in progress");const{current:n,edge:a,feature:o,start:r}=e.apolloDragging;if(Math.abs(n.x-r.x)<=4)return e.setDragging(),void e.setCursor();const{displayedRegions:s}=e.lgv,l=e.getAssemblyId(s[r.regionNumber].assemblyName);let i;if("max"===a){const e=o._id;i=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[e],featureId:e,oldEnd:o.max,newEnd:n.bp,assembly:l})}else{const e=o._id;i=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[e],featureId:e,oldStart:o.min,newStart:n.bp,assembly:l})}e.changeManager.submit(i),e.setDragging(),e.setCursor()}}))).actions((e=>({onMouseDown(t){const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseDown(e,n,t)},onMouseMove(t){const n=e.getMousePosition(t);if(e.apolloDragging)return e.setCursor("col-resize"),void e.continueDrag(n,t);Fn(n)?n.featureAndGlyphUnderMouse.glyph.onMouseMove(e,n,t):(e.setApolloHover(),e.setCursor())},onMouseLeave(t){e.setDragging(),e.setApolloHover();const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseLeave(e,n,t)},onMouseUp(t){const n=e.getMousePosition(t);Fn(n)&&n.featureAndGlyphUnderMouse.glyph.onMouseUp(e,n,t),e.apolloDragging&&e.endDrag()}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.overlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);const{apolloDragging:n,apolloHover:a}=e;if(!a)return;const{glyph:o}=a;o.drawHover(e,t),o.drawTooltip(e,t),n&&ca(n.feature.topLevelFeature).drawDragPreview(e,t)}),{name:"LinearApolloDisplayRenderMouseoverAndDrag"}))}})))}(0,o).props({tabularEditor:i.types.optional(va,{})}).named("LinearApolloDisplay")}const Ea=w.makeStyles()((e=>({canvasContainer:{position:"relative",left:0},canvas:{position:"absolute",left:0},ellipses:{textOverflow:"ellipsis",overflow:"hidden"},avatar:{position:"absolute",color:e.palette.warning.light,backgroundColor:e.palette.warning.contrastText}}))),xa=S.observer((function(e){const t=f.useTheme(),{model:n}=e,{apolloRowHeight:a,contextMenuItems:o,cursor:s,featuresHeight:l,isShown:i,onMouseDown:c,onMouseLeave:u,onMouseMove:d,onMouseUp:m,regionCannotBeRendered:g,session:p,setCanvas:b,setCollaboratorCanvas:S,setOverlayCanvas:w,setSeqTrackCanvas:v,setSeqTrackOverlayCanvas:C,setTheme:E}=n,{classes:x}=Ea(),A=r.getContainingView(n);h.useEffect((()=>{E(t)}),[t,E]);const[T,k]=h.useState(),[N,R]=h.useState([]),D=g();if(!i)return null;const{assemblyManager:F}=p;return re.default.createElement(re.default.Fragment,null,A.bpPerPx<=3?re.default.createElement("div",{className:x.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95}},re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),v(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:x.canvas,"data-testid":"seqTrackCanvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),C(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:x.canvas,"data-testid":"seqTrackOverlayCanvas"})):null,re.default.createElement("div",{className:x.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:l},onContextMenu:e=>{if(e.preventDefault(),N.length>0)R([]);else{const t=[e.clientX,e.clientY];k(t),R(o(t))}}},D?re.default.createElement(f.Alert,{severity:"warning",classes:{message:x.ellipses}},re.default.createElement(f.Tooltip,{title:D},re.default.createElement("div",null,D))):re.default.createElement(re.default.Fragment,null,re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),S(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:x.canvas,"data-testid":"collaboratorCanvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),b(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:x.canvas,"data-testid":"canvas"}),re.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),w(e)},width:A.dynamicBlocks.totalWidthPx,height:l,onMouseMove:d,onMouseLeave:u,onMouseDown:c,onMouseUp:m,className:x.canvas,style:{cursor:s??"default"},"data-testid":"overlayCanvas"}),A.displayedRegions.flatMap(((e,t)=>{const o=F.get(e.assemblyName);return[...p.apolloDataStore.checkResults.values()].filter((t=>o?.isValidRefName(t.refSeq)&&o.getCanonicalRefName(t.refSeq)===e.refName&&r.doesIntersect2(e.start,e.end,t.start,t.end))).map((o=>{const r=(A.bpToPx({refName:e.refName,coord:o.start,regionNumber:t})?.offsetPx??0)-A.offsetPx,[s]=o.ids;if(!s)return null;const{topLevelFeature:l}=s,i=parent?n.getFeatureLayoutPosition(l)?.layoutRow??0:0;return re.default.createElement(f.Tooltip,{key:o._id,title:o.message},re.default.createElement(f.Avatar,{className:x.avatar,style:{top:i*a,left:r,height:a,width:a}},re.default.createElement(Ee.default,null)))}))})),re.default.createElement(y.Menu,{open:N.length>0,onMenuItemClick:(e,t)=>{t(),R([])},onClose:()=>{R([])},TransitionProps:{onExit:()=>{R([])}},anchorReference:"anchorPosition",anchorPosition:T?{top:T[1],left:T[0]}:void 0,style:{zIndex:t.zIndex.tooltip},menuItems:N}))))})),Aa=S.observer((function({model:e}){const{height:t}=e;return re.default.createElement("div",{style:{position:"absolute",left:0,top:t/2,width:"100%"}},re.default.createElement("hr",{style:{margin:0,top:0,color:"black"}}))})),Ta=w.makeStyles()((e=>({shading:{background:f.alpha(e.palette.primary.main,.2),overflowY:"scroll",overflowX:"hidden"},details:{background:e.palette.background.paper},accordionControl:{height:12,width:"100%","&:hover":{background:e.palette.action.hover},display:"flex",alignItems:"center",justifyContent:"center"},accordionRoot:{background:e.palette.divider},resizeHandle:{width:"100%",height:4,position:"absolute",cursor:"row-resize",zIndex:100},expandIcon:{},title:{userSelect:"none"},alertContainer:{display:"flex",alignItems:"center",justifyContent:"center"}}))),ka=({onResize:e})=>{const{classes:t}=Ta(),n=h.useCallback((t=>{t.stopPropagation(),t.preventDefault(),e(t.movementY)}),[e]),a=h.useCallback((e=>{e.stopPropagation(),e.preventDefault(),globalThis.removeEventListener("mousemove",n),globalThis.removeEventListener("mouseup",a),globalThis.removeEventListener("mouseleave",a)}),[n]);return re.default.createElement("div",{onMouseDown:e=>{e.stopPropagation(),globalThis.addEventListener("mousemove",n),globalThis.addEventListener("mouseup",a),globalThis.addEventListener("mouseleave",a)},onClick:e=>{e.stopPropagation(),e.preventDefault()},className:t.resizeHandle})},Na=S.observer((function({onClick:e,onResize:t,open:n,title:a}){const{classes:o}=Ta();return re.default.createElement("div",{className:o.accordionRoot},n&&t?re.default.createElement(ka,{onResize:t}):null,re.default.createElement("div",{className:o.accordionControl,onClick:e},re.default.createElement(n?ve.default:Ce.default,{className:o.expandIcon}),a?re.default.createElement(f.Typography,{className:o.title,variant:"caption",component:"span"},a):null))})),Ra=S.observer((function({model:e,...t}){const n=r.getSession(e),{ontologyManager:a}=n.apolloDataStore,{featureTypeOntology:o}=a,s=o?.dataStore,{classes:l}=Ta(),{detailsHeight:i,graphical:c,height:u,isShown:d,selectedFeature:m,table:g,tabularEditor:p,toggleShown:y}=e,b=h.useRef(null);h.useEffect((()=>{!function(e,t){const{apolloRowHeight:n,selectedFeature:a}=e;if(t.current&&a){const o=e.getFeatureLayoutPosition(a);o&&t.current.scroll({top:(o.layoutRow+o.featureRow)*n,behavior:"smooth"})}}(e,b)}),[e,m]);const S=t=>{e.setDetailsHeight(i-t)};if(!s)return re.default.createElement("div",{className:l.alertContainer},re.default.createElement(f.Alert,{severity:"error"},"Could not load feature type ontology."));if(c&&g){const n=p.isShown?i:0,a=d?u-i-24:0;return re.default.createElement("div",{style:{height:u}},re.default.createElement(Na,{open:d,title:"Graphical",onClick:y}),re.default.createElement("div",{className:l.shading,ref:b,style:{height:a}},re.default.createElement(xa,{model:e,...t})),re.default.createElement(Na,{title:"Table",open:p.isShown,onClick:p.togglePane,onResize:S}),re.default.createElement("div",{className:l.details,style:{height:n}},re.default.createElement(wa,{model:e})))}return c?re.default.createElement("div",{className:l.shading,ref:b,style:{height:u}},re.default.createElement(xa,{model:e,...t})):re.default.createElement("div",{className:l.details,style:{height:u}},re.default.createElement(wa,{model:e}))})),Da=i.types.model("JobsManager",{}).views((e=>({get jobStatusWidget(){const{widgets:t}=r.getSession(e);let n=t.get("JobsList");return n||(n=r.getSession(e).addWidget("JobsListWidget","JobsList")),n}}))).actions((e=>({update(t,n,a){e.jobStatusWidget.updateJobStatusMessage(t,n),a&&e.jobStatusWidget.updateJobProgressPct(t,a)},abortJob(t,n){const a=r.getSession(e);if(r.isSessionModelWithWidgets(a)){a.showWidget(e.jobStatusWidget),e.jobStatusWidget.updateJobStatusMessage(t,n??"Aborted unexpectedly");const o=e.jobStatusWidget.jobs.findIndex((e=>e.name===t));e.jobStatusWidget.addAbortedJob({...e.jobStatusWidget.jobs[o]}),e.jobStatusWidget.removeJob(t),a.notify("Job aborted","info")}},runJob(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.addJob(t))},done(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.removeJob(t.name),e.jobStatusWidget.addFinishedJob({name:t.name,statusMessage:"All operations successful",progressPct:100,cancelCallback:t.cancelCallback}))}})));class Fa{clientStore;constructor(e){this.clientStore=e}}class Ma{dataStore;constructor(e){this.dataStore=e}recentChanges=[];async submit(n,a={}){const{addToRecents:o=!0,submitToBackend:s=!0,updateJobsManager:l=!1}=a,i=r.getSession(this.dataStore),c=new AbortController,{jobsManager:u}=r.getSession(this.dataStore),d={name:n.typeName,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{c.abort()}};l&&u.runJob(d);const f=await t.validationRegistry.frontendPreValidate(n);if(!f.ok){const e=`Pre-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),void i.notify(e,"error")}try{await n.execute(this.dataStore)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),void i.notify(String(e),"error")}if((await t.validationRegistry.frontendPostValidate(n,this.dataStore)).ok||await this.revert(n),s){l&&u.update(d.name,"Submitting to driver");const{collaborationServerDriver:t,getBackendDriver:o}=this.dataStore,r=e.isAssemblySpecificChange(n)?o(n.assembly):t;let s;try{s=await r.submitChange(n,a)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),i.notify(String(e),"error"),void await this.revert(n,!1)}if(!s.ok){const e=`Post-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),i.notify(e,"error"),void await this.revert(n,!1)}n.notification&&i.notify(n.notification,"success")}o&&this.recentChanges.push(n),l&&u.done(d)}async revert(e,t=!0){const n=e.getInverse();return this.submit(n,{submitToBackend:t,addToRecents:!1})}async revertLastChange(){const e=this.recentChanges.pop();if(e)return this.revert(e);r.getSession(this.dataStore).notify("No changes to undo!","warning")}}class Ia extends Fa{inFlight=new Map;async fetch(e,t,n){return e.getFetcher({locationType:"UriLocation",uri:t.toString()})(t,n)}async searchFeatures(e,t){const n=this.clientStore.getInternetAccount(t[0]),{baseURL:a}=n,o=new URL("features/searchFeatures",a),r=new URLSearchParams({assemblies:t.join(","),term:e});o.search=r.toString();const s=o.toString(),l=await this.fetch(n,s);if(!l.ok){const e=await Ne(l,"searchFeatures failed");throw new Error(e)}return l.json()}async getFeatures(e){const{assemblyName:t,end:a,refName:o,start:s}=e,{assemblyManager:l}=r.getSession(this.clientStore),i=l.get(t);if(!i)throw new Error(`Could not find assembly with name "${t}"`);const{ids:c}=n.getConf(i,["sequence","metadata"]),u=c[o];if(!u)throw new Error(`Could not find refSeq "${o}"`);const d=this.clientStore.getInternetAccount(t),{baseURL:f}=d,m=new URL("features/getFeatures",f),g=new URLSearchParams({refSeq:u,start:String(s),end:String(a)});m.search=g.toString();const p=m.toString(),h=await this.fetch(d,p);if(!h.ok){const e=await Ne(h,"getFeatures failed");throw new Error(e)}return this.checkSocket(t,o,d),h.json()}checkSocket(t,n,a){const{socket:o}=a,r=a.retrieveToken(),s=`${t}-${n}`,l=new Ma(this.clientStore);o.hasListeners(s)||o.on(s,(async t=>{if(a.setLastChangeSequenceNumber(Number(t.changeSequence)),t.userSessionId!==r&&t.channel===s){const n=e.Change.fromJSON(t.changeInfo);await l.submit(n,{submitToBackend:!1})}}))}async getSequence(e){const t=`${e.refName}:${e.start}-${e.end}`,a=this.inFlight.get(t),{assemblyName:o,end:s,refName:l,start:i}=e,{assemblyManager:c}=r.getSession(this.clientStore),u=c.get(o);if(!u)throw new Error(`Could not find assembly with name "${o}"`);const{ids:d}=n.getConf(u,["sequence","metadata"]),f=d[l];if(!f)throw new Error(`Could not find refSeq "${l}"`);if(a)return{seq:await a,refSeq:f};let m=this.clientStore.assemblies.get(o);m||(m=this.clientStore.addAssembly(o));let g=m.refSeqs.get(f);g||(g=m.addRefSeq(f,l));const p=g.getSequence(i,s);if(p.length===s-i)return{seq:p,refSeq:f};const h=this.clientStore.getInternetAccount(o),{baseURL:y}=h,b=new URL("sequence",y),S=new URLSearchParams({refSeq:f,start:String(i),end:String(s)});b.search=S.toString();const w=b.toString(),v=this.getSeqFromServer(h,w,g,i,s);this.inFlight.set(t,v);const C=await v;return this.checkSocket(o,l,h),this.inFlight.delete(t),{seq:C,refSeq:f}}async getSeqFromServer(e,t,n,a,o){const r=await this.fetch(e,t);if(!r.ok){let e;try{e=await r.text()}catch{e=""}throw new Error(`getSequence failed: ${r.status} (${r.statusText})${e?` (${e})`:""}`)}const s=await r.text();return n.addSequence({sequence:s,start:a,stop:o}),s}async getRefNameAliases(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRefNameAliases failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,aliases:[e._id,...e.aliases],uniqueId:`alias-${e._id}`})))}async getRegions(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRegions failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,start:0,end:e.length})))}getAssemblies(e){const{assemblyManager:t}=r.getSession(this.clientStore);return t.assemblies.filter((t=>{const a=n.getConf(t,["sequence","metadata"]);return!(!(a&&a.apollo&&a.internetAccountConfigId)||e&&a.internetAccountConfigId!==e)}))}async submitChange(e,n={}){const{internetAccountId:a}=n,o=this.clientStore.getInternetAccount("assembly"in e?e.assembly:void 0,a),{baseURL:r}=o,s=new URL("changes",r).href,l=await this.fetch(o,s,{method:"POST",body:JSON.stringify(e.toJSON()),headers:{"Content-Type":"application/json"}});if(!l.ok){const e=await Ne(l,"submitChange failed");throw new Error(e)}const i=new t.ValidationResultSet;return l.ok||(i.ok=!1),i}}class La extends Fa{async getFeatures(){return[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=this.clientStore.assemblies.get(t);if(!r)return{seq:"",refSeq:a};const s=r.refSeqs.get(a);return s?{seq:s.getSequence(o,n),refSeq:a}:{seq:"",refSeq:a}}async getRefNameAliases(e){const t=this.clientStore.assemblies.get(e),n=[];if(!t)return n;for(const[,e]of t.refSeqs)n.push({refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`});return n}async getRegions(e){const t=this.clientStore.assemblies.get(e);if(!t)return[];const n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.file&&!t.internetAccountConfigId)}))}async submitChange(e,n={}){const{clientStore:a}=this,{assemblies:o}=a;a.clearCheckResults();for(const[,e]of o)if("InMemoryFileDriver"===e.backendDriverType){const t=await ke(e);a.addCheckResults(t)}return new t.ValidationResultSet}async searchFeatures(e,t){return[]}}class qa extends Fa{async loadAssembly(e){const{assemblyManager:t}=r.getSession(this.clientStore),a=t.get(e);if(!a)throw new Error(`Assembly ${e} not found`);const{file:o}=n.getConf(a,["sequence","metadata"]),s=require("node:fs");return Te(e,await s.promises.readFile(o,"utf8"),this.clientStore)}async getAssembly(e){let t=this.clientStore.assemblies.get(e);return t||(t=await this.loadAssembly(e)),t}async getRefNameAliases(e){const t=await this.getAssembly(e),n=[];for(const[,e]of t.refSeqs)n.push({refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`});return n}async getFeatures(e){return await this.getAssembly(e.assemblyName),[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=(await this.getAssembly(t)).refSeqs.get(a);if(!r)throw new Error(`refSeq ${a} not found in client data store`);return{seq:r.getSequence(o,n),refSeq:a}}async getRegions(e){const t=await this.getAssembly(e),n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.internetAccountConfigId&&t.file)}))}async submitChange(a){if(!e.isAssemblySpecificChange(a))throw new Error(`Cannot use this type of change with local file: "${a.typeName}"`);const{assemblyManager:o}=r.getSession(this.clientStore),s=o.get(a.assembly);if(!s)throw new Error(`Could not find assembly with name "${a.assembly}"`);const{file:l}=n.getConf(s,["sequence","metadata"]),c=this.clientStore.assemblies.get(a.assembly);if(!c)throw new Error(`Could not find assembly in client with name "${a.assembly}"`);const u=new Set(...c.refSeqs.keys()),{checkResults:d}=this.clientStore;for(const e of d.values())u.has(e.refSeq)&&d.delete(e._id);const f=await ke(c);this.clientStore.addCheckResults(f);const m=[{directive:"gff-version",value:"3"}];for(const[,e]of c.refSeqs)m.push({directive:"sequence-region",value:`${e.name} 1 ${e.sequence[0].stop}`});for(const e of c.comments)m.push({comment:e});for(const[,e]of c.refSeqs){const{features:n}=e;for(const[,e]of n)m.push(t.annotationFeatureToGFF3(i.getSnapshot(e)))}for(const[,e]of c.refSeqs){const[n]=e.sequence,a=t.splitStringIntoChunks(n.sequence,80).join("\n");m.push({id:e.name,description:e.description,sequence:a})}const g=ee.default.formatSync(m),p=require("node:fs");return await p.promises.writeFile(l,g,"utf8"),new t.ValidationResultSet}async searchFeatures(e,t){return[]}}function Pa(e,a){const o=new AbortController,{signal:s}=o,c=e.evaluateExtensionPoint("Apollo-extendAnnotationFeature",$.AnnotationFeatureModel),u=function(e){return i.types.model("ClientDataStore",{typeName:i.types.optional(i.types.literal("Client"),"Client"),assemblies:i.types.map($.ApolloAssembly),checkResults:i.types.map($.CheckResult),ontologyManager:i.types.optional(Qe,{})}).views((t=>({get internetAccounts(){return i.getRoot(t).internetAccounts},get pluginConfiguration(){return i.getRoot(t).jbrowse.configuration.ApolloPlugin},getFeature:n=>i.resolveIdentifier(e,t.assemblies,n)}))).actions((e=>({addAssembly(t,n){const a={_id:t,refSeqs:{}};return n&&(a.backendDriverType=n),e.assemblies.put(a)},addFeature(t,n){const a=e.assemblies.get(t);if(!a)throw new Error(`Could not find assembly "${t}" to add feature "${n._id}"`);const o=a.refSeqs.get(n.refSeq);if(!o)throw new Error(`Could not find refSeq "${n.refSeq}" to add feature "${n._id}"`);o.features.put(n)},deleteFeature(t){const n=e.getFeature(t);if(!n)throw new Error(`Could not find feature "${t}" to delete`);const{_id:a,parent:o}=n;o?o.deleteChild(t):i.getParentOfType(n,$.ApolloRefSeq).deleteFeature(a)},deleteAssembly(t){e.assemblies.delete(t)},addCheckResult(t){e.checkResults.put(t)},addCheckResults(t){for(const n of t)e.checkResults.has(n._id)||e.checkResults.put(n)},deleteCheckResult(t){e.checkResults.delete(t)},clearCheckResults(){e.checkResults.clear()}}))).volatile((e=>({changeManager:new Ma(e),collaborationServerDriver:new Ia(e),inMemoryFileDriver:new La(e),desktopFileDriver:r.isElectron?new qa(e):void 0}))).actions((e=>({afterCreate(){i.addDisposer(e,l.autorun((()=>{const{ontologyManager:t,pluginConfiguration:a}=e,o=a.ontologies;for(const e of o||[]){const[a,o,r,s]=[n.readConfObject(e,"name"),n.readConfObject(e,"version"),n.readConfObject(e,"source"),n.readConfObject(e,"textIndexFields")];t.findOntology(a)||t.addOntology(a,o,r,{textIndexing:{indexFields:s}})}})))}}))).views((e=>({getBackendDriver(t){if(!t)return e.collaborationServerDriver;const a=r.getSession(e),{assemblyManager:o}=a,s=o.get(t);if(!s)return e.collaborationServerDriver;const{file:l,internetAccountConfigId:i}=n.getConf(s,["sequence","metadata"]);return r.isElectron&&l?e.desktopFileDriver:i?e.collaborationServerDriver:e.inMemoryFileDriver},getInternetAccount(t,a){if(!(t??a))throw new Error("Must provide either assemblyName or internetAccountId");let o=a;if(t&&!o){const{assemblyManager:a}=r.getSession(e),s=a.get(t);if(!s)throw new Error(`No assembly found with name ${t}`);({internetAccountConfigId:o}=n.getConf(s,["sequence","metadata"]))}const{internetAccounts:s}=e,l=s.find((e=>e.internetAccountId===o));if(!l)throw new Error(`No InternetAccount found with config id ${a}`);return l}}))).actions((e=>({loadFeatures:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const[a,o]=yield t.getFeatures(n);if(0===a.length)continue;const{assemblyName:r,refName:s}=n;let l=e.assemblies.get(r);l||(l=e.assemblies.put({_id:r,refSeqs:{}}));const[i]=a;let c=l.refSeqs.get(i.refSeq);c||(c=l.refSeqs.put({_id:i.refSeq,name:s,features:{}}));for(const e of a)c.features.has(e._id)||c.features.put(e);e.addCheckResults(o)}})),loadRefSeq:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const{refSeq:a,seq:o}=yield t.getSequence(n),{assemblyName:r,end:s,refName:l,start:i}=n;let c=e.assemblies.get(r);c||(c=e.assemblies.put({_id:r,refSeqs:{}}));let u=c.refSeqs.get(a);u||(u=c.refSeqs.put({_id:a,name:l,sequence:[]})),u.addSequence({start:i,stop:s,sequence:o})}}))})))}(c),d=a.props({apolloDataStore:i.types.optional(u,{typeName:"Client"}),apolloSelectedFeature:i.types.safeReference(c),jobsManager:i.types.optional(Da,{})}).extend((()=>{const e=l.observable.array([]);return{views:{get collaborators(){return e}},actions:{addOrUpdateCollaborator(t){const n=e.find((e=>e.id===t.id));n?n.locations=t.locations:e.push(t)}}}})).actions((e=>({apolloSetSelectedFeature(t){e.apolloSelectedFeature=t},addApolloTrackConfig(t,a){const o=`apollo_track_${t.name}`;e.tracks.some((e=>e.trackId===o))||e.addTrackConf({type:"ApolloTrack",trackId:o,name:`Annotations (${n.getConf(t,"displayName")||t.name})`,assemblyNames:[t.name],textSearching:{textSearchAdapter:{type:"ApolloTextSearchAdapter",trackId:o,assemblyNames:[t.name],textSearchAdapterId:`apollo_search_${t.name}`,...a?{baseURL:{uri:a,locationType:"UriLocation"}}:{}}},displays:[{type:"LinearApolloDisplay",displayId:`${o}-LinearApolloDisplay`},{type:"SixFrameFeatureDisplay",displayId:`${o}-SixFrameFeatureDisplay`}]})},broadcastLocations(){const{internetAccounts:t}=i.getRoot(e),n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const a=t;if(a.initialized){const{dynamicBlocks:t}=a;t.forEach((t=>{if(void 0!==t.regionNumber){const{assemblyName:a,end:o,refName:r,start:s}=t,l=e.apolloDataStore.assemblies.get(a);l&&"CollaborationServerDriver"===l.backendDriverType&&n.push({assemblyName:a,refName:r,start:s,end:o})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}}))).actions((e=>({afterCreate:i.flow((function*(){const t=i.getSnapshot(e),{id:n,name:a}=t;i.applySnapshot(e,{name:a,id:n});const{internetAccounts:o,jbrowse:r}=i.getRoot(e);l.autorun((()=>{const t=[];for(const n of e.views){if("LinearGenomeView"!==n.type)return;const a=n;if(a.initialized){const{dynamicBlocks:n}=a;n.forEach((n=>{if(void 0!==n.regionNumber){const{assemblyName:a,end:o,refName:r,start:s}=n,l=e.apolloDataStore.assemblies.get(a);l&&"CollaborationServerDriver"===l.backendDriverType&&t.push({assemblyName:a,refName:r,start:s,end:o})}}))}}if(0===t.length){for(const e of o)"baseURL"in e&&e.postUserLocation([]);return}const n=[];for(const e of o)if("baseURL"in e){for(const e of t)n.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(n)}}),{name:"ApolloSession"});for(const n of o){if("ApolloInternetAccount"!==n.type)continue;const{baseURL:a}=n,o=new URL("jbrowse/config.json",a).href,l=n.getFetcher({locationType:"UriLocation",uri:o});let c,u;try{c=yield l(o,{signal:s})}catch(e){console.error(e);continue}if(c.ok){try{u=yield c.json()}catch(e){console.error(e);continue}i.applySnapshot(r,u),i.applySnapshot(e,t)}else{const e=yield Ne(c,"Failed to fetch assemblies");console.error(e)}}})),beforeDestroy(){o.abort("destroying session model")}}))).views((e=>{const a=e.getTrackActionMenuItems;return{getTrackActionMenuItems(o){if("ApolloTrack"===o.type||"ReferenceSequenceTrack"===o.type)return a?.(o);const r=n.readConfObject(o,"trackId");return r.endsWith("-sessionTrack")?[...a?.(o)??[],{label:"Save track to Apollo",onClick:async()=>{const{internetAccounts:n,jbrowse:a}=i.getRoot(e),s=i.getSnapshot(a);let l;l=t.filterJBrowseConfig(s),0===Object.keys(l).length&&(l=void 0);const c={...i.getSnapshot(o),trackId:r.slice(0,r.length-13)};for(const a of n){if("ApolloInternetAccount"!==a.type)continue;const n=new t.ImportJBrowseConfigChange({typeName:"ImportJBrowseConfigChange",oldJBrowseConfig:l,newJBrowseConfig:{...l,tracks:l?.tracks&&[...l.tracks,c]}}),{internetAccountId:o}=a;await e.apolloDataStore.changeManager.submit(n,{internetAccountId:o});const{notify:r}=e;r("Track added","success")}e.deleteTrackConf(o),a.addTrackConf(c)},icon:xe.default}]:[...a?.(o)??[],{label:"Remove track from Apollo",onClick:async()=>{const{internetAccounts:n,jbrowse:a}=i.getRoot(e),s=i.getSnapshot(a);let l;l=t.filterJBrowseConfig(s),0===Object.keys(l).length&&(l=void 0);const c=l?.tracks?.filter((e=>e.trackId!==r));for(const a of n){if("ApolloInternetAccount"!==a.type)continue;const n=new t.ImportJBrowseConfigChange({typeName:"ImportJBrowseConfigChange",oldJBrowseConfig:l,newJBrowseConfig:{...l,tracks:c}}),{internetAccountId:o}=a;await e.apolloDataStore.changeManager.submit(n,{internetAccountId:o});const{notify:r}=e;r("Track removed","success")}e.deleteTrackConf(o),a.deleteTrackConf(o)},icon:xe.default}]}}}));return i.types.snapshotProcessor(d,{postProcessor(e,t){e.apolloSelectedFeature=void 0;const n=Object.fromEntries(Object.entries(e.apolloDataStore.assemblies).filter((([,e])=>"InMemoryFileDriver"===e.backendDriverType)));if(e.apolloDataStore={typeName:"Client",assemblies:n,checkResults:{}},!t)return e;const{apolloDataStore:a}=t,{checkResults:o}=a;for(const[,t]of o){const[n]=t.ids;if(!n)continue;const o=a.assemblies.get(n.assemblyId);o&&"InMemoryFileDriver"===o.backendDriverType&&(e.apolloDataStore.checkResults[t._id]=i.getSnapshot(t))}return e}})}const Ua={0:2,1:1,2:0},Ba={3:0,4:1,5:2};function _a(e,t){const a=e.getPlugin("LinearGenomeViewPlugin"),{BaseLinearDisplay:o}=a.exports;return o.named("SixFrameFeatureDisplay").props({type:i.types.literal("SixFrameFeatureDisplay"),configuration:n.ConfigurationReference(t),apolloRowHeight:20,detailsMinHeight:200,showStartCodons:!1,showStopCodons:!0,showIntronLines:!0}).volatile((()=>({apolloFeatureUnderMouse:void 0,apolloRowUnderMouse:void 0}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...G.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get regions(){let t;try{({blockDefinitions:t}=e)}catch{return[]}return t.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))},regionCannotBeRendered(){const t=r.getContainingView(e);if(t&&t.bpPerPx>=200)return"Zoom in to see annotations"},get session(){return r.getSession(e)}}))).actions((e=>{let t=[];return{afterAttach(){i.addDisposer(e,l.autorun((()=>{const n=r.getSession(e);if(r.getContainingView(e).initialized){if(e.regionCannotBeRendered())return;const a=[],o=[];for(const n of e.blockDefinitions.contentBlocks)a.push(n.key),t.includes(n.key)||o.push(n);n.apolloDataStore.loadFeatures(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),n.apolloDataStore.loadRefSeq(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),t=a}}),{name:"SixFrameFeatureDisplay"}))}}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get changeManager(){return r.getSession(e).apolloDataStore.changeManager},get sequence(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName),r=o?.getSequence(e.start,e.end);a.set(e.start,r??"")}return a},get features(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName);let r=a.get(e.refName);r||(r=new Map,a.set(e.refName,r));for(const[t,n]of o?.features.entries()??new Map)e.start<n.end&&e.end>n.start&&r.set(t,n)}return a},get featuresMinMax(){const e={};for(const[t,n]of this.features||[]){let a,o;for(const[,e]of n)void 0===a&&({min:a}=e),void 0===o&&({max:o}=e),e.min<a&&({min:a}=e),e.max>o&&({max:o}=e);void 0!==a&&void 0!==o&&(e[t]=[a,o])}return e},get codonLayout(){const e=new Map;let t="",n=0;for(const[e,a]of this.sequence||[])a&&(t||(n=e),t+=a);for(let a=0;a<6;a++){const o=[],s=[],l=a in Ba;let i,c,u;l?(i=(t.length+n)%3,c=(Ba[a]+i+3)%3,u=r.reverse(t).slice(c)):(i=3-n%3,c=(Ua[a]+i+3)%3,u=t.slice(c));for(let e=0;e<u.length;e+=3){const t=u.slice(e,e+3),a=l?r.reverse(r.revcom(t)):t,i=l?n+u.length-(3+e):n+e+c;r.defaultStarts.includes(a.toUpperCase())?o.push(i):r.defaultStops.includes(a.toUpperCase())&&s.push(i)}e.set(a,{starts:o,stops:s})}return e},get featureLayout(){const e=new Map;for(const[t,n]of this.features||[]){if(!n)continue;const a=this.featuresMinMax[t];if(!a)continue;const[o,r]=a,s=[],l=6;for(let t=0;t<l;t++){const t=s.length;s[t]=Array.from({length:r-o}),e.set(t,[])}for(const t of[...n.values()].sort(((e,t)=>{const{max:n,min:a}=e,{max:o,min:r}=t;return a-r||n-o})))for(const[,n]of t.children??new Map)if("mRNA"===n.type)for(const[,a]of n.children||new Map){let o;if("CDS"===a.type){let r;a.discontinuousLocations.length>0?({discontinuousLocations:r}=a):r=[a];for(const a of r){const r=a.start+3,s=a.end-3;for(const[l,{stops:i}]of this.codonLayout)if((l<3&&1===t.strand||l>=3&&-1===t.strand)&&0===i.filter((e=>e>=r&&e<=s)).length){o=l;const t=e.get(o);t?.push([n.featureId,a]);break}}}}}return e},getAssemblyId(t){const{assemblyManager:n}=r.getSession(e),a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return r.getSession(e).apolloSelectedFeature},get setSelectedFeature(){return r.getSession(e).apolloSetSelectedFeature}}))).actions((e=>({setSelectedFeature(t){r.getSession(e).apolloSetSelectedFeature(t)},setApolloFeatureUnderMouse(t){e.apolloFeatureUnderMouse=t},setApolloRowUnderMouse(t){e.apolloRowUnderMouse=t},toggleShowStartCodons(){e.showStartCodons=!e.showStartCodons},toggleShowStopCodons(){e.showStopCodons=!e.showStopCodons},toggleShowIntronLines(){e.showIntronLines=!e.showIntronLines}}))).views((e=>({get highestRow(){return 0===e.featureLayout.size?0:Math.max(...e.featureLayout.keys())},get featuresHeight(){return(this.highestRow+1)*e.apolloRowHeight},get detailsHeight(){return Math.max(e.detailsMinHeight,e.height-this.featuresHeight)},trackMenuItems:()=>[{label:"Show start codons",type:"checkbox",checked:e.showStartCodons,onClick:()=>{e.toggleShowStartCodons()}},{label:"Show stop codons",type:"checkbox",checked:e.showStopCodons,onClick:()=>{e.toggleShowStopCodons()}},{label:"Show intron lines",type:"checkbox",checked:e.showIntronLines,onClick:()=>{e.toggleShowIntronLines()}}]})))}var ja=n.ConfigurationSchema("ApolloRefNameAliasAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});const Oa="undefined"==typeof sessionStorage;class $a extends B.BaseAdapter{refNameAliases;async getRefNameAliases(){const e=n.readConfObject(this.config,"assemblyId");if(!Oa){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)throw new Error("No Apollo data store found");const n=t.getBackendDriver(e);return await n.getRefNameAliases(e)}const t=await new Promise(((t,n)=>{const a=setTimeout((()=>{n(new Error("timeout"))}),2e4),o=q.nanoid(),r=e=>{const n=e.data;(function(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo&&"refNameAliases"in e})(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),t(n.refNameAliases))};addEventListener("message",r),rpcServer.emit("apollo",{apollo:!0,method:"getRefNameAliases",assembly:e,messageId:o})}));return this.refNameAliases=t,t}freeResources(){}}const Ga="WorkerGlobalScope"in globalThis;for(const[n,a]of Object.entries(t.changes))e.changeRegistry.registerChange(n,a);const Wa=new t.CDSCheck;e.checkRegistry.registerCheck(Wa.name,Wa),t.validationRegistry.registerValidation(new t.CoreValidation),t.validationRegistry.registerValidation(new t.ParentChildValidation),exports.default=class extends Z.default{name="ApolloPlugin";version="0.2.2";configurationSchema=Qt;install(e){!function(e){e.addAdapterType((()=>new he.default({name:"ApolloSequenceAdapter",configSchema:zt,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:Ht})))}(e),function(e){e.addAdapterType((()=>new he.default({name:"ApolloRefNameAliasAdapter",configSchema:ja,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:$a})))}(e),function(e){e.addTextSearchAdapterType((()=>new a.TextSearchAdapterType({name:"ApolloTextSearchAdapter",displayName:"Apollo text search adapter",configSchema:Zt,AdapterClass:Kt,description:"Apollo Text Search adapter"})))}(e),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloFeatureDetailsWidget",{});return new a.WidgetType({name:"ApolloFeatureDetailsWidget",heading:"Apollo feature details",configSchema:e,stateModel:gn,ReactComponent:mn})})),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloTranscriptDetails",{});return new a.WidgetType({name:"ApolloTranscriptDetails",heading:"Apollo transcript details",configSchema:e,stateModel:pn,ReactComponent:vn})})),e.addTrackType((()=>{const t=n.ConfigurationSchema("ApolloTrack",{adapter:""},{baseConfiguration:a.createBaseTrackConfig(e),explicitIdentifier:"trackId"});return new a.TrackType({name:"ApolloTrack",configSchema:t,stateModel:a.createBaseTrackModel(e,"ApolloTrack",t)})})),e.addInternetAccountType((()=>new a.InternetAccountType({name:"ApolloInternetAccount",configSchema:Ae,stateModel:$t(Ae)}))),e.addDisplayType((()=>new a.DisplayType({name:"LinearApolloDisplay",configSchema:Cn,stateModel:Ca(0,Cn),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:Ra}))),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("SixFrameFeatureDisplay",{renderer:Xt,height:{type:"number",defaultValue:120}},{baseConfiguration:a,explicitlyTyped:!0})}(e),o=function(e){const t=e.getPlugin("LinearGenomeViewPlugin");if(!t)throw new Error("LinearGenomeView plugin not found");const{BaseLinearDisplayComponent:n}=t.exports;return S.observer((function({model:e,...t}){const{classes:a}=Ta(),{height:o,selectedFeature:r}=e;let{detailsHeight:s}=e;return r||(s=0),re.default.createElement("div",{style:{height:e.height}},re.default.createElement("div",{className:a.shading,style:{height:o-s}},re.default.createElement(n,{model:e,...t})),re.default.createElement("div",{className:"testTrackLines"},re.default.createElement(Aa,{model:e})))}))}(e);return new a.DisplayType({name:"SixFrameFeatureDisplay",configSchema:t,stateModel:_a(e,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:o})})),e.addRendererType((()=>new Yt({name:"ApolloSixFrameRenderer",ReactComponent:Jt,configSchema:Xt,pluginManager:e}))),e.addToExtensionPoint("Core-extendSession",Pa.bind(this,e)),e.addToExtensionPoint("Core-extendPluggableElement",(e=>{if("LinearGenomeView"===e.name){const{stateModel:t}=e,n=t.views((e=>{const t=e.rubberBandMenuItems;return{rubberBandMenuItems:()=>[...t(),{label:"Add new feature",icon:Q.default,onClick:()=>{const t=r.getSession(e),{leftOffset:n,rightOffset:a}=e,o=e.getSelectedRegions(n,a);t.queueDialog((e=>[lt,{session:t,handleClose:()=>{e()},region:o[0],changeManager:t.apolloDataStore.changeManager}]))}}]}}));e.stateModel=n}return e})),e.addToExtensionPoint("Core-extendPluggableElement",en),Ga||e.addToExtensionPoint("Core-extendWorker",(t=>"on"in t&&t.on?(t.on("apollo",(async n=>{if("object"!=typeof(a=n)||null===a||!("apollo"in a)||!0!==a.apollo)return;var a;const{apollo:o,messageId:r,method:s}=n;switch(s){case"getSequence":{const{region:a}=n,{assemblyName:s}=a,l=e.rootModel?.session?.apolloDataStore;if(!l)break;const i=l.getBackendDriver(s),{seq:c}=await i.getSequence(a);t.workers[0].postMessage({apollo:o,messageId:r,sequence:c});break}case"getRegions":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRegions(a);t.workers[0].postMessage({apollo:o,messageId:r,regions:i});break}case"getRefNameAliases":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRefNameAliases(a);t.workers[0].postMessage({apollo:o,messageId:r,refNameAliases:i});break}}})),t):t))}configure(e){r.isAbstractMenuManager(e.rootModel)&&(e.rootModel.appendToMenu("Apollo",{label:"Download GFF3",onClick:e=>{e.queueDialog((t=>[ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Manage Checks",onClick:e=>{e.queueDialog((t=>[pt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View Change Log",onClick:e=>{e.queueDialog((t=>[Nt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Open local GFF3 file",onClick:e=>{e.queueDialog((t=>[Tt,{session:e,handleClose:()=>{t()},inMemoryFileDriver:e.apolloDataStore.inMemoryFileDriver}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View check results",onClick:e=>{e.queueDialog((t=>[Mt,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Log out",onClick:e=>{e.queueDialog((t=>[gt,{session:e,handleClose:()=>{t()}}]))}}))}};
2
2
  //# sourceMappingURL=jbrowse-plugin-apollo.cjs.production.min.js.map