diff --git a/index.js b/index.js index 9b5984d..760dc0b 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,8 @@ -async function M(h){return await new Promise(a=>{setTimeout(a,h)})}var O=class{constructor(t){this.sparqlEnpointUri=t}async getSparqlResultSet(t,a={},n=""){ -a.headers=a.headers||{},a.headers.Accept="application/sparql-results+json";let l=0,c=async()=>{try{let u=await fetch(this. -sparqlEnpointUri+"?query="+encodeURIComponent(t),a);if(!u.ok)throw new Error("Response not ok. Status "+u.status);return await u. -json()}catch(u){if(a.signal?.aborted)throw u;if(l<10){let p=50*(1<{setTimeout(n,h)})}var A=class{constructor(t){this.sparqlEnpointUri=t}async getSparqlResultSet(t,n={},a=""){ +n.headers=n.headers||{},n.headers.Accept="application/sparql-results+json";let d=0,c=async()=>{try{let u=await fetch(this. +sparqlEnpointUri+"?query="+encodeURIComponent(t),n);if(!u.ok)throw new Error("Response not ok. Status "+u.status);return await u. +json()}catch(u){if(n.signal?.aborted)throw u;if(d<10){let p=50*(1< PREFIX dwc: @@ -233,33 +233,32 @@ LIMIT 500`,B=h=>`${x} WHERE { } } ${P} -LIMIT 500`;function R(h,t){let a=h.split(/\s*[,]\s*/),n=t.split(/\s*[,]\s*/),l=a.length>0&&/\d{4}/.test(a.at(-1))?a.pop():null,c=n. -length>0&&/\d{4}/.test(n.at(-1))?n.pop():null,u=a.length>0&&/\s*et\.?\s*al\.?/.test(a.at(-1)),p=n.length>0&&/\s*et\.?\s*al\.?/. -test(n.at(-1));if(u&&(a[a.length-1]=a[a.length-1].replace(/\s*et\.?\s*al\.?/,"")),p&&(n[n.length-1]=n[n.length-1].replace( -/\s*et\.?\s*al\.?/,"")),!u&&!p&&a.length!=n.length)return null;let r=[],o=0;for(;o=c.length?h:t}return null}function Q(h,t){return h. -localeCompare(t,"en",{sensitivity:"base",usage:"search"})===0}var b=class{isFinished=!1;monitor=new EventTarget;controller=new AbortController;sparqlEndpoint;names=[];pushName(t){this. -names.push(t),this.monitor.dispatchEvent(new CustomEvent("updated"))}finish(){this.isFinished=!0,this.monitor.dispatchEvent( -new CustomEvent("updated"))}expanded=new Set;acceptedCol=new Map;treatments=new Map;ignoreDeprecatedCoL;startWithSubTaxa;constructor(t,a,n=!0,l=!1){ -if(this.sparqlEndpoint=t,this.ignoreDeprecatedCoL=n,this.startWithSubTaxa=l,a.startsWith("http"))this.getName(a,{searchTerm:!0, +LIMIT 500`;function R(h,t){let n=h.split(/\s*[,]\s*/),a=t.split(/\s*[,]\s*/),d=n.length>0&&/\d{4}/.test(n.at(-1))?n.pop():null,c=a. +length>0&&/\d{4}/.test(a.at(-1))?a.pop():null,u=n.length>0&&/\s*et\.?\s*al\.?/.test(n.at(-1)),p=a.length>0&&/\s*et\.?\s*al\.?/. +test(a.at(-1));if(u&&(n[n.length-1]=n[n.length-1].replace(/\s*et\.?\s*al\.?/,"")),p&&(a[a.length-1]=a[a.length-1].replace( +/\s*et\.?\s*al\.?/,"")),!u&&!p&&n.length!=a.length)return null;let i=[],o=0;for(;o=c.length?h:t}return null}function Q(h,t){return h. +localeCompare(t,"en",{sensitivity:"base",usage:"search"})===0}var b=class{isFinished=!1;monitor=new EventTarget;controller=new AbortController;sparqlEndpoint;fetchOptions={signal:this. +controller.signal,cache:"force-cache"};names=[];pushName(t){this.names.push(t),this.monitor.dispatchEvent(new CustomEvent( +"updated"))}finish(){this.isFinished=!0,this.monitor.dispatchEvent(new CustomEvent("updated"))}expanded=new Set;acceptedCol=new Map;treatments=new Map;ignoreDeprecatedCoL;startWithSubTaxa;constructor(t,n,a=!0,d=!1){ +if(this.sparqlEndpoint=t,this.ignoreDeprecatedCoL=a,this.startWithSubTaxa=d,n.startsWith("http"))this.getName(n,{searchTerm:!0, subTaxon:!1}).catch(c=>{console.log("SynoGroup Failure: ",c),this.controller.abort("SynoGroup Failed")}).finally(()=>this. -finish());else{let c=[...a.split(" ").filter(u=>!!u),void 0,void 0];this.getNameFromLatin(c,{searchTerm:!0,subTaxon:!1}). -finally(()=>this.finish())}}findName(t){let a;for(let n of this.names){if(n.taxonNameURI===t||n.col?.colURI===t){a=n;break} -let l=n.authorizedNames.find(c=>c.col?.colURI===t||c.taxonConceptURIs.includes(t));if(l){a=l;break}}return a?Promise.resolve( -a):new Promise((n,l)=>{this.monitor.addEventListener("updated",()=>{(this.names.length===0||this.isFinished)&&l();let c=this. -names.at(-1);if(c.taxonNameURI===t||c.col?.colURI===t){n(c);return}let u=c.authorizedNames.find(p=>p.col?.colURI===t||p. -taxonConceptURIs.includes(t));if(u){n(u);return}})})}async getName(t,a){if(this.expanded.has(t)){console.log("Skipping k\ -nown",t);return}if(this.controller.signal?.aborted)return Promise.reject();let n;if(t.startsWith("https://www.catalogueo\ -flife.org"))n=await this.sparqlEndpoint.getSparqlResultSet(_(t),{signal:this.controller.signal},`NameFromCol ${t}`);else if(t. -startsWith("http://taxon-concept.plazi.org"))n=await this.sparqlEndpoint.getSparqlResultSet(F(t),{signal:this.controller. -signal},`NameFromTC ${t}`);else if(t.startsWith("http://taxon-name.plazi.org"))n=await this.sparqlEndpoint.getSparqlResultSet( -B(t),{signal:this.controller.signal},`NameFromTN ${t}`);else throw`Cannot handle name-uri <${t}> !`;await this.handleName( -n,a),this.startWithSubTaxa&&a.searchTerm&&!a.subTaxon&&await this.getSubtaxa(t)}async getSubtaxa(t){let a=t.startsWith("\ -http://taxon-concept.plazi.org")?` +finish());else{let c=[...n.split(" ").filter(u=>!!u),void 0,void 0];this.getNameFromLatin(c,{searchTerm:!0,subTaxon:!1}). +finally(()=>this.finish())}}findName(t){let n;for(let a of this.names){if(a.taxonNameURI===t||a.col?.colURI===t){n=a;break} +let d=a.authorizedNames.find(c=>c.col?.colURI===t||c.taxonConceptURIs.includes(t));if(d){n=d;break}}return n?Promise.resolve( +n):new Promise((a,d)=>{this.monitor.addEventListener("updated",()=>{(this.names.length===0||this.isFinished)&&d();let c=this. +names.at(-1);if(c.taxonNameURI===t||c.col?.colURI===t){a(c);return}let u=c.authorizedNames.find(p=>p.col?.colURI===t||p. +taxonConceptURIs.includes(t));if(u){a(u);return}})})}async getName(t,n){if(this.expanded.has(t)){console.log("Skipping k\ +nown",t);return}if(this.controller.signal?.aborted)return Promise.reject();let a;if(t.startsWith("https://www.catalogueo\ +flife.org"))a=await this.sparqlEndpoint.getSparqlResultSet(_(t),this.fetchOptions,`NameFromCol ${t}`);else if(t.startsWith( +"http://taxon-concept.plazi.org"))a=await this.sparqlEndpoint.getSparqlResultSet(F(t),this.fetchOptions,`NameFromTC ${t}`);else if(t. +startsWith("http://taxon-name.plazi.org"))a=await this.sparqlEndpoint.getSparqlResultSet(B(t),this.fetchOptions,`NameFro\ +mTN ${t}`);else throw`Cannot handle name-uri <${t}> !`;await this.handleName(a,n),this.startWithSubTaxa&&n.searchTerm&&!n. +subTaxon&&await this.getSubtaxa(t)}async getSubtaxa(t){let n=t.startsWith("http://taxon-concept.plazi.org")?` PREFIX trt: SELECT DISTINCT ?sub WHERE { BIND(<${t}> as ?url) @@ -272,50 +271,49 @@ SELECT DISTINCT ?sub WHERE { BIND(<${t}> as ?url) ?sub (dwc:parent|trt:hasParentName)* ?url . } -LIMIT 5000`;if(this.controller.signal?.aborted)return Promise.reject();let l=(await this.sparqlEndpoint.getSparqlResultSet( -a,{signal:this.controller.signal},`Subtaxa ${t}`)).results.bindings.map(c=>c.sub?.value).filter(c=>c&&!this.expanded.has( -c));await Promise.allSettled(l.map(c=>this.getName(c,{searchTerm:!0,subTaxon:!0})))}async getNameFromLatin([t,a,n],l){let c=`\ - +LIMIT 5000`;if(this.controller.signal?.aborted)return Promise.reject();let d=(await this.sparqlEndpoint.getSparqlResultSet( +n,this.fetchOptions,`Subtaxa ${t}`)).results.bindings.map(c=>c.sub?.value).filter(c=>c&&!this.expanded.has(c));await Promise. +allSettled(d.map(c=>this.getName(c,{searchTerm:!0,subTaxon:!0})))}async getNameFromLatin([t,n,a],d){let c=` PREFIX dwc: SELECT DISTINCT ?uri WHERE { ?uri dwc:genus|dwc:genericName "${t}" . - ${a?`?uri dwc:species|dwc:specificEpithet "${a}" .`:"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species\ + ${n?`?uri dwc:species|dwc:specificEpithet "${n}" .`:"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species\ . }"} - ${n?`?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet "${n}" .`:"FILTER NOT EXISTS { ?uri dwc:subSpec\ + ${a?`?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet "${a}" .`:"FILTER NOT EXISTS { ?uri dwc:subSpec\ ies|dwc:variety|dwc:form|dwc:infraspecificEpithet ?infrasp . }"} } LIMIT 500`;if(this.controller.signal?.aborted)return Promise.reject();let p=(await this.sparqlEndpoint.getSparqlResultSet( -c,{signal:this.controller.signal},`NameFromLatin ${t} ${a} ${n}`)).results.bindings.map(r=>r.uri?.value).filter(r=>r&&!this. -expanded.has(r));await Promise.allSettled(p.map(r=>this.getName(r,l)))}async handleName(t,a){let n=[],l=e=>{switch(e){case"\ -variety":return"var.";case"subspecies":return"subsp.";case"form":return"f.";default:return e}},c=(t.results.bindings[0]. -name?t.results.bindings[0].authority?t.results.bindings[0].name.value.replace(t.results.bindings[0].authority.value,""): -t.results.bindings[0].name.value:t.results.bindings[0].genus.value+(t.results.bindings[0].section?.value?` sect. ${t.results. -bindings[0].section.value}`:"")+(t.results.bindings[0].subgenus?.value?` (${t.results.bindings[0].subgenus.value})`:"")+ -(t.results.bindings[0].species?.value?` ${t.results.bindings[0].species.value}`:"")+(t.results.bindings[0].infrasp?.value? -` ${l(t.results.bindings[0].rank.value)} ${t.results.bindings[0].infrasp.value}`:"")).trim(),u,p=[],r=t.results.bindings[0]. -tn?.value;if(r){if(this.expanded.has(r))return;this.expanded.add(r)}let o=new Set;for(let e of t.results.bindings){if(e. -col){let s=e.col.value;if(e.authority?.value){if(!p.find(i=>i.col?.colURI===s)){if(this.expanded.has(s)){console.log("Sk\ -ipping known",s);return}o.has(s)||(o.add(s),p.push({displayName:c,authority:e.authority.value,authorities:[e.authority.value], -col:{colURI:e.col.value,acceptedURI:e.acceptedcol?.value??"INAVLID COL"},taxonConceptURIs:[],treatments:{def:new Set,aug:new Set, -dpr:new Set,cite:new Set}}))}}else{if(this.expanded.has(s)){console.log("Skipping known",s);return}u&&u.colURI!==s&&console. -log("Duplicate unathorized COL:",u,s),u={colURI:s,acceptedURI:e.acceptedcol?.value??"INVALID COL"}}}if(e.tc&&e.tcAuth&&e. -tcAuth.value){if(this.expanded.has(e.tc.value)){console.log("Skipping known",e.tc.value);return}else if(!o.has(e.tc.value)){ -o.add(e.tc.value);let s=this.makeTreatmentSet(e.defs?.value.split("|")),i=this.makeTreatmentSet(e.augs?.value.split("|")), -T=this.makeTreatmentSet(e.dprs?.value.split("|")),v=this.makeTreatmentSet(e.cites?.value.split("|"));s.forEach(I=>n.push( -I)),i.forEach(I=>n.push(I)),T.forEach(I=>n.push(I));let N=p.find(I=>R(I.authority,e.tcAuth.value)!==null);if(N){let I=e. -tcAuth.value;N.authority=R(N.authority,I),N.authorities.push(...e.tcAuth.value.split(" / ")),N.taxonConceptURIs.push(e.tc. -value),N.treatments={def:N.treatments.def.union(s),aug:N.treatments.aug.union(i),dpr:N.treatments.dpr.union(T),cite:N.treatments. -cite.union(v)}}else p.push({displayName:c,authority:e.tcAuth.value,authorities:e.tcAuth.value.split(" / "),taxonConceptURIs:[ -e.tc.value],treatments:{def:s,aug:i,dpr:T,cite:v}})}}}let m=this.makeTreatmentSet(t.results.bindings[0].tntreats?.value. -split("|"));m.forEach(e=>n.push(e));let d={kingdom:t.results.bindings[0].kingdom.value,displayName:c,rank:t.results.bindings[0]. -rank.value,taxonNameURI:r,authorizedNames:p,col:u,justification:a,treatments:{treats:m,cite:this.makeTreatmentSet(t.results. -bindings[0].tncites?.value.split("|"))},vernacularNames:r?this.getVernacular(r):Promise.resolve(new Map)};for(let e of d. -authorizedNames){e.col&&this.expanded.add(e.col.colURI);for(let s of e.taxonConceptURIs)this.expanded.add(s)}this.pushName( -d);let g=new Map;(await Promise.all(n.map(e=>e.details.then(s=>[e,s])))).map(([e,s])=>{s.treats.aug.difference(this.expanded). -forEach(i=>g.set(i,e)),s.treats.def.difference(this.expanded).forEach(i=>g.set(i,e)),s.treats.dpr.difference(this.expanded). -forEach(i=>g.set(i,e)),s.treats.treattn.difference(this.expanded).forEach(i=>g.set(i,e))}),u&&await this.findColSynonyms( -u.colURI,d),await Promise.allSettled([...p.filter(e=>e.col).map(e=>this.findColSynonyms(e.col.colURI,d)),...[...g].map(([ -e,s])=>this.getName(e,{searchTerm:!1,parent:d,treatment:s}))])}async findColSynonyms(t,a){let n=` +c,this.fetchOptions,`NameFromLatin ${t} ${n} ${a}`)).results.bindings.map(i=>i.uri?.value).filter(i=>i&&!this.expanded.has( +i));await Promise.allSettled(p.map(i=>this.getName(i,d)))}async handleName(t,n){let a=[],d=e=>{switch(e){case"variety":return"\ +var.";case"subspecies":return"subsp.";case"form":return"f.";default:return e}},c=(t.results.bindings[0].name?t.results.bindings[0]. +authority?t.results.bindings[0].name.value.replace(t.results.bindings[0].authority.value,""):t.results.bindings[0].name. +value:t.results.bindings[0].genus.value+(t.results.bindings[0].section?.value?` sect. ${t.results.bindings[0].section.value}`: +"")+(t.results.bindings[0].subgenus?.value?` (${t.results.bindings[0].subgenus.value})`:"")+(t.results.bindings[0].species?. +value?` ${t.results.bindings[0].species.value}`:"")+(t.results.bindings[0].infrasp?.value?` ${d(t.results.bindings[0].rank. +value)} ${t.results.bindings[0].infrasp.value}`:"")).trim(),u,p=[],i=t.results.bindings[0].tn?.value;if(i){if(this.expanded. +has(i))return;this.expanded.add(i)}let o=new Set;for(let e of t.results.bindings){if(e.col){let s=e.col.value;if(e.authority?. +value){if(!p.find(r=>r.col?.colURI===s)){if(this.expanded.has(s)){console.log("Skipping known",s);return}o.has(s)||(o.add( +s),p.push({displayName:c,authority:e.authority.value,authorities:[e.authority.value],col:{colURI:e.col.value,acceptedURI:e. +acceptedcol?.value??"INAVLID COL"},taxonConceptURIs:[],treatments:{def:new Set,aug:new Set,dpr:new Set,cite:new Set}}))}}else{ +if(this.expanded.has(s)){console.log("Skipping known",s);return}u&&u.colURI!==s&&console.log("Duplicate unathorized COL:", +u,s),u={colURI:s,acceptedURI:e.acceptedcol?.value??"INVALID COL"}}}if(e.tc&&e.tcAuth&&e.tcAuth.value){if(this.expanded.has( +e.tc.value)){console.log("Skipping known",e.tc.value);return}else if(!o.has(e.tc.value)){o.add(e.tc.value);let s=this.makeTreatmentSet( +e.defs?.value.split("|")),r=this.makeTreatmentSet(e.augs?.value.split("|")),T=this.makeTreatmentSet(e.dprs?.value.split( +"|")),v=this.makeTreatmentSet(e.cites?.value.split("|"));s.forEach(I=>a.push(I)),r.forEach(I=>a.push(I)),T.forEach(I=>a. +push(I));let N=p.find(I=>R(I.authority,e.tcAuth.value)!==null);if(N){let I=e.tcAuth.value;N.authority=R(N.authority,I),N. +authorities.push(...e.tcAuth.value.split(" / ")),N.taxonConceptURIs.push(e.tc.value),N.treatments={def:N.treatments.def. +union(s),aug:N.treatments.aug.union(r),dpr:N.treatments.dpr.union(T),cite:N.treatments.cite.union(v)}}else p.push({displayName:c, +authority:e.tcAuth.value,authorities:e.tcAuth.value.split(" / "),taxonConceptURIs:[e.tc.value],treatments:{def:s,aug:r,dpr:T, +cite:v}})}}}let m=this.makeTreatmentSet(t.results.bindings[0].tntreats?.value.split("|"));m.forEach(e=>a.push(e));let l={ +kingdom:t.results.bindings[0].kingdom.value,displayName:c,rank:t.results.bindings[0].rank.value,taxonNameURI:i,authorizedNames:p, +col:u,justification:n,treatments:{treats:m,cite:this.makeTreatmentSet(t.results.bindings[0].tncites?.value.split("|"))}, +vernacularNames:i?this.getVernacular(i):Promise.resolve(new Map)};for(let e of l.authorizedNames){e.col&&this.expanded.add( +e.col.colURI);for(let s of e.taxonConceptURIs)this.expanded.add(s)}this.pushName(l);let g=new Map;(await Promise.all(a.map( +e=>e.details.then(s=>[e,s])))).map(([e,s])=>{s.treats.aug.difference(this.expanded).forEach(r=>g.set(r,e)),s.treats.def. +difference(this.expanded).forEach(r=>g.set(r,e)),s.treats.dpr.difference(this.expanded).forEach(r=>g.set(r,e)),s.treats. +treattn.difference(this.expanded).forEach(r=>g.set(r,e))}),u&&await this.findColSynonyms(u.colURI,l),await Promise.allSettled( +[...p.filter(e=>e.col).map(e=>this.findColSynonyms(e.col.colURI,l)),...[...g].map(([e,s])=>this.getName(e,{searchTerm:!1, +parent:l,treatment:s}))])}async findColSynonyms(t,n){let a=` PREFIX dwc: SELECT DISTINCT ?current ?current_status (GROUP_CONCAT(DISTINCT ?dpr; separator="|") AS ?dprs) WHERE { BIND(<${t}> AS ?col) @@ -330,18 +328,18 @@ SELECT DISTINCT ?current ?current_status (GROUP_CONCAT(DISTINCT ?dpr; separator= BIND(?col AS ?current) } } -GROUP BY ?current ?current_status`;if(this.acceptedCol.has(t))return[];let l=await this.sparqlEndpoint.getSparqlResultSet( -n,{signal:this.controller.signal},`AcceptedCol ${t}`),c=[];for(let u of l.results.bindings)for(let p of u.dprs.value.split( -"|"))p&&(this.acceptedCol.has(u.current.value)||(this.acceptedCol.set(u.current.value,u.current.value),c.push(this.getName( -u.current.value,{searchTerm:!1,parent:a}))),this.acceptedCol.set(p,u.current.value),this.ignoreDeprecatedCoL||c.push(this. -getName(p,{searchTerm:!1,parent:a})));return l.results.bindings.length===0?(this.acceptedCol.has(t)||this.acceptedCol.set( -t,"INVALID COL"),Promise.all(c)):(this.acceptedCol.has(t)||this.acceptedCol.set(t,t),Promise.all(c))}async getVernacular(t){ -let a=new Map,n=`SELECT DISTINCT ?n WHERE { <${t}> ?n . }`,l=(await this.sparqlEndpoint. -getSparqlResultSet(n,{signal:this.controller.signal},`Vernacular ${t}`)).results.bindings;for(let c of l)c.n?.value&&(c. -n["xml:lang"]?a.has(c.n["xml:lang"])?a.get(c.n["xml:lang"]).push(c.n.value):a.set(c.n["xml:lang"],[c.n.value]):a.has("??")? -a.get("??").push(c.n.value):a.set("??",[c.n.value]));return a}makeTreatmentSet(t){return t?new Set(t.filter(a=>!!a).map( -a=>{let[n,l]=a.split(">");if(!this.treatments.has(n)){let c=this.getTreatmentDetails(n);this.treatments.set(n,{url:n,date:l? -parseInt(l,10):void 0,details:c})}return this.treatments.get(n)})):new Set}async getTreatmentDetails(t){let a=` +GROUP BY ?current ?current_status`;if(this.acceptedCol.has(t))return[];let d=await this.sparqlEndpoint.getSparqlResultSet( +a,this.fetchOptions,`AcceptedCol ${t}`),c=[];for(let u of d.results.bindings)for(let p of u.dprs.value.split("|"))p&&(this. +acceptedCol.has(u.current.value)||(this.acceptedCol.set(u.current.value,u.current.value),c.push(this.getName(u.current.value, +{searchTerm:!1,parent:n}))),this.acceptedCol.set(p,u.current.value),this.ignoreDeprecatedCoL||c.push(this.getName(p,{searchTerm:!1, +parent:n})));return d.results.bindings.length===0?(this.acceptedCol.has(t)||this.acceptedCol.set(t,"INVALID COL"),Promise. +all(c)):(this.acceptedCol.has(t)||this.acceptedCol.set(t,t),Promise.all(c))}async getVernacular(t){let n=new Map,a=`SELE\ +CT DISTINCT ?n WHERE { <${t}> ?n . }`,d=(await this.sparqlEndpoint.getSparqlResultSet( +a,this.fetchOptions,`Vernacular ${t}`)).results.bindings;for(let c of d)c.n?.value&&(c.n["xml:lang"]?n.has(c.n["xml:lang"])? +n.get(c.n["xml:lang"]).push(c.n.value):n.set(c.n["xml:lang"],[c.n.value]):n.has("??")?n.get("??").push(c.n.value):n.set( +"??",[c.n.value]));return n}makeTreatmentSet(t){return t?new Set(t.filter(n=>!!n).map(n=>{let[a,d]=n.split(">");if(!this. +treatments.has(a)){let c=this.getTreatmentDetails(a);this.treatments.set(a,{url:a,date:d?parseInt(d,10):void 0,details:c})} +return this.treatments.get(a)})):new Set}async getTreatmentDetails(t){let n=` PREFIX dc: PREFIX dwc: PREFIX dwcFP: @@ -407,15 +405,15 @@ WHERE { } } GROUP BY ?date ?title ?mc`;if(this.controller.signal.aborted)return{materialCitations:[],figureCitations:[],treats:{def:new Set, -aug:new Set,dpr:new Set,citetc:new Set,treattn:new Set,citetn:new Set}};try{let n=await this.sparqlEndpoint.getSparqlResultSet( -a,{signal:this.controller.signal},`TreatmentDetails ${t}`),l=n.results.bindings.filter(r=>r.mc&&r.catalogNumbers?.value). -map(r=>{let o=r.httpUris?.value?.split("|");return{catalogNumber:r.catalogNumbers.value,collectionCode:r.collectionCodes?. -value||void 0,typeStatus:r.typeStatuss?.value||void 0,countryCode:r.countryCodes?.value||void 0,stateProvince:r.stateProvinces?. -value||void 0,municipality:r.municipalitys?.value||void 0,county:r.countys?.value||void 0,locality:r.localitys?.value||void 0, -verbatimLocality:r.verbatimLocalitys?.value||void 0,recordedBy:r.recordedBys?.value||void 0,eventDate:r.eventDates?.value|| -void 0,samplingProtocol:r.samplingProtocols?.value||void 0,decimalLatitude:r.decimalLatitudes?.value||void 0,decimalLongitude:r. -decimalLongitudes?.value||void 0,verbatimElevation:r.verbatimElevations?.value||void 0,gbifOccurrenceId:r.gbifOccurrenceIds?. -value||void 0,gbifSpecimenId:r.gbifSpecimenIds?.value||void 0,httpUri:o?.length?o:void 0}}),c=` +aug:new Set,dpr:new Set,citetc:new Set,treattn:new Set,citetn:new Set}};try{let a=await this.sparqlEndpoint.getSparqlResultSet( +n,this.fetchOptions,`TreatmentDetails ${t}`),d=a.results.bindings.filter(i=>i.mc&&i.catalogNumbers?.value).map(i=>{let o=i. +httpUris?.value?.split("|");return{catalogNumber:i.catalogNumbers.value,collectionCode:i.collectionCodes?.value||void 0, +typeStatus:i.typeStatuss?.value||void 0,countryCode:i.countryCodes?.value||void 0,stateProvince:i.stateProvinces?.value|| +void 0,municipality:i.municipalitys?.value||void 0,county:i.countys?.value||void 0,locality:i.localitys?.value||void 0,verbatimLocality:i. +verbatimLocalitys?.value||void 0,recordedBy:i.recordedBys?.value||void 0,eventDate:i.eventDates?.value||void 0,samplingProtocol:i. +samplingProtocols?.value||void 0,decimalLatitude:i.decimalLatitudes?.value||void 0,decimalLongitude:i.decimalLongitudes?. +value||void 0,verbatimElevation:i.verbatimElevations?.value||void 0,gbifOccurrenceId:i.gbifOccurrenceIds?.value||void 0, +gbifSpecimenId:i.gbifSpecimenIds?.value||void 0,httpUri:o?.length?o:void 0}}),c=` PREFIX cito: PREFIX fabio: PREFIX dc: @@ -424,19 +422,19 @@ SELECT DISTINCT ?url ?description WHERE { ?cites a fabio:Figure ; fabio:hasRepresentation ?url . OPTIONAL { ?cites dc:description ?description . } -} `,p=(await this.sparqlEndpoint.getSparqlResultSet(c,{signal:this.controller.signal},`TreatmentDetails/Figures ${t}`)). -results.bindings.filter(r=>r.url?.value).map(r=>({url:r.url.value,description:r.description?.value}));return{creators:n. -results.bindings[0]?.creators?.value,title:n.results.bindings[0]?.title?.value,materialCitations:l,figureCitations:p,treats:{ -def:new Set(n.results.bindings[0]?.defs?.value?n.results.bindings[0].defs.value.split("|"):void 0),aug:new Set(n.results. -bindings[0]?.augs?.value?n.results.bindings[0].augs.value.split("|"):void 0),dpr:new Set(n.results.bindings[0]?.dprs?.value? -n.results.bindings[0].dprs.value.split("|"):void 0),citetc:new Set(n.results.bindings[0]?.cites?.value?n.results.bindings[0]. -cites.value.split("|"):void 0),treattn:new Set(n.results.bindings[0]?.trttns?.value?n.results.bindings[0].trttns.value.split( -"|"):void 0),citetn:new Set(n.results.bindings[0]?.citetns?.value?n.results.bindings[0].citetns.value.split("|"):void 0)}}}catch(n){ -return console.warn("SPARQL Error: "+n),{materialCitations:[],figureCitations:[],treats:{def:new Set,aug:new Set,dpr:new Set, -citetc:new Set,treattn:new Set,citetn:new Set}}}}[Symbol.asyncIterator](){let t=0;return{next:()=>new Promise((a,n)=>{let l=()=>{ -if(this.controller.signal.aborted)n(new Error("SynyonymGroup has been aborted"));else if(t{this.monitor.removeEventListener("updated",c), -l()};this.monitor.addEventListener("updated",c)}};l()})}}};function U(h){let t=new Set(h);return Array.from(t)}var L=new URLSearchParams(document.location.search),X=!L.has("show_col"),Z=L.has("subtaxa"),W=L.has("sort_treatments_by_\ +} `,p=(await this.sparqlEndpoint.getSparqlResultSet(c,this.fetchOptions,`TreatmentDetails/Figures ${t}`)).results.bindings. +filter(i=>i.url?.value).map(i=>({url:i.url.value,description:i.description?.value}));return{creators:a.results.bindings[0]?. +creators?.value,title:a.results.bindings[0]?.title?.value,materialCitations:d,figureCitations:p,treats:{def:new Set(a.results. +bindings[0]?.defs?.value?a.results.bindings[0].defs.value.split("|"):void 0),aug:new Set(a.results.bindings[0]?.augs?.value? +a.results.bindings[0].augs.value.split("|"):void 0),dpr:new Set(a.results.bindings[0]?.dprs?.value?a.results.bindings[0]. +dprs.value.split("|"):void 0),citetc:new Set(a.results.bindings[0]?.cites?.value?a.results.bindings[0].cites.value.split( +"|"):void 0),treattn:new Set(a.results.bindings[0]?.trttns?.value?a.results.bindings[0].trttns.value.split("|"):void 0), +citetn:new Set(a.results.bindings[0]?.citetns?.value?a.results.bindings[0].citetns.value.split("|"):void 0)}}}catch(a){return console. +warn("SPARQL Error: "+a),{materialCitations:[],figureCitations:[],treats:{def:new Set,aug:new Set,dpr:new Set,citetc:new Set, +treattn:new Set,citetn:new Set}}}}[Symbol.asyncIterator](){let t=0;return{next:()=>new Promise((n,a)=>{let d=()=>{if(this. +controller.signal.aborted)a(new Error("SynyonymGroup has been aborted"));else if(t{this.monitor.removeEventListener("updated",c),d()};this.monitor.addEventListener( +"updated",c)}};d()})}}};function U(h){let t=new Set(h);return Array.from(t)}var L=new URLSearchParams(document.location.search),X=!L.has("show_col"),Z=L.has("subtaxa"),W=L.has("sort_treatments_by_\ type"),J=L.get("server")||"https://treatment.ld.plazi.org/sparql",z=L.get("q")||"https://www.catalogueoflife.org/data/ta\ xon/3WD9M",k=document.getElementById("root");var f={def:'',collapse:'',empty:''},C=document.createElement("div");k.insertAdjacentElement( "beforebegin",C);C.append(`Finding Synonyms for ${z} `);var G=document.createElement("progress");C.append(G);var j=performance. -now(),Y=new O(J),S=new b(Y,z,X,Z),E=class extends HTMLElement{constructor(t,a){super(),this.innerHTML=f[a]??f.unknown;let n=document. -createElement("button");n.classList.add("icon","button"),n.innerHTML=f.expand,n.addEventListener("click",()=>{this.classList. -toggle("expanded")?n.innerHTML=f.collapse:n.innerHTML=f.expand});let l=document.createElement("span");t.date?l.innerText= -""+t.date:(l.classList.add("missing"),l.innerText="No Date"),this.append(l);let c=document.createElement("progress");this. +now(),Y=new A(J),S=new b(Y,z,X,Z),E=class extends HTMLElement{constructor(t,n){super(),this.innerHTML=f[n]??f.unknown;let a=document. +createElement("button");a.classList.add("icon","button"),a.innerHTML=f.expand,a.addEventListener("click",()=>{this.classList. +toggle("expanded")?a.innerHTML=f.collapse:a.innerHTML=f.expand});let d=document.createElement("span");t.date?d.innerText= +""+t.date:(d.classList.add("missing"),d.innerText="No Date"),this.append(d);let c=document.createElement("progress");this. append(": ",c);let u=document.createElement("a");u.classList.add("treatment","uri"),u.href=t.url,u.target="_blank",u.innerText= -t.url.replace("http://treatment.plazi.org/id/",""),u.innerHTML+=f.link,this.append(" ",u),this.append(n);let p=document. -createElement("div");p.classList.add("indent","details"),this.append(p),t.details.then(r=>{let o=document.createElement( -"span"),m=document.createElement("i");if(c.replaceWith(o," ",m),r.creators?o.innerText=r.creators:(o.classList.add("miss\ -ing"),o.innerText="No Authors"),r.title?m.innerText="\u201C"+r.title+"\u201D":(m.classList.add("missing"),m.innerText="N\ -o Title"),r.treats.def.size>0){let d=document.createElement("div");d.innerHTML=f.east,d.innerHTML+=f.def,(a==="def"||a=== -"cite")&&d.classList.add("hidden"),p.append(d),r.treats.def.forEach(g=>{let e=document.createElement("a");e.classList.add( -"taxon","uri");let s=g.replace("http://taxon-concept.plazi.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",d. -append(" ",e),S.findName(g).then(i=>{e.classList.remove("uri"),i.authority?e.innerText=i.displayName+" "+i.authority:e.innerText= -i.displayName},()=>{e.removeAttribute("href")})})}if(r.treats.aug.size>0||r.treats.treattn.size>0){let d=document.createElement( -"div");d.innerHTML=f.east,d.innerHTML+=f.aug,(a==="aug"||a==="cite")&&d.classList.add("hidden"),p.append(d),r.treats.aug. +t.url.replace("http://treatment.plazi.org/id/",""),u.innerHTML+=f.link,this.append(" ",u),this.append(a);let p=document. +createElement("div");p.classList.add("indent","details"),this.append(p),t.details.then(i=>{let o=document.createElement( +"span"),m=document.createElement("i");if(c.replaceWith(o," ",m),i.creators?o.innerText=i.creators:(o.classList.add("miss\ +ing"),o.innerText="No Authors"),i.title?m.innerText="\u201C"+i.title+"\u201D":(m.classList.add("missing"),m.innerText="N\ +o Title"),i.treats.def.size>0){let l=document.createElement("div");l.innerHTML=f.east,l.innerHTML+=f.def,(n==="def"||n=== +"cite")&&l.classList.add("hidden"),p.append(l),i.treats.def.forEach(g=>{let e=document.createElement("a");e.classList.add( +"taxon","uri");let s=g.replace("http://taxon-concept.plazi.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",l. +append(" ",e),S.findName(g).then(r=>{e.classList.remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText= +r.displayName},()=>{e.removeAttribute("href")})})}if(i.treats.aug.size>0||i.treats.treattn.size>0){let l=document.createElement( +"div");l.innerHTML=f.east,l.innerHTML+=f.aug,(n==="aug"||n==="cite")&&l.classList.add("hidden"),p.append(l),i.treats.aug. forEach(g=>{let e=document.createElement("a");e.classList.add("taxon","uri");let s=g.replace("http://taxon-concept.plazi\ -.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",d.append(" ",e),S.findName(g).then(i=>{e.classList.remove("\ -uri"),i.authority?e.innerText=i.displayName+" "+i.authority:e.innerText=i.displayName},()=>{e.removeAttribute("href")})}), -r.treats.treattn.forEach(g=>{let e=document.createElement("a");e.classList.add("taxon","uri");let s=g.replace("http://ta\ -xon-name.plazi.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",d.append(" ",e),S.findName(g).then(i=>{e.classList. -remove("uri"),i.authority?e.innerText=i.displayName+" "+i.authority:e.innerText=i.displayName},()=>{e.removeAttribute("h\ -ref")})})}if(r.treats.dpr.size>0){let d=document.createElement("div");d.innerHTML=f.west,d.innerHTML+=f.dpr,(a==="dpr"|| -a==="cite")&&d.classList.add("hidden"),p.append(d),r.treats.dpr.forEach(g=>{let e=document.createElement("a");e.classList. +.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",l.append(" ",e),S.findName(g).then(r=>{e.classList.remove("\ +uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})}), +i.treats.treattn.forEach(g=>{let e=document.createElement("a");e.classList.add("taxon","uri");let s=g.replace("http://ta\ +xon-name.plazi.org/id/","");e.innerText=s,e.href="#"+s,e.title="show name",l.append(" ",e),S.findName(g).then(r=>{e.classList. +remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("h\ +ref")})})}if(i.treats.dpr.size>0){let l=document.createElement("div");l.innerHTML=f.west,l.innerHTML+=f.dpr,(n==="dpr"|| +n==="cite")&&l.classList.add("hidden"),p.append(l),i.treats.dpr.forEach(g=>{let e=document.createElement("a");e.classList. add("taxon","uri");let s=g.replace("http://taxon-concept.plazi.org/id/","");e.innerText=s,e.href="#"+s,e.title="show nam\ -e",d.append(" ",e),S.findName(g).then(i=>{e.classList.remove("uri"),i.authority?e.innerText=i.displayName+" "+i.authority: -e.innerText=i.displayName},()=>{e.removeAttribute("href")})})}if(r.treats.citetc.size>0||r.treats.citetn.size>0){let d=document. -createElement("div");d.innerHTML=f.empty+f.cite,d.classList.add("hidden"),p.append(d),r.treats.citetc.forEach(g=>{let e=document. +e",l.append(" ",e),S.findName(g).then(r=>{e.classList.remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority: +e.innerText=r.displayName},()=>{e.removeAttribute("href")})})}if(i.treats.citetc.size>0||i.treats.citetn.size>0){let l=document. +createElement("div");l.innerHTML=f.empty+f.cite,l.classList.add("hidden"),p.append(l),i.treats.citetc.forEach(g=>{let e=document. createElement("a");e.classList.add("taxon","uri");let s=g.replace("http://taxon-concept.plazi.org/id/","");e.innerText=s, -e.href="#"+s,e.title="show name",d.append(" ",e),S.findName(g).then(i=>{e.classList.remove("uri"),i.authority?e.innerText= -i.displayName+" "+i.authority:e.innerText=i.displayName},()=>{e.removeAttribute("href")})}),r.treats.citetn.forEach(g=>{ +e.href="#"+s,e.title="show name",l.append(" ",e),S.findName(g).then(r=>{e.classList.remove("uri"),r.authority?e.innerText= +r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})}),i.treats.citetn.forEach(g=>{ let e=document.createElement("a");e.classList.add("taxon","uri");let s=g.replace("http://taxon-name.plazi.org/id/","");e. -innerText=s,e.href="#"+s,e.title="show name",d.append(" ",e),S.findName(g).then(i=>{e.classList.remove("uri"),i.authority? -e.innerText=i.displayName+" "+i.authority:e.innerText=i.displayName},()=>{e.removeAttribute("href")})})}if(r.figureCitations. -length>0){let d=document.createElement("div");d.classList.add("figures","hidden"),p.append(d);for(let g of r.figureCitations){ -let e=document.createElement("figure");d.append(e);let s=document.createElement("img");s.src=g.url,s.loading="lazy",s.alt= -g.description??"Cited Figure without caption",e.append(s);let i=document.createElement("figcaption");i.innerText=g.description?? -"",e.append(i)}}if(r.materialCitations.length>0){let d=document.createElement("div");d.innerHTML=f.empty+f.cite+" Materi\ -al Citations:
-",d.classList.add("hidden"),p.append(d),d.innerText+=r.materialCitations.map(g=>JSON.stringify(g).replaceAll( +innerText=s,e.href="#"+s,e.title="show name",l.append(" ",e),S.findName(g).then(r=>{e.classList.remove("uri"),r.authority? +e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})})}if(i.figureCitations. +length>0){let l=document.createElement("div");l.classList.add("figures","hidden"),p.append(l);for(let g of i.figureCitations){ +let e=document.createElement("figure");l.append(e);let s=document.createElement("img");s.src=g.url,s.loading="lazy",s.alt= +g.description??"Cited Figure without caption",e.append(s);let r=document.createElement("figcaption");r.innerText=g.description?? +"",e.append(r)}}if(i.materialCitations.length>0){let l=document.createElement("div");l.innerHTML=f.empty+f.cite+" Materi\ +al Citations:
-",l.classList.add("hidden"),p.append(l),l.innerText+=i.materialCitations.map(g=>JSON.stringify(g).replaceAll( "{","").replaceAll("}","").replaceAll('":',": ").replaceAll(",",", ").replaceAll('"',"")).join(` - -`)}})}};customElements.define("syno-treatment",E);var y=class extends HTMLElement{constructor(t){super();let a=document. -createElement("h2"),n=document.createElement("i");n.innerText=t.displayName,a.append(n),this.append(a);let l=document.createElement( -"span");l.classList.add("rank"),l.innerText=t.rank;let c=document.createElement("span");if(c.classList.add("rank"),c.innerText= -t.kingdom||"Missing Kingdom",a.append(" ",c," ",l),t.taxonNameURI){let o=document.createElement("a");o.classList.add("ta\ + -`)}})}};customElements.define("syno-treatment",E);var y=class extends HTMLElement{constructor(t){super();let n=document. +createElement("h2"),a=document.createElement("i");a.innerText=t.displayName,n.append(a),this.append(n);let d=document.createElement( +"span");d.classList.add("rank"),d.innerText=t.rank;let c=document.createElement("span");if(c.classList.add("rank"),c.innerText= +t.kingdom||"Missing Kingdom",n.append(" ",c," ",d),t.taxonNameURI){let o=document.createElement("a");o.classList.add("ta\ xon","uri");let m=t.taxonNameURI.replace("http://taxon-name.plazi.org/id/","");o.innerText=m,o.id=m,o.href=t.taxonNameURI, -o.target="_blank",o.innerHTML+=f.link,a.append(" ",o)}let u=document.createElement("div");u.classList.add("vernacular"), +o.target="_blank",o.innerHTML+=f.link,n.append(" ",o)}let u=document.createElement("div");u.classList.add("vernacular"), t.vernacularNames.then(o=>{o.size>0&&(u.innerText="\u201C"+U([...o.values()].flat()).join("\u201D, \u201C")+"\u201D")}), this.append(u);let p=document.createElement("ul");if(this.append(p),t.col){let o=document.createElement("a");o.classList. add("col","uri");let m=t.col.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");o.innerText=m,o.id=m,o.href= -t.col.colURI,o.target="_blank",o.innerHTML+=f.link,a.append(" ",o);let d=document.createElement("div");d.classList.add("\ -treatmentline"),d.innerHTML=t.col.acceptedURI!==t.col.colURI?f.col_dpr:f.col_aug,p.append(d);let g=document.createElement( -"span");g.innerText="Catalogue of Life",d.append(g);let e=document.createElement("div");if(e.classList.add("indent"),d.append( -e),t.col.acceptedURI!==t.col.colURI){let s=document.createElement("div");s.innerHTML=f.east+f.col_aug,e.append(s);let i=document. -createElement("a");i.classList.add("col","uri");let T=t.col.acceptedURI.replace("https://www.catalogueoflife.org/data/ta\ -xon/","");i.innerText=T,i.href=`#${T}`,i.title="show name",s.append(i),S.findName(t.col.acceptedURI).then(v=>{v.authority? -i.innerText=v.displayName+" "+v.authority:i.innerText=v.displayName},()=>{i.removeAttribute("href")})}}if(t.treatments.treats. +t.col.colURI,o.target="_blank",o.innerHTML+=f.link,n.append(" ",o);let l=document.createElement("div");l.classList.add("\ +treatmentline"),l.innerHTML=t.col.acceptedURI!==t.col.colURI?f.col_dpr:f.col_aug,p.append(l);let g=document.createElement( +"span");g.innerText="Catalogue of Life",l.append(g);let e=document.createElement("div");if(e.classList.add("indent"),l.append( +e),t.col.acceptedURI!==t.col.colURI){let s=document.createElement("div");s.innerHTML=f.east+f.col_aug,e.append(s);let r=document. +createElement("a");r.classList.add("col","uri");let T=t.col.acceptedURI.replace("https://www.catalogueoflife.org/data/ta\ +xon/","");r.innerText=T,r.href=`#${T}`,r.title="show name",s.append(r),S.findName(t.col.acceptedURI).then(v=>{v.authority? +r.innerText=v.displayName+" "+v.authority:r.innerText=v.displayName},()=>{r.removeAttribute("href")})}}if(t.treatments.treats. size>0||t.treatments.cite.size>0){for(let o of t.treatments.treats){let m=new E(o,"aug");p.append(m)}for(let o of t.treatments. -cite){let m=new E(o,"cite");p.append(m)}}let r=document.createElement("abbr");r.classList.add("justification"),r.innerText= -"...?",D(t).then(o=>r.title=`This ${o}`),a.append(" ",r);for(let o of t.authorizedNames){let m=document.createElement("h\ -3"),d=document.createElement("i");d.innerText=o.displayName,d.classList.add("gray"),m.append(d),m.append(" ",o.authority), +cite){let m=new E(o,"cite");p.append(m)}}let i=document.createElement("abbr");i.classList.add("justification"),i.innerText= +"...?",D(t).then(o=>i.title=`This ${o}`),n.append(" ",i);for(let o of t.authorizedNames){let m=document.createElement("h\ +3"),l=document.createElement("i");l.innerText=o.displayName,l.classList.add("gray"),m.append(l),m.append(" ",o.authority), this.append(m);let g=document.createElement("ul");if(this.append(g),o.taxonConceptURIs[0]){let s=document.createElement( -"a");s.classList.add("taxon","uri");let i=o.taxonConceptURIs[0].replace("http://taxon-concept.plazi.org/id/","");s.innerText= -i,s.id=i,s.href=o.taxonConceptURIs[0],s.target="_blank",s.innerHTML+=f.link,m.append(" ",s)}if(o.col){let s=document.createElement( -"a");s.classList.add("col","uri");let i=o.col.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");s.innerText= -i,s.id=i,s.href=o.col.colURI,s.target="_blank",s.innerHTML+=f.link,m.append(" ",s);let T=document.createElement("div");T. +"a");s.classList.add("taxon","uri");let r=o.taxonConceptURIs[0].replace("http://taxon-concept.plazi.org/id/","");s.innerText= +r,s.id=r,s.href=o.taxonConceptURIs[0],s.target="_blank",s.innerHTML+=f.link,m.append(" ",s)}if(o.col){let s=document.createElement( +"a");s.classList.add("col","uri");let r=o.col.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");s.innerText= +r,s.id=r,s.href=o.col.colURI,s.target="_blank",s.innerHTML+=f.link,m.append(" ",s);let T=document.createElement("div");T. classList.add("treatmentline"),T.innerHTML=o.col.acceptedURI!==o.col.colURI?f.col_dpr:f.col_aug,g.append(T);let v=document. createElement("span");v.innerText="Catalogue of Life",T.append(v);let N=document.createElement("div");if(N.classList.add( "indent"),T.append(N),o.col.acceptedURI!==o.col.colURI){let I=document.createElement("div");I.innerHTML=f.east+f.col_aug, N.append(I);let w=document.createElement("a");w.classList.add("col","uri");let q=o.col.acceptedURI.replace("https://www.\ catalogueoflife.org/data/taxon/","");w.innerText=q,w.href=`#${q}`,w.title="show name",I.append(" ",w),S.findName(o.col.acceptedURI). -then(A=>{w.classList.remove("uri"),A.authority?w.innerText=A.displayName+" "+A.authority:w.innerText=A.displayName},()=>{ +then(O=>{w.classList.remove("uri"),O.authority?w.innerText=O.displayName+" "+O.authority:w.innerText=O.displayName},()=>{ w.removeAttribute("href")})}}let e=[];for(let s of o.treatments.def)e.push({trt:s,status:"def"});for(let s of o.treatments. aug)e.push({trt:s,status:"aug"});for(let s of o.treatments.dpr)e.push({trt:s,status:"dpr"});for(let s of o.treatments.cite) -e.push({trt:s,status:"cite"});W||e.sort((s,i)=>s.trt.date&&i.trt.date?s.trt.date-i.trt.date:s.trt.date?1:i.trt.date?-1:0); -for(let{trt:s,status:i}of e){let T=new E(s,i);g.append(T)}}}};customElements.define("syno-name",y);async function D(h){if(h. +e.push({trt:s,status:"cite"});W||e.sort((s,r)=>s.trt.date&&r.trt.date?s.trt.date-r.trt.date:s.trt.date?1:r.trt.date?-1:0); +for(let{trt:s,status:r}of e){let T=new E(s,r);g.append(T)}}}};customElements.define("syno-name",y);async function D(h){if(h. justification.searchTerm)return h.justification.subTaxon?"is a sub-taxon of the search term.":"is the search term.";if(h. -justification.treatment){let t=await h.justification.treatment.details,a=await D(h.justification.parent);return`is, acco\ +justification.treatment){let t=await h.justification.treatment.details,n=await D(h.justification.parent);return`is, acco\ rding to ${t.creators} ${h.justification.treatment.date}, - a synonym of ${h.justification.parent.displayName} which ${a}`}else{let t=await D(h.justification.parent);return`is\ + a synonym of ${h.justification.parent.displayName} which ${n}`}else{let t=await D(h.justification.parent);return`is\ , according to the Catalogue of Life, a synonym of ${h.justification.parent.displayName} which ${t}`}}for await(let h of S){let t=new y(h);k.append(t)}var V=performance. now();C.innerHTML="";C.innerText=`Found ${S.names.length} names with ${S.treatments.size} treatments. This took ${(V-j)/ diff --git a/index.js.map b/index.js.map index bd34324..0ef8737 100644 --- a/index.js.map +++ b/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../SparqlEndpoint.ts", "../Queries.ts", "../UnifyAuthorities.ts", "../SynonymGroup.ts", "https://jsr.io/@std/collections/1.0.9/distinct.ts", "index.ts"], - "sourcesContent": ["async function sleep(ms: number): Promise {\n const p = new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n return await p;\n}\n\n/** Describes the format of the JSON return by SPARQL endpoints */\nexport type SparqlJson = {\n head: {\n vars: string[];\n };\n results: {\n bindings: {\n [key: string]:\n | { type: string; value: string; \"xml:lang\"?: string }\n | undefined;\n }[];\n };\n};\n\n/**\n * Represents a remote sparql endpoint and provides a uniform way to run queries.\n */\nexport class SparqlEndpoint {\n /** Create a new SparqlEndpoint with the given URI */\n constructor(private sparqlEnpointUri: string) {}\n\n /** @ignore */\n // reasons: string[] = [];\n\n /**\n * Run a query against the sparql endpoint\n *\n * It automatically retries up to 10 times on fetch errors, waiting 50ms on the first retry and doupling the wait each time.\n * Retries are logged to the console (`console.warn`)\n *\n * @throws In case of non-ok response status codes or if fetch failed 10 times.\n * @param query The sparql query to run against the endpoint\n * @param fetchOptions Additional options for the `fetch` request\n * @param _reason (Currently ignored, used internally for debugging purposes)\n * @returns Results of the query\n */\n async getSparqlResultSet(\n query: string,\n fetchOptions: RequestInit = {},\n _reason = \"\",\n ): Promise {\n // this.reasons.push(_reason);\n // DEBUG: console.info(`SPARQL ${_reason}:\\n${query}`);\n\n fetchOptions.headers = fetchOptions.headers || {};\n (fetchOptions.headers as Record)[\"Accept\"] =\n \"application/sparql-results+json\";\n let retryCount = 0;\n const sendRequest = async (): Promise => {\n try {\n // DEBUG: console.info(`SPARQL ${_reason} (${retryCount + 1})`);\n const response = await fetch(\n this.sparqlEnpointUri + \"?query=\" + encodeURIComponent(query),\n fetchOptions,\n );\n if (!response.ok) {\n throw new Error(\"Response not ok. Status \" + response.status);\n }\n return await response.json();\n } catch (error) {\n if (fetchOptions.signal?.aborted) {\n throw error;\n } else if (retryCount < 10) {\n const wait = 50 * (1 << retryCount++);\n console.info(`!! Fetch Error. Retrying in ${wait}ms (${retryCount})`);\n await sleep(wait);\n return await sendRequest();\n }\n console.warn(\"!! Fetch Error:\", query, \"\\n---\\n\", error);\n throw error;\n }\n };\n return await sendRequest();\n }\n}\n", "/**\n * Common to all of the `getNameFrom_`-queries.\n *\n * As its own variable to ensure consistency in the resturned bindings.\n */\nconst preamble = `PREFIX dc: \nPREFIX dwc: \nPREFIX dwcFP: \nPREFIX cito: \nPREFIX trt: \nSELECT DISTINCT ?kingdom ?tn ?tc ?col ?acceptedcol ?rank ?genus ?section ?subgenus ?species ?infrasp ?name ?authority\n (group_concat(DISTINCT ?tcauth;separator=\" / \") AS ?tcAuth)\n (group_concat(DISTINCT ?aug;separator=\"|\") as ?augs)\n (group_concat(DISTINCT ?def;separator=\"|\") as ?defs)\n (group_concat(DISTINCT ?dpr;separator=\"|\") as ?dprs)\n (group_concat(DISTINCT ?cite;separator=\"|\") as ?cites)\n (group_concat(DISTINCT ?trtn;separator=\"|\") as ?tntreats)\n (group_concat(DISTINCT ?citetn;separator=\"|\") as ?tncites)`;\n\n/**\n * Common to all of the `getNameFrom_`-queries.\n *\n * As its own variable to ensure consistency in the resturned bindings.\n */\nconst postamble =\n `GROUP BY ?kingdom ?tn ?tc ?col ?acceptedcol ?rank ?genus ?section ?subgenus ?species ?infrasp ?name ?authority`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromCol = (colUri: string) =>\n `${preamble} WHERE {\nBIND(<${colUri}> as ?col)\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name .\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n OPTIONAL {\n ?col dwc:specificEpithet ?colspecies .\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n }\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n\n BIND(COALESCE(?colkingdom, \"\") AS ?kingdom)\n BIND(COALESCE(?colsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?colspecies, \"\") AS ?species)\n BIND(COALESCE(?colinfrasp, \"\") AS ?infrasp)\n\n OPTIONAL {\n ?tn dwc:rank ?trank ;\n a dwcFP:TaxonName .\n FILTER(LCASE(?rank) = LCASE(?trank))\n ?tn dwc:genus ?genus .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n FILTER(?subgenus = COALESCE(?tnsubgenus, COALESCE(?section, \"\")))\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL { ?tn dwc:species ?tnspecies . }\n FILTER(?species = COALESCE(?tnspecies, \"\"))\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n FILTER(?infrasp = COALESCE(?tninfrasp, \"\"))\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?tc trt:hasTaxonName ?tn ; dwc:scientificNameAuthorship ?tcauth ; a dwcFP:TaxonConcept .\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n }\n }\n}\n${postamble}\nLIMIT 500`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromTC = (tcUri: string) =>\n `${preamble} WHERE {\n <${tcUri}> trt:hasTaxonName ?tn .\n ?tc trt:hasTaxonName ?tn ;\n dwc:scientificNameAuthorship ?tcauth ;\n a dwcFP:TaxonConcept .\n\n ?tn a dwcFP:TaxonName .\n ?tn dwc:rank ?tnrank .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n ?tn dwc:genus ?genus .\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL {\n ?tn dwc:species ?tnspecies .\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n }\n \n BIND(LCASE(?tnrank) AS ?rank)\n BIND(COALESCE(?tnsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?tnspecies, \"\") AS ?species)\n BIND(COALESCE(?tninfrasp, \"\") AS ?infrasp)\n \n OPTIONAL {\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name . # Note: contains authority\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n FILTER(?kingdom = COALESCE(?colkingdom, \"\"))\n\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n FILTER(COALESCE(?tnsubgenus, COALESCE(?section, \"\")) = COALESCE(?colsubgenus, \"\"))\n OPTIONAL { ?col dwc:specificEpithet ?colspecies . }\n FILTER(?species = COALESCE(?colspecies, \"\"))\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n FILTER(?infrasp = COALESCE(?colinfrasp, \"\"))\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n }\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n}\n${postamble}\nLIMIT 500`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromTN = (tnUri: string) =>\n `${preamble} WHERE {\n BIND(<${tnUri}> as ?tn)\n ?tn a dwcFP:TaxonName .\n ?tn dwc:rank ?tnrank .\n ?tn dwc:genus ?genus .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL {\n ?tn dwc:species ?tnspecies .\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n }\n \n BIND(LCASE(?tnrank) AS ?rank)\n BIND(COALESCE(?tnsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?tnspecies, \"\") AS ?species)\n BIND(COALESCE(?tninfrasp, \"\") AS ?infrasp)\n \n OPTIONAL {\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name . # Note: contains authority\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n FILTER(?kingdom = COALESCE(?colkingdom, \"\"))\n\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n FILTER(COALESCE(?tnsubgenus, COALESCE(?section, \"\")) = COALESCE(?colsubgenus, \"\"))\n OPTIONAL { ?col dwc:specificEpithet ?colspecies . }\n FILTER(?species = COALESCE(?colspecies, \"\"))\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n FILTER(?infrasp = COALESCE(?colinfrasp, \"\"))\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n }\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?tc trt:hasTaxonName ?tn ; dwc:scientificNameAuthorship ?tcauth ; a dwcFP:TaxonConcept .\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n }\n}\n${postamble}\nLIMIT 500`;\n", "export function unifyAuthorithy(a: string, b: string): string | null {\n const as = a.split(/\\s*[,]\\s*/);\n const bs = b.split(/\\s*[,]\\s*/);\n const yearA = (as.length > 0 && /\\d{4}/.test(as.at(-1)!)) ? as.pop()! : null;\n const yearB = (bs.length > 0 && /\\d{4}/.test(bs.at(-1)!)) ? bs.pop()! : null;\n const etalA = as.length > 0 && /\\s*et\\.?\\s*al\\.?/.test(as.at(-1)!);\n const etalB = bs.length > 0 && /\\s*et\\.?\\s*al\\.?/.test(bs.at(-1)!);\n if (etalA) {\n as[as.length - 1] = as[as.length - 1].replace(/\\s*et\\.?\\s*al\\.?/, \"\");\n }\n if (etalB) {\n bs[bs.length - 1] = bs[bs.length - 1].replace(/\\s*et\\.?\\s*al\\.?/, \"\");\n }\n\n if (!etalA && !etalB && as.length != bs.length) return null;\n\n const result: string[] = [];\n let i = 0;\n for (; i < as.length && i < bs.length; i++) {\n const r = unifySingleName(as[i], bs[i]);\n if (r !== null) result.push(r);\n else return null;\n }\n for (let j = i; j < as.length; j++) {\n if (as[j]) result.push(as[j]);\n }\n for (let j = i; j < bs.length; j++) {\n if (bs[j]) result.push(bs[j]);\n }\n\n if (yearA && yearB) {\n if (yearA === yearB) result.push(yearA);\n else return null;\n } else if (yearA) {\n result.push(yearA);\n } else if (yearB) {\n result.push(yearB);\n }\n\n return result.join(\", \");\n}\n\nfunction unifySingleName(a: string, b: string) {\n let prefixA = a.replaceAll(\"-\", \" \");\n let prefixB = b.replaceAll(\"-\", \" \");\n if (prefixA.endsWith(\".\") || prefixB.endsWith(\".\")) {\n // might be abbreviation\n // normalize to get compatible string lengths\n const longA = prefixA.normalize(\"NFKC\");\n const longB = prefixB.normalize(\"NFKC\");\n const indexA = longA.lastIndexOf(\".\");\n const indexB = longB.lastIndexOf(\".\");\n const index = indexA !== -1\n ? (indexB !== -1 ? Math.min(indexA, indexB) : indexA)\n : indexB;\n prefixA = longA.substring(0, index);\n prefixB = longB.substring(0, index);\n }\n\n if (isEquivalent(prefixA, prefixB)) {\n // normalize such that accents are represented with combining characters\n // so that the version with accents is longer\n const normA = a.normalize(\"NFD\");\n const normB = b.normalize(\"NFD\");\n return normA.length >= normB.length ? a : b;\n }\n return null;\n}\n\nfunction isEquivalent(a: string, b: string): boolean {\n return a.localeCompare(b, \"en\", {\n sensitivity: \"base\", // a = \u00E4, A = a, a \u2260 b\n usage: \"search\",\n }) === 0;\n}\n", "import type { SparqlEndpoint, SparqlJson } from \"./mod.ts\";\nimport * as Queries from \"./Queries.ts\";\nimport { unifyAuthorithy } from \"./UnifyAuthorities.ts\";\n\n/** Finds all synonyms of a taxon */\nexport class SynonymGroup implements AsyncIterable {\n /** Indicates whether the SynonymGroup has found all synonyms.\n *\n * @readonly\n */\n isFinished = false;\n /** Used internally to watch for new names found */\n private monitor: EventTarget = new EventTarget();\n\n /** Used internally to abort in-flight network requests when SynonymGroup is aborted */\n private controller = new AbortController();\n\n /** The SparqlEndpoint used */\n private sparqlEndpoint: SparqlEndpoint;\n\n /**\n * List of names found so-far.\n *\n * Contains full list of synonyms _if_ .isFinished and not .isAborted\n *\n * @readonly\n */\n names: Name[] = [];\n /**\n * Add a new Name to this.names.\n *\n * Note: does not deduplicate on its own\n *\n * @internal */\n private pushName(name: Name) {\n this.names.push(name);\n this.monitor.dispatchEvent(new CustomEvent(\"updated\"));\n }\n\n /**\n * Call when all synonyms are found\n *\n * @internal */\n private finish() {\n this.isFinished = true;\n this.monitor.dispatchEvent(new CustomEvent(\"updated\"));\n }\n\n /** contains TN, TC, CoL uris of synonyms which are in-flight somehow or are done already */\n private expanded = new Set(); // new Map();\n\n /** contains CoL uris where we don't need to check for Col \"acceptedName\" links\n *\n * col -> accepted col\n */\n private acceptedCol = new Map();\n\n /**\n * Used internally to deduplicate treatments, maps from URI to Object.\n *\n * Contains full list of treatments _if_ .isFinished and not .isAborted\n *\n * @readonly\n */\n treatments: Map = new Map();\n\n /**\n * Whether to show taxa deprecated by CoL that would not have been found otherwise.\n * This significantly increases the number of results in some cases.\n */\n ignoreDeprecatedCoL: boolean;\n\n /**\n * if set to true, subTaxa of the search term are also considered as starting points.\n *\n * Note that \"intermediate\" ranks like subGenus and section are always included when searching for a genus by latin name.\n */\n startWithSubTaxa: boolean;\n\n /**\n * Constructs a SynonymGroup\n *\n * @param sparqlEndpoint SPARQL-Endpoint to query\n * @param taxonName either a string of the form \"Genus species infraspecific\" (species & infraspecific names optional), or an URI of a http://filteredpush.org/ontologies/oa/dwcFP#TaxonConcept or ...#TaxonName or a CoL taxon URI\n * @param [ignoreDeprecatedCoL=true] Whether to show taxa deprecated by CoL that would not have been found otherwise\n * @param [startWithSubTaxa=false] if set to true, subTaxa of the search term are also considered as starting points.\n */\n constructor(\n sparqlEndpoint: SparqlEndpoint,\n taxonName: string,\n ignoreDeprecatedCoL = true,\n startWithSubTaxa = false,\n ) {\n this.sparqlEndpoint = sparqlEndpoint;\n this.ignoreDeprecatedCoL = ignoreDeprecatedCoL;\n this.startWithSubTaxa = startWithSubTaxa;\n\n if (taxonName.startsWith(\"http\")) {\n this.getName(taxonName, { searchTerm: true, subTaxon: false })\n .catch((e) => {\n console.log(\"SynoGroup Failure: \", e);\n this.controller.abort(\"SynoGroup Failed\");\n })\n .finally(() => this.finish());\n } else {\n const name = [\n ...taxonName.split(\" \").filter((n) => !!n),\n undefined,\n undefined,\n ] as [string, string | undefined, string | undefined];\n this.getNameFromLatin(name, { searchTerm: true, subTaxon: false })\n .finally(\n () => this.finish(),\n );\n }\n }\n\n /**\n * Finds the given name (identified by taxon-name, taxon-concept or CoL uri) among the list of synonyms.\n *\n * Will reject when the SynonymGroup finishes but the name was not found \u2014 this means that this was not a synonym.\n */\n findName(uri: string): Promise {\n let name: Name | AuthorizedName | undefined;\n for (const n of this.names) {\n if (n.taxonNameURI === uri || n.col?.colURI === uri) {\n name = n;\n break;\n }\n const an = n.authorizedNames.find((an) =>\n an.col?.colURI === uri || an.taxonConceptURIs.includes(uri)\n );\n if (an) {\n name = an;\n break;\n }\n }\n if (name) return Promise.resolve(name);\n return new Promise((resolve, reject) => {\n this.monitor.addEventListener(\"updated\", () => {\n if (this.names.length === 0 || this.isFinished) reject();\n const n = this.names.at(-1)!;\n if (n.taxonNameURI === uri || n.col?.colURI === uri) {\n resolve(n);\n return;\n }\n const an = n.authorizedNames.find((an) =>\n an.col?.colURI === uri || an.taxonConceptURIs.includes(uri)\n );\n if (an) {\n resolve(an);\n return;\n }\n });\n });\n }\n\n /** @internal */\n private async getName(\n taxonName: string,\n justification: Justification,\n ): Promise {\n if (this.expanded.has(taxonName)) {\n console.log(\"Skipping known\", taxonName);\n return;\n }\n\n if (this.controller.signal?.aborted) return Promise.reject();\n\n let json: SparqlJson | undefined;\n\n if (taxonName.startsWith(\"https://www.catalogueoflife.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromCol(taxonName),\n { signal: this.controller.signal },\n `NameFromCol ${taxonName}`,\n );\n } else if (taxonName.startsWith(\"http://taxon-concept.plazi.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromTC(taxonName),\n { signal: this.controller.signal },\n `NameFromTC ${taxonName}`,\n );\n } else if (taxonName.startsWith(\"http://taxon-name.plazi.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromTN(taxonName),\n { signal: this.controller.signal },\n `NameFromTN ${taxonName}`,\n );\n } else {\n throw `Cannot handle name-uri <${taxonName}> !`;\n }\n\n await this.handleName(json!, justification);\n\n if (\n this.startWithSubTaxa && justification.searchTerm &&\n !justification.subTaxon\n ) {\n await this.getSubtaxa(taxonName);\n }\n }\n\n /** @internal */\n private async getSubtaxa(url: string): Promise {\n const query = url.startsWith(\"http://taxon-concept.plazi.org\")\n ? `\nPREFIX trt: \nSELECT DISTINCT ?sub WHERE {\n BIND(<${url}> as ?url)\n ?sub trt:hasParentName*/^trt:hasTaxonName ?url .\n}\nLIMIT 5000`\n : `\nPREFIX dwc: \nPREFIX trt: \nSELECT DISTINCT ?sub WHERE {\n BIND(<${url}> as ?url)\n ?sub (dwc:parent|trt:hasParentName)* ?url .\n}\nLIMIT 5000`;\n\n if (this.controller.signal?.aborted) return Promise.reject();\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n { signal: this.controller.signal },\n `Subtaxa ${url}`,\n );\n\n const names = json.results.bindings\n .map((n) => n.sub?.value)\n .filter((n) => n && !this.expanded.has(n)) as string[];\n\n await Promise.allSettled(\n names.map((n) => this.getName(n, { searchTerm: true, subTaxon: true })),\n );\n }\n\n /** @internal */\n private async getNameFromLatin(\n [genus, species, infrasp]: [string, string | undefined, string | undefined],\n justification: Justification,\n ): Promise {\n const query = `\n PREFIX dwc: \nSELECT DISTINCT ?uri WHERE {\n ?uri dwc:genus|dwc:genericName \"${genus}\" .\n ${\n species\n ? `?uri dwc:species|dwc:specificEpithet \"${species}\" .`\n : \"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species . }\"\n }\n ${\n infrasp\n ? `?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet \"${infrasp}\" .`\n : \"FILTER NOT EXISTS { ?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet ?infrasp . }\"\n }\n}\nLIMIT 500`;\n\n if (this.controller.signal?.aborted) return Promise.reject();\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n { signal: this.controller.signal },\n `NameFromLatin ${genus} ${species} ${infrasp}`,\n );\n\n const names = json.results.bindings\n .map((n) => n.uri?.value)\n .filter((n) => n && !this.expanded.has(n)) as string[];\n\n await Promise.allSettled(names.map((n) => this.getName(n, justification)));\n }\n\n /**\n * Note this makes some assumptions on which variables are present in the bindings\n *\n * @internal */\n private async handleName(\n json: SparqlJson,\n justification: Justification,\n ): Promise {\n const treatmentPromises: Treatment[] = [];\n\n const abbreviateRank = (rank: string) => {\n switch (rank) {\n case \"variety\":\n return \"var.\";\n case \"subspecies\":\n return \"subsp.\";\n case \"form\":\n return \"f.\";\n default:\n return rank;\n }\n };\n\n const displayName: string = (json.results.bindings[0].name\n ? (\n json.results.bindings[0].authority\n ? json.results.bindings[0].name.value\n .replace(\n json.results.bindings[0].authority.value,\n \"\",\n )\n : json.results.bindings[0].name.value\n )\n : json.results.bindings[0].genus!.value +\n (json.results.bindings[0].section?.value\n ? ` sect. ${json.results.bindings[0].section.value}`\n : \"\") +\n (json.results.bindings[0].subgenus?.value\n ? ` (${json.results.bindings[0].subgenus.value})`\n : \"\") +\n (json.results.bindings[0].species?.value\n ? ` ${json.results.bindings[0].species.value}`\n : \"\") +\n (json.results.bindings[0].infrasp?.value\n ? ` ${abbreviateRank(json.results.bindings[0].rank!.value)} ${\n json.results.bindings[0].infrasp.value\n }`\n : \"\")).trim();\n\n // Case where the CoL-taxon has no authority. There should only be one of these.\n let unathorizedCol: { colURI: string; acceptedURI: string } | undefined;\n\n // there can be multiple CoL-taxa with same latin name, e.g. Leontopodium alpinum has 3T6ZY and 3T6ZX.\n const authorizedNames: AuthorizedName[] = [];\n\n const taxonNameURI = json.results.bindings[0].tn?.value;\n if (taxonNameURI) {\n if (this.expanded.has(taxonNameURI)) return;\n this.expanded.add(taxonNameURI); //, NameStatus.madeName);\n }\n\n const expandedHere = new Set();\n\n for (const t of json.results.bindings) {\n if (t.col) {\n const colURI = t.col.value;\n if (!t.authority?.value) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n if (unathorizedCol && unathorizedCol.colURI !== colURI) {\n console.log(\"Duplicate unathorized COL:\", unathorizedCol, colURI);\n }\n unathorizedCol = {\n colURI,\n acceptedURI: t.acceptedcol?.value ?? \"INVALID COL\",\n };\n } else if (!authorizedNames.find((e) => e.col?.colURI === colURI)) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n if (!expandedHere.has(colURI)) {\n expandedHere.add(colURI);\n // TODO: handle unification of names\n // might not be neccessary, assuming all CoL-taxa are non-unifiable and\n // they are always handled first\n authorizedNames.push({\n displayName,\n authority: t.authority!.value,\n authorities: [t.authority!.value],\n col: {\n colURI: t.col.value,\n acceptedURI: t.acceptedcol?.value ?? \"INAVLID COL\",\n },\n taxonConceptURIs: [],\n treatments: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n cite: new Set(),\n },\n });\n }\n }\n }\n\n if (t.tc && t.tcAuth && t.tcAuth.value) {\n if (this.expanded.has(t.tc.value)) {\n console.log(\"Skipping known\", t.tc.value);\n return;\n } else if (!expandedHere.has(t.tc.value)) {\n expandedHere.add(t.tc.value);\n\n const def = this.makeTreatmentSet(t.defs?.value.split(\"|\"));\n const aug = this.makeTreatmentSet(t.augs?.value.split(\"|\"));\n const dpr = this.makeTreatmentSet(t.dprs?.value.split(\"|\"));\n const cite = this.makeTreatmentSet(t.cites?.value.split(\"|\"));\n\n def.forEach((t) => treatmentPromises.push(t));\n aug.forEach((t) => treatmentPromises.push(t));\n dpr.forEach((t) => treatmentPromises.push(t));\n\n const prevName = authorizedNames.find((e) =>\n unifyAuthorithy(e.authority, t.tcAuth!.value) !== null\n // t.tcAuth!.value.split(\" / \").some((auth) =>\n // unifyAuthorithy(e.authority, auth) !== null\n // )\n );\n if (prevName) {\n // TODO: I feel like this could be made much more efficient -- we are unifying repeatedly\n const best = t.tcAuth!.value; // .split(\" / \").find((auth) =>\n // unifyAuthorithy(prevName.authority, auth) !== null\n // )!;\n\n prevName.authority = unifyAuthorithy(prevName.authority, best)!;\n prevName.authorities.push(...t.tcAuth.value.split(\" / \"));\n prevName.taxonConceptURIs.push(t.tc.value);\n prevName.treatments = {\n def: prevName.treatments.def.union(def),\n aug: prevName.treatments.aug.union(aug),\n dpr: prevName.treatments.dpr.union(dpr),\n cite: prevName.treatments.cite.union(cite),\n };\n } else {\n authorizedNames.push({\n displayName,\n authority: t.tcAuth.value,\n authorities: t.tcAuth.value.split(\" / \"),\n taxonConceptURIs: [t.tc.value],\n treatments: {\n def,\n aug,\n dpr,\n cite,\n },\n });\n }\n }\n }\n }\n\n const treats = this.makeTreatmentSet(\n json.results.bindings[0].tntreats?.value.split(\"|\"),\n );\n treats.forEach((t) => treatmentPromises.push(t));\n\n const name: Name = {\n kingdom: json.results.bindings[0].kingdom!.value,\n displayName,\n rank: json.results.bindings[0].rank!.value,\n taxonNameURI,\n authorizedNames: authorizedNames,\n col: unathorizedCol,\n justification,\n treatments: {\n treats,\n cite: this.makeTreatmentSet(\n json.results.bindings[0].tncites?.value.split(\"|\"),\n ),\n },\n vernacularNames: taxonNameURI\n ? this.getVernacular(taxonNameURI)\n : Promise.resolve(new Map()),\n };\n\n for (const authName of name.authorizedNames) {\n if (authName.col) this.expanded.add(authName.col.colURI);\n for (const tc of authName.taxonConceptURIs) this.expanded.add(tc);\n }\n\n this.pushName(name);\n\n /** Map */\n const newSynonyms = new Map();\n (await Promise.all(\n treatmentPromises.map((treat) =>\n treat.details.then((d): [Treatment, TreatmentDetails] => {\n return [treat, d];\n })\n ),\n )).map(([treat, d]) => {\n d.treats.aug.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.def.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.dpr.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.treattn.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n });\n\n if (unathorizedCol) {\n await this.findColSynonyms(unathorizedCol.colURI, name);\n }\n\n await Promise.allSettled(\n [\n ...authorizedNames\n .filter((n) => n.col)\n .map((n) => this.findColSynonyms(n.col!.colURI, name)),\n ...[...newSynonyms].map(([n, treatment]) =>\n this.getName(n, { searchTerm: false, parent: name, treatment })\n ),\n ],\n );\n }\n\n /** @internal */\n private async findColSynonyms(\n colUri: string,\n parent: Name,\n ): Promise {\n const query = `\nPREFIX dwc: \nSELECT DISTINCT ?current ?current_status (GROUP_CONCAT(DISTINCT ?dpr; separator=\"|\") AS ?dprs) WHERE {\n BIND(<${colUri}> AS ?col)\n {\n ?col dwc:acceptedName ?current .\n ?dpr dwc:acceptedName ?current .\n OPTIONAL { ?current dwc:taxonomicStatus ?current_status . }\n } UNION {\n ?col dwc:taxonomicStatus ?current_status .\n OPTIONAL { ?dpr dwc:acceptedName ?col . }\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?current)\n }\n}\nGROUP BY ?current ?current_status`;\n\n if (this.acceptedCol.has(colUri)) {\n // we have already found this group of synonyms\n return [];\n }\n\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n { signal: this.controller.signal },\n `AcceptedCol ${colUri}`,\n );\n\n const promises: Promise[] = [];\n\n for (const b of json.results.bindings) {\n for (const dpr of b.dprs!.value.split(\"|\")) {\n if (dpr) {\n if (!this.acceptedCol.has(b.current!.value)) {\n this.acceptedCol.set(b.current!.value, b.current!.value);\n promises.push(\n this.getName(b.current!.value, {\n searchTerm: false,\n parent,\n }),\n );\n }\n\n this.acceptedCol.set(dpr, b.current!.value);\n if (!this.ignoreDeprecatedCoL) {\n promises.push(\n this.getName(dpr, { searchTerm: false, parent }),\n );\n }\n }\n }\n }\n\n if (json.results.bindings.length === 0) {\n // the provided colUri is not in CoL\n // promises === []\n if (!this.acceptedCol.has(colUri)) {\n this.acceptedCol.set(colUri, \"INVALID COL\");\n }\n return Promise.all(promises);\n }\n\n if (!this.acceptedCol.has(colUri)) this.acceptedCol.set(colUri, colUri);\n return Promise.all(promises);\n }\n\n /** @internal */\n private async getVernacular(uri: string): Promise {\n const result: vernacularNames = new Map();\n const query =\n `SELECT DISTINCT ?n WHERE { <${uri}> ?n . }`;\n const bindings = (await this.sparqlEndpoint.getSparqlResultSet(query, {\n signal: this.controller.signal,\n }, `Vernacular ${uri}`)).results.bindings;\n for (const b of bindings) {\n if (b.n?.value) {\n if (b.n[\"xml:lang\"]) {\n if (result.has(b.n[\"xml:lang\"])) {\n result.get(b.n[\"xml:lang\"])!.push(b.n.value);\n } else result.set(b.n[\"xml:lang\"], [b.n.value]);\n } else {\n if (result.has(\"??\")) result.get(\"??\")!.push(b.n.value);\n else result.set(\"??\", [b.n.value]);\n }\n }\n }\n return result;\n }\n\n /** @internal\n *\n * the supplied \"urls\" must be of the form \"URL>DATE\"\n */\n private makeTreatmentSet(urls?: string[]): Set {\n if (!urls) return new Set();\n return new Set(\n urls.filter((url) => !!url).map((url_d) => {\n const [url, date] = url_d.split(\">\");\n if (!this.treatments.has(url)) {\n const details = this.getTreatmentDetails(url);\n this.treatments.set(url, {\n url,\n date: date ? parseInt(date, 10) : undefined,\n details,\n });\n }\n return this.treatments.get(url) as Treatment;\n }),\n );\n }\n\n /** @internal */\n private async getTreatmentDetails(\n treatmentUri: string,\n ): Promise {\n const query = `\nPREFIX dc: \nPREFIX dwc: \nPREFIX dwcFP: \nPREFIX cito: \nPREFIX trt: \nSELECT DISTINCT\n ?date ?title ?mc\n (group_concat(DISTINCT ?catalogNumber;separator=\" / \") as ?catalogNumbers)\n (group_concat(DISTINCT ?collectionCode;separator=\" / \") as ?collectionCodes)\n (group_concat(DISTINCT ?typeStatus;separator=\" / \") as ?typeStatuss)\n (group_concat(DISTINCT ?countryCode;separator=\" / \") as ?countryCodes)\n (group_concat(DISTINCT ?stateProvince;separator=\" / \") as ?stateProvinces)\n (group_concat(DISTINCT ?municipality;separator=\" / \") as ?municipalitys)\n (group_concat(DISTINCT ?county;separator=\" / \") as ?countys)\n (group_concat(DISTINCT ?locality;separator=\" / \") as ?localitys)\n (group_concat(DISTINCT ?verbatimLocality;separator=\" / \") as ?verbatimLocalitys)\n (group_concat(DISTINCT ?recordedBy;separator=\" / \") as ?recordedBys)\n (group_concat(DISTINCT ?eventDate;separator=\" / \") as ?eventDates)\n (group_concat(DISTINCT ?samplingProtocol;separator=\" / \") as ?samplingProtocols)\n (group_concat(DISTINCT ?decimalLatitude;separator=\" / \") as ?decimalLatitudes)\n (group_concat(DISTINCT ?decimalLongitude;separator=\" / \") as ?decimalLongitudes)\n (group_concat(DISTINCT ?verbatimElevation;separator=\" / \") as ?verbatimElevations)\n (group_concat(DISTINCT ?gbifOccurrenceId;separator=\" / \") as ?gbifOccurrenceIds)\n (group_concat(DISTINCT ?gbifSpecimenId;separator=\" / \") as ?gbifSpecimenIds)\n (group_concat(DISTINCT ?creator;separator=\"; \") as ?creators)\n (group_concat(DISTINCT ?httpUri;separator=\"|\") as ?httpUris)\n (group_concat(DISTINCT ?aug;separator=\"|\") as ?augs)\n (group_concat(DISTINCT ?def;separator=\"|\") as ?defs)\n (group_concat(DISTINCT ?dpr;separator=\"|\") as ?dprs)\n (group_concat(DISTINCT ?cite;separator=\"|\") as ?cites)\n (group_concat(DISTINCT ?trttn;separator=\"|\") as ?trttns)\n (group_concat(DISTINCT ?citetn;separator=\"|\") as ?citetns)\nWHERE {\n BIND (<${treatmentUri}> as ?treatment)\n ?treatment dc:creator ?creator .\n OPTIONAL { ?treatment dc:title ?title }\n OPTIONAL { ?treatment trt:augmentsTaxonConcept ?aug . }\n OPTIONAL { ?treatment trt:definesTaxonConcept ?def . }\n OPTIONAL { ?treatment trt:deprecates ?dpr . }\n OPTIONAL { ?treatment cito:cites ?cite . ?cite a dwcFP:TaxonConcept . }\n OPTIONAL { ?treatment trt:treatsTaxonName ?trttn . }\n OPTIONAL { ?treatment trt:citesTaxonName ?citetn . }\n OPTIONAL {\n ?treatment dwc:basisOfRecord ?mc .\n ?mc dwc:catalogNumber ?catalogNumber .\n OPTIONAL { ?mc dwc:collectionCode ?collectionCode . }\n OPTIONAL { ?mc dwc:typeStatus ?typeStatus . }\n OPTIONAL { ?mc dwc:countryCode ?countryCode . }\n OPTIONAL { ?mc dwc:stateProvince ?stateProvince . }\n OPTIONAL { ?mc dwc:municipality ?municipality . }\n OPTIONAL { ?mc dwc:county ?county . }\n OPTIONAL { ?mc dwc:locality ?locality . }\n OPTIONAL { ?mc dwc:verbatimLocality ?verbatimLocality . }\n OPTIONAL { ?mc dwc:recordedBy ?recordedBy . }\n OPTIONAL { ?mc dwc:eventDate ?eventDate . }\n OPTIONAL { ?mc dwc:samplingProtocol ?samplingProtocol . }\n OPTIONAL { ?mc dwc:decimalLatitude ?decimalLatitude . }\n OPTIONAL { ?mc dwc:decimalLongitude ?decimalLongitude . }\n OPTIONAL { ?mc dwc:verbatimElevation ?verbatimElevation . }\n OPTIONAL { ?mc trt:gbifOccurrenceId ?gbifOccurrenceId . }\n OPTIONAL { ?mc trt:gbifSpecimenId ?gbifSpecimenId . }\n OPTIONAL { ?mc trt:httpUri ?httpUri . }\n }\n}\nGROUP BY ?date ?title ?mc`;\n if (this.controller.signal.aborted) {\n return {\n materialCitations: [],\n figureCitations: [],\n treats: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n citetc: new Set(),\n treattn: new Set(),\n citetn: new Set(),\n },\n };\n }\n try {\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n { signal: this.controller.signal },\n `TreatmentDetails ${treatmentUri}`,\n );\n const materialCitations: MaterialCitation[] = json.results.bindings\n .filter((t) => t.mc && t.catalogNumbers?.value)\n .map((t) => {\n const httpUri = t.httpUris?.value?.split(\"|\");\n return {\n \"catalogNumber\": t.catalogNumbers!.value,\n \"collectionCode\": t.collectionCodes?.value || undefined,\n \"typeStatus\": t.typeStatuss?.value || undefined,\n \"countryCode\": t.countryCodes?.value || undefined,\n \"stateProvince\": t.stateProvinces?.value || undefined,\n \"municipality\": t.municipalitys?.value || undefined,\n \"county\": t.countys?.value || undefined,\n \"locality\": t.localitys?.value || undefined,\n \"verbatimLocality\": t.verbatimLocalitys?.value || undefined,\n \"recordedBy\": t.recordedBys?.value || undefined,\n \"eventDate\": t.eventDates?.value || undefined,\n \"samplingProtocol\": t.samplingProtocols?.value || undefined,\n \"decimalLatitude\": t.decimalLatitudes?.value || undefined,\n \"decimalLongitude\": t.decimalLongitudes?.value || undefined,\n \"verbatimElevation\": t.verbatimElevations?.value || undefined,\n \"gbifOccurrenceId\": t.gbifOccurrenceIds?.value || undefined,\n \"gbifSpecimenId\": t.gbifSpecimenIds?.value || undefined,\n httpUri: httpUri?.length ? httpUri : undefined,\n };\n });\n const figureQuery = `\nPREFIX cito: \nPREFIX fabio: \nPREFIX dc: \nSELECT DISTINCT ?url ?description WHERE {\n <${treatmentUri}> cito:cites ?cites .\n ?cites a fabio:Figure ;\n fabio:hasRepresentation ?url .\n OPTIONAL { ?cites dc:description ?description . }\n} `;\n const figures = (await this.sparqlEndpoint.getSparqlResultSet(\n figureQuery,\n { signal: this.controller.signal },\n `TreatmentDetails/Figures ${treatmentUri}`,\n )).results.bindings;\n const figureCitations = figures.filter((f) => f.url?.value).map(\n (f) => {\n return { url: f.url!.value, description: f.description?.value };\n },\n );\n return {\n creators: json.results.bindings[0]?.creators?.value,\n title: json.results.bindings[0]?.title?.value,\n materialCitations,\n figureCitations,\n treats: {\n def: new Set(\n json.results.bindings[0]?.defs?.value\n ? json.results.bindings[0].defs.value.split(\"|\")\n : undefined,\n ),\n aug: new Set(\n json.results.bindings[0]?.augs?.value\n ? json.results.bindings[0].augs.value.split(\"|\")\n : undefined,\n ),\n dpr: new Set(\n json.results.bindings[0]?.dprs?.value\n ? json.results.bindings[0].dprs.value.split(\"|\")\n : undefined,\n ),\n citetc: new Set(\n json.results.bindings[0]?.cites?.value\n ? json.results.bindings[0].cites.value.split(\"|\")\n : undefined,\n ),\n treattn: new Set(\n json.results.bindings[0]?.trttns?.value\n ? json.results.bindings[0].trttns.value.split(\"|\")\n : undefined,\n ),\n citetn: new Set(\n json.results.bindings[0]?.citetns?.value\n ? json.results.bindings[0].citetns.value.split(\"|\")\n : undefined,\n ),\n },\n };\n } catch (error) {\n console.warn(\"SPARQL Error: \" + error);\n return {\n materialCitations: [],\n figureCitations: [],\n treats: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n citetc: new Set(),\n treattn: new Set(),\n citetn: new Set(),\n },\n };\n }\n }\n\n /** Allows iterating over the synonyms while they are found */\n [Symbol.asyncIterator](): AsyncIterator {\n let returnedSoFar = 0;\n return {\n next: () =>\n new Promise>(\n (resolve, reject) => {\n const callback = () => {\n if (this.controller.signal.aborted) {\n reject(new Error(\"SynyonymGroup has been aborted\"));\n } else if (returnedSoFar < this.names.length) {\n resolve({ value: this.names[returnedSoFar++] });\n } else if (this.isFinished) {\n resolve({ done: true, value: true });\n } else {\n const listener = () => {\n this.monitor.removeEventListener(\"updated\", listener);\n callback();\n };\n this.monitor.addEventListener(\"updated\", listener);\n }\n };\n callback();\n },\n ),\n };\n }\n}\n\n// TODO: CoL taxa without authority -- associate them with the Name directly\n// eg. 5KTTT is \"Quercus robur subsp. robur\" w/o authority\n\n/** The central object.\n *\n * Each `Name` exists because of a taxon-name, taxon-concept or col-taxon in the data.\n * Each `Name` is uniquely determined by its human-readable latin name (for taxa ranking below genus, this is a multi-part name \u2014 binomial or trinomial) and kingdom.\n */\nexport type Name = {\n /** taxonomic kingdom\n *\n * may be empty for some CoL-taxa with missing ancestors */\n kingdom: string;\n /** Human-readable name */\n displayName: string;\n /** taxonomic rank */\n rank: string;\n\n /** vernacular names */\n vernacularNames: Promise;\n\n // /** Contains the family tree / upper taxons accorindg to CoL / treatmentbank.\n // * //TODO */\n // trees: Promise<{\n // col?: Tree;\n // tb?: Tree;\n // }>;\n\n /** The URI of the respective `dwcFP:TaxonName` if it exists */\n taxonNameURI?: string;\n\n /** Catalogue of Life-Data */\n col?: {\n /** The URI of the respective CoL-taxon if it exists\n *\n * Note that this is only for CoL-taxa which do not have an authority.\n */\n colURI: string;\n /** The URI of the corresponding accepted CoL-taxon if it exists.\n *\n * The same as URI if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedURI: string;\n };\n\n /** All `AuthorizedName`s with this name */\n authorizedNames: AuthorizedName[];\n\n /** How this name was found */\n justification: Justification;\n\n /** treatments directly associated with .taxonNameUri */\n treatments: {\n treats: Set;\n cite: Set;\n };\n};\n\n/**\n * A map from language tags (IETF) to an array of vernacular names.\n */\nexport type vernacularNames = Map;\n\n/** Why a given Name was found (ther migth be other possible justifications) */\nexport type Justification = {\n searchTerm: true;\n /** indicates that this is a subTaxon of the parent */\n subTaxon: boolean;\n} | {\n searchTerm: false;\n parent: Name;\n /** if missing, indicates synonymy according to CoL or subTaxon */\n treatment?: Treatment;\n};\n\n/**\n * Corresponds to a taxon-concept or a CoL-Taxon\n */\nexport type AuthorizedName = {\n // TODO: neccesary?\n /** this may not be neccesary, as `AuthorizedName`s should only appear within a `Name` */\n // name: Name;\n /** Human-readable name */\n displayName: string;\n /** Human-readable authority */\n authority: string;\n /**\n * Human-readable authorities as given in the Data.\n */\n authorities: string[];\n\n /** The URIs of the respective `dwcFP:TaxonConcept` if it exists */\n taxonConceptURIs: string[];\n\n /** Catalogue of Life-Data */\n col?: {\n /** The URI of the respective CoL-taxon if it exists */\n colURI: string;\n /** The URI of the corresponding accepted CoL-taxon if it exists.\n *\n * The same as URI if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedURI: string;\n };\n\n // TODO: sensible?\n // /** these are CoL-taxa linked in the rdf, which differ lexically */\n // seeAlsoCol: string[];\n\n /** treatments directly associated with .taxonConceptURI */\n treatments: {\n def: Set;\n aug: Set;\n dpr: Set;\n cite: Set;\n };\n};\n\n/** A plazi-treatment */\nexport type Treatment = {\n url: string;\n date?: number;\n\n /** Details are behind a promise becuase they are loaded with a separate query. */\n details: Promise;\n};\n\n/** Details of a treatment */\nexport type TreatmentDetails = {\n materialCitations: MaterialCitation[];\n figureCitations: FigureCitation[];\n creators?: string;\n title?: string;\n treats: {\n def: Set;\n aug: Set;\n dpr: Set;\n citetc: Set;\n treattn: Set;\n citetn: Set;\n };\n};\n\n/** A cited material */\nexport type MaterialCitation = {\n \"catalogNumber\": string;\n \"collectionCode\"?: string;\n \"typeStatus\"?: string;\n \"countryCode\"?: string;\n \"stateProvince\"?: string;\n \"municipality\"?: string;\n \"county\"?: string;\n \"locality\"?: string;\n \"verbatimLocality\"?: string;\n \"recordedBy\"?: string;\n \"eventDate\"?: string;\n \"samplingProtocol\"?: string;\n \"decimalLatitude\"?: string;\n \"decimalLongitude\"?: string;\n \"verbatimElevation\"?: string;\n \"gbifOccurrenceId\"?: string;\n \"gbifSpecimenId\"?: string;\n \"httpUri\"?: string[];\n};\n\n/** A cited figure */\nexport type FigureCitation = {\n url: string;\n description?: string;\n};\n", "// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.\n// This module is browser compatible.\n\n/**\n * Returns all distinct elements in the given array, preserving order by first\n * occurrence.\n *\n * @typeParam T The type of the elements in the input array.\n *\n * @param array The array to filter for distinct elements.\n *\n * @returns An array of distinct elements in the input array.\n *\n * @example Basic usage\n * ```ts\n * import { distinct } from \"@std/collections/distinct\";\n * import { assertEquals } from \"@std/assert\";\n *\n * const numbers = [3, 2, 5, 2, 5];\n * const distinctNumbers = distinct(numbers);\n *\n * assertEquals(distinctNumbers, [3, 2, 5]);\n * ```\n */\nexport function distinct(array: Iterable): T[] {\n const set = new Set(array);\n\n return Array.from(set);\n}\n", "/// \nimport {\n type AuthorizedName,\n type Name,\n SparqlEndpoint,\n SynonymGroup,\n type Treatment,\n} from \"../mod.ts\";\nimport { distinct } from \"jsr:@std/collections/distinct\";\n\nconst params = new URLSearchParams(document.location.search);\nconst HIDE_COL_ONLY_SYNONYMS = !params.has(\"show_col\");\nconst START_WITH_SUBTAXA = params.has(\"subtaxa\");\nconst SORT_TREATMENTS_BY_TYPE = params.has(\"sort_treatments_by_type\");\nconst ENDPOINT_URL = params.get(\"server\") ||\n \"https://treatment.ld.plazi.org/sparql\";\nconst NAME = params.get(\"q\") ||\n \"https://www.catalogueoflife.org/data/taxon/3WD9M\";\n\nconst root = document.getElementById(\"root\") as HTMLDivElement;\n\nenum SynoStatus {\n Def = \"def\",\n Aug = \"aug\",\n Dpr = \"dpr\",\n Cite = \"cite\",\n}\n\nconst icons = {\n def:\n ``,\n aug:\n ``,\n dpr:\n ``,\n cite:\n ``,\n unknown:\n ``,\n\n col_aug:\n ``,\n col_dpr:\n ``,\n\n link:\n ``,\n\n expand:\n ``,\n collapse:\n ``,\n\n east:\n ``,\n west:\n ``,\n empty: ``,\n};\n\nconst indicator = document.createElement(\"div\");\nroot.insertAdjacentElement(\"beforebegin\", indicator);\nindicator.append(`Finding Synonyms for ${NAME} `);\nconst progress = document.createElement(\"progress\");\nindicator.append(progress);\n\nconst timeStart = performance.now();\n\nconst sparqlEndpoint = new SparqlEndpoint(ENDPOINT_URL);\nconst synoGroup = new SynonymGroup(\n sparqlEndpoint,\n NAME,\n HIDE_COL_ONLY_SYNONYMS,\n START_WITH_SUBTAXA,\n);\n\nclass SynoTreatment extends HTMLElement {\n constructor(trt: Treatment, status: SynoStatus) {\n super();\n\n this.innerHTML = icons[status] ?? icons.unknown;\n\n const button = document.createElement(\"button\");\n button.classList.add(\"icon\", \"button\");\n button.innerHTML = icons.expand;\n button.addEventListener(\"click\", () => {\n if (this.classList.toggle(\"expanded\")) {\n button.innerHTML = icons.collapse;\n } else {\n button.innerHTML = icons.expand;\n }\n });\n\n const date = document.createElement(\"span\");\n if (trt.date) date.innerText = \"\" + trt.date;\n else {\n date.classList.add(\"missing\");\n date.innerText = \"No Date\";\n }\n this.append(date);\n\n const spinner = document.createElement(\"progress\");\n this.append(\": \", spinner);\n\n const url = document.createElement(\"a\");\n url.classList.add(\"treatment\", \"uri\");\n url.href = trt.url;\n url.target = \"_blank\";\n url.innerText = trt.url.replace(\"http://treatment.plazi.org/id/\", \"\");\n url.innerHTML += icons.link;\n this.append(\" \", url);\n\n this.append(button);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\", \"details\");\n this.append(names);\n\n trt.details.then((details) => {\n const creators = document.createElement(\"span\");\n const title = document.createElement(\"i\");\n spinner.replaceWith(creators, \" \", title);\n\n if (details.creators) creators.innerText = details.creators;\n else {\n creators.classList.add(\"missing\");\n creators.innerText = \"No Authors\";\n }\n\n if (details.title) title.innerText = \"\u201C\" + details.title + \"\u201D\";\n else {\n title.classList.add(\"missing\");\n title.innerText = \"No Title\";\n }\n\n if (details.treats.def.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.east;\n line.innerHTML = icons.east;\n line.innerHTML += icons.def;\n if (status === SynoStatus.Def || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.def.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.aug.size > 0 || details.treats.treattn.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.east;\n line.innerHTML = icons.east;\n line.innerHTML += icons.aug;\n if (status === SynoStatus.Aug || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.aug.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n details.treats.treattn.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-name.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.dpr.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.west;\n line.innerHTML = icons.west;\n line.innerHTML += icons.dpr;\n if (status === SynoStatus.Dpr || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.dpr.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.citetc.size > 0 || details.treats.citetn.size > 0) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.empty + icons.cite;\n // if (status === SynoStatus.Dpr || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n // }\n names.append(line);\n\n details.treats.citetc.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n details.treats.citetn.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-name.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.figureCitations.length > 0) {\n const line = document.createElement(\"div\");\n line.classList.add(\"figures\", \"hidden\");\n names.append(line);\n for (const figure of details.figureCitations) {\n const el = document.createElement(\"figure\");\n line.append(el);\n const img = document.createElement(\"img\");\n img.src = figure.url;\n img.loading = \"lazy\";\n img.alt = figure.description ?? \"Cited Figure without caption\";\n el.append(img);\n const caption = document.createElement(\"figcaption\");\n caption.innerText = figure.description ?? \"\";\n el.append(caption);\n }\n }\n if (details.materialCitations.length > 0) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.empty + icons.cite +\n \" Material Citations:
-\";\n line.classList.add(\"hidden\");\n names.append(line);\n line.innerText += details.materialCitations.map((c) =>\n JSON.stringify(c)\n .replaceAll(\"{\", \"\")\n .replaceAll(\"}\", \"\")\n .replaceAll('\":', \": \")\n .replaceAll(\",\", \", \")\n .replaceAll('\"', \"\")\n ).join(\"\\n -\");\n }\n });\n }\n}\ncustomElements.define(\"syno-treatment\", SynoTreatment);\n\nclass SynoName extends HTMLElement {\n constructor(name: Name) {\n super();\n\n const title = document.createElement(\"h2\");\n const name_title = document.createElement(\"i\");\n name_title.innerText = name.displayName;\n title.append(name_title);\n this.append(title);\n\n const rank_badge = document.createElement(\"span\");\n rank_badge.classList.add(\"rank\");\n rank_badge.innerText = name.rank;\n const kingdom_badge = document.createElement(\"span\");\n kingdom_badge.classList.add(\"rank\");\n kingdom_badge.innerText = name.kingdom || \"Missing Kingdom\";\n title.append(\" \", kingdom_badge, \" \", rank_badge);\n\n if (name.taxonNameURI) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n const short = name.taxonNameURI.replace(\n \"http://taxon-name.plazi.org/id/\",\n \"\",\n );\n name_uri.innerText = short;\n name_uri.id = short;\n name_uri.href = name.taxonNameURI;\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n title.append(\" \", name_uri);\n }\n\n const vernacular = document.createElement(\"div\");\n vernacular.classList.add(\"vernacular\");\n name.vernacularNames.then((names) => {\n if (names.size > 0) {\n vernacular.innerText = \"\u201C\" +\n distinct([...names.values()].flat()).join(\"\u201D, \u201C\") + \"\u201D\";\n }\n });\n this.append(vernacular);\n\n const treatments = document.createElement(\"ul\");\n this.append(treatments);\n\n if (name.col) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.col.colURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.id = id;\n col_uri.href = name.col.colURI;\n col_uri.target = \"_blank\";\n col_uri.innerHTML += icons.link;\n title.append(\" \", col_uri);\n\n const li = document.createElement(\"div\");\n li.classList.add(\"treatmentline\");\n li.innerHTML = name.col.acceptedURI !== name.col.colURI\n ? icons.col_dpr\n : icons.col_aug;\n treatments.append(li);\n\n const creators = document.createElement(\"span\");\n creators.innerText = \"Catalogue of Life\";\n li.append(creators);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\");\n li.append(names);\n\n if (name.col.acceptedURI !== name.col.colURI) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.east + icons.col_aug;\n names.append(line);\n\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.col.acceptedURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.href = `#${id}`;\n col_uri.title = \"show name\";\n line.append(col_uri);\n synoGroup.findName(name.col.acceptedURI).then((n) => {\n if ((n as AuthorizedName).authority) {\n col_uri.innerText = n.displayName + \" \" +\n (n as AuthorizedName).authority;\n } else col_uri.innerText = n.displayName;\n }, () => {\n col_uri.removeAttribute(\"href\");\n });\n }\n }\n if (name.treatments.treats.size > 0 || name.treatments.cite.size > 0) {\n for (const trt of name.treatments.treats) {\n const li = new SynoTreatment(trt, SynoStatus.Aug);\n treatments.append(li);\n }\n for (const trt of name.treatments.cite) {\n const li = new SynoTreatment(trt, SynoStatus.Cite);\n treatments.append(li);\n }\n }\n\n const justification = document.createElement(\"abbr\");\n justification.classList.add(\"justification\");\n justification.innerText = \"...?\";\n justify(name).then((just) => justification.title = `This ${just}`);\n title.append(\" \", justification);\n\n for (const authorizedName of name.authorizedNames) {\n const authName = document.createElement(\"h3\");\n const name_title = document.createElement(\"i\");\n name_title.innerText = authorizedName.displayName;\n name_title.classList.add(\"gray\");\n authName.append(name_title);\n authName.append(\" \", authorizedName.authority);\n this.append(authName);\n\n const treatments = document.createElement(\"ul\");\n this.append(treatments);\n\n if (authorizedName.taxonConceptURIs[0]) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n // TODO handle other URIs\n const short = authorizedName.taxonConceptURIs[0].replace(\n \"http://taxon-concept.plazi.org/id/\",\n \"\",\n );\n name_uri.innerText = short;\n name_uri.id = short;\n name_uri.href = authorizedName.taxonConceptURIs[0];\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n authName.append(\" \", name_uri);\n }\n if (authorizedName.col) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.col.colURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.id = id;\n col_uri.href = authorizedName.col.colURI;\n col_uri.target = \"_blank\";\n col_uri.innerHTML += icons.link;\n authName.append(\" \", col_uri);\n\n const li = document.createElement(\"div\");\n li.classList.add(\"treatmentline\");\n li.innerHTML =\n authorizedName.col.acceptedURI !== authorizedName.col.colURI\n ? icons.col_dpr\n : icons.col_aug;\n treatments.append(li);\n\n const creators = document.createElement(\"span\");\n creators.innerText = \"Catalogue of Life\";\n li.append(creators);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\");\n li.append(names);\n\n if (authorizedName.col.acceptedURI !== authorizedName.col.colURI) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.east + icons.col_aug;\n names.append(line);\n\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.col.acceptedURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.href = `#${id}`;\n col_uri.title = \"show name\";\n line.append(\" \", col_uri);\n synoGroup.findName(authorizedName.col.acceptedURI).then((n) => {\n col_uri.classList.remove(\"uri\");\n if ((n as AuthorizedName).authority) {\n col_uri.innerText = n.displayName + \" \" +\n (n as AuthorizedName).authority;\n } else col_uri.innerText = n.displayName;\n }, () => {\n col_uri.removeAttribute(\"href\");\n });\n }\n }\n\n const treatments_array: { trt: Treatment; status: SynoStatus }[] = [];\n\n for (const trt of authorizedName.treatments.def) {\n treatments_array.push({ trt, status: SynoStatus.Def });\n }\n for (const trt of authorizedName.treatments.aug) {\n treatments_array.push({ trt, status: SynoStatus.Aug });\n }\n for (const trt of authorizedName.treatments.dpr) {\n treatments_array.push({ trt, status: SynoStatus.Dpr });\n }\n for (const trt of authorizedName.treatments.cite) {\n treatments_array.push({ trt, status: SynoStatus.Cite });\n }\n\n if (!SORT_TREATMENTS_BY_TYPE) {\n treatments_array.sort((a, b) => {\n if (a.trt.date && b.trt.date) return a.trt.date - b.trt.date;\n if (a.trt.date) return 1;\n if (b.trt.date) return -1;\n return 0;\n });\n }\n\n for (const { trt, status } of treatments_array) {\n const li = new SynoTreatment(trt, status);\n treatments.append(li);\n }\n }\n }\n}\ncustomElements.define(\"syno-name\", SynoName);\n\nasync function justify(name: Name): Promise {\n if (name.justification.searchTerm) {\n if (name.justification.subTaxon) {\n return \"is a sub-taxon of the search term.\";\n } else return \"is the search term.\";\n } else if (name.justification.treatment) {\n const details = await name.justification.treatment.details;\n const parent = await justify(name.justification.parent);\n return `is, according to ${details.creators} ${name.justification.treatment.date},\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n // return `is, according to ${details.creators} ${details.date} \u201C${details.title||\"No Title\"}\u201D ${name.justification.treatment.url},\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n } else {\n const parent = await justify(name.justification.parent);\n return `is, according to the Catalogue of Life,\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n }\n}\n\nfor await (const name of synoGroup) {\n const element = new SynoName(name);\n root.append(element);\n}\n\nconst timeEnd = performance.now();\n\nindicator.innerHTML = \"\";\nindicator.innerText =\n `Found ${synoGroup.names.length} names with ${synoGroup.treatments.size} treatments. This took ${\n (timeEnd - timeStart) / 1000\n } seconds.`;\nif (synoGroup.names.length === 0) root.append(\":[\");\n"], - "mappings": "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", + "sourcesContent": ["async function sleep(ms: number): Promise {\n const p = new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n return await p;\n}\n\n/** Describes the format of the JSON return by SPARQL endpoints */\nexport type SparqlJson = {\n head: {\n vars: string[];\n };\n results: {\n bindings: {\n [key: string]:\n | { type: string; value: string; \"xml:lang\"?: string }\n | undefined;\n }[];\n };\n};\n\n/**\n * Represents a remote sparql endpoint and provides a uniform way to run queries.\n */\nexport class SparqlEndpoint {\n /** Create a new SparqlEndpoint with the given URI */\n constructor(private sparqlEnpointUri: string) {}\n\n /** @ignore */\n // reasons: string[] = [];\n\n /**\n * Run a query against the sparql endpoint\n *\n * It automatically retries up to 10 times on fetch errors, waiting 50ms on the first retry and doupling the wait each time.\n * Retries are logged to the console (`console.warn`)\n *\n * @throws In case of non-ok response status codes or if fetch failed 10 times.\n * @param query The sparql query to run against the endpoint\n * @param fetchOptions Additional options for the `fetch` request\n * @param _reason (Currently ignored, used internally for debugging purposes)\n * @returns Results of the query\n */\n async getSparqlResultSet(\n query: string,\n fetchOptions: RequestInit = {},\n _reason = \"\",\n ): Promise {\n // this.reasons.push(_reason);\n // DEBUG: console.info(`SPARQL ${_reason}:\\n${query}`);\n\n fetchOptions.headers = fetchOptions.headers || {};\n (fetchOptions.headers as Record)[\"Accept\"] =\n \"application/sparql-results+json\";\n let retryCount = 0;\n const sendRequest = async (): Promise => {\n try {\n // DEBUG: console.info(`SPARQL ${_reason} (${retryCount + 1})`);\n const response = await fetch(\n this.sparqlEnpointUri + \"?query=\" + encodeURIComponent(query),\n fetchOptions,\n );\n if (!response.ok) {\n throw new Error(\"Response not ok. Status \" + response.status);\n }\n return await response.json();\n } catch (error) {\n if (fetchOptions.signal?.aborted) {\n throw error;\n } else if (retryCount < 10) {\n const wait = 50 * (1 << retryCount++);\n console.info(`!! Fetch Error. Retrying in ${wait}ms (${retryCount})`);\n await sleep(wait);\n fetchOptions.cache = \"no-cache\"; // do not attempt to use cache on retry (this will populate the chache on success though)\n return await sendRequest();\n }\n console.warn(\"!! Fetch Error:\", query, \"\\n---\\n\", error);\n throw error;\n }\n };\n return await sendRequest();\n }\n}\n", "/**\n * Common to all of the `getNameFrom_`-queries.\n *\n * As its own variable to ensure consistency in the resturned bindings.\n */\nconst preamble = `PREFIX dc: \nPREFIX dwc: \nPREFIX dwcFP: \nPREFIX cito: \nPREFIX trt: \nSELECT DISTINCT ?kingdom ?tn ?tc ?col ?acceptedcol ?rank ?genus ?section ?subgenus ?species ?infrasp ?name ?authority\n (group_concat(DISTINCT ?tcauth;separator=\" / \") AS ?tcAuth)\n (group_concat(DISTINCT ?aug;separator=\"|\") as ?augs)\n (group_concat(DISTINCT ?def;separator=\"|\") as ?defs)\n (group_concat(DISTINCT ?dpr;separator=\"|\") as ?dprs)\n (group_concat(DISTINCT ?cite;separator=\"|\") as ?cites)\n (group_concat(DISTINCT ?trtn;separator=\"|\") as ?tntreats)\n (group_concat(DISTINCT ?citetn;separator=\"|\") as ?tncites)`;\n\n/**\n * Common to all of the `getNameFrom_`-queries.\n *\n * As its own variable to ensure consistency in the resturned bindings.\n */\nconst postamble =\n `GROUP BY ?kingdom ?tn ?tc ?col ?acceptedcol ?rank ?genus ?section ?subgenus ?species ?infrasp ?name ?authority`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromCol = (colUri: string) =>\n `${preamble} WHERE {\nBIND(<${colUri}> as ?col)\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name .\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n OPTIONAL {\n ?col dwc:specificEpithet ?colspecies .\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n }\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n\n BIND(COALESCE(?colkingdom, \"\") AS ?kingdom)\n BIND(COALESCE(?colsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?colspecies, \"\") AS ?species)\n BIND(COALESCE(?colinfrasp, \"\") AS ?infrasp)\n\n OPTIONAL {\n ?tn dwc:rank ?trank ;\n a dwcFP:TaxonName .\n FILTER(LCASE(?rank) = LCASE(?trank))\n ?tn dwc:genus ?genus .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n FILTER(?subgenus = COALESCE(?tnsubgenus, COALESCE(?section, \"\")))\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL { ?tn dwc:species ?tnspecies . }\n FILTER(?species = COALESCE(?tnspecies, \"\"))\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n FILTER(?infrasp = COALESCE(?tninfrasp, \"\"))\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?tc trt:hasTaxonName ?tn ; dwc:scientificNameAuthorship ?tcauth ; a dwcFP:TaxonConcept .\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n }\n }\n}\n${postamble}\nLIMIT 500`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromTC = (tcUri: string) =>\n `${preamble} WHERE {\n <${tcUri}> trt:hasTaxonName ?tn .\n ?tc trt:hasTaxonName ?tn ;\n dwc:scientificNameAuthorship ?tcauth ;\n a dwcFP:TaxonConcept .\n\n ?tn a dwcFP:TaxonName .\n ?tn dwc:rank ?tnrank .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n ?tn dwc:genus ?genus .\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL {\n ?tn dwc:species ?tnspecies .\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n }\n \n BIND(LCASE(?tnrank) AS ?rank)\n BIND(COALESCE(?tnsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?tnspecies, \"\") AS ?species)\n BIND(COALESCE(?tninfrasp, \"\") AS ?infrasp)\n \n OPTIONAL {\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name . # Note: contains authority\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n FILTER(?kingdom = COALESCE(?colkingdom, \"\"))\n\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n FILTER(COALESCE(?tnsubgenus, COALESCE(?section, \"\")) = COALESCE(?colsubgenus, \"\"))\n OPTIONAL { ?col dwc:specificEpithet ?colspecies . }\n FILTER(?species = COALESCE(?colspecies, \"\"))\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n FILTER(?infrasp = COALESCE(?colinfrasp, \"\"))\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n }\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n}\n${postamble}\nLIMIT 500`;\n\n/**\n * Note: this query assumes that there is no sub-species taxa with missing dwc:species\n *\n * Note: the handling assumes that at most one taxon-name matches this colTaxon\n */\nexport const getNameFromTN = (tnUri: string) =>\n `${preamble} WHERE {\n BIND(<${tnUri}> as ?tn)\n ?tn a dwcFP:TaxonName .\n ?tn dwc:rank ?tnrank .\n ?tn dwc:genus ?genus .\n { ?tn dwc:kingdom ?kingdom . } UNION { ?tn trt:hasParentName* ?k . ?k dwc:rank \"kingdom\" ; dwc:kingdom ?kingdom . }\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n OPTIONAL { ?tn dwc:section ?section . }\n OPTIONAL {\n ?tn dwc:species ?tnspecies .\n OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . }\n }\n \n BIND(LCASE(?tnrank) AS ?rank)\n BIND(COALESCE(?tnsubgenus, \"\") AS ?subgenus)\n BIND(COALESCE(?tnspecies, \"\") AS ?species)\n BIND(COALESCE(?tninfrasp, \"\") AS ?infrasp)\n \n OPTIONAL {\n ?col dwc:taxonRank ?rank .\n ?col dwc:scientificName ?name . # Note: contains authority\n ?col dwc:genericName ?genus .\n {\n ?col dwc:acceptedName ?acceptedcol .\n } UNION {\n ?col dwc:taxonomicStatus ?col_status . # TODO: unused\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?acceptedcol)\n }\n OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n FILTER(?kingdom = COALESCE(?colkingdom, \"\"))\n\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n FILTER(COALESCE(?tnsubgenus, COALESCE(?section, \"\")) = COALESCE(?colsubgenus, \"\"))\n OPTIONAL { ?col dwc:specificEpithet ?colspecies . }\n FILTER(?species = COALESCE(?colspecies, \"\"))\n OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . }\n FILTER(?infrasp = COALESCE(?colinfrasp, \"\"))\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n }\n\n OPTIONAL {\n ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate .\n BIND(CONCAT(STR(?trtnt), \">\", ?trtndate) AS ?trtn)\n }\n OPTIONAL {\n ?citetnt trt:citesTaxonName ?tn ; trt:publishedIn/dc:date ?citetndate .\n BIND(CONCAT(STR(?citetnt), \">\", ?citetndate) AS ?citetn)\n }\n\n OPTIONAL {\n ?tc trt:hasTaxonName ?tn ; dwc:scientificNameAuthorship ?tcauth ; a dwcFP:TaxonConcept .\n\n OPTIONAL {\n ?augt trt:augmentsTaxonConcept ?tc ; trt:publishedIn/dc:date ?augdate .\n BIND(CONCAT(STR(?augt), \">\", ?augdate) AS ?aug)\n }\n OPTIONAL {\n ?deft trt:definesTaxonConcept ?tc ; trt:publishedIn/dc:date ?defdate .\n BIND(CONCAT(STR(?deft), \">\", ?defdate) AS ?def)\n }\n OPTIONAL {\n ?dprt trt:deprecates ?tc ; trt:publishedIn/dc:date ?dprdate .\n BIND(CONCAT(STR(?dprt), \">\", ?dprdate) AS ?dpr)\n }\n OPTIONAL {\n ?citet cito:cites ?tc ; trt:publishedIn/dc:date ?citedate .\n BIND(CONCAT(STR(?citet), \">\", ?citedate) AS ?cite)\n }\n }\n}\n${postamble}\nLIMIT 500`;\n", "export function unifyAuthorithy(a: string, b: string): string | null {\n const as = a.split(/\\s*[,]\\s*/);\n const bs = b.split(/\\s*[,]\\s*/);\n const yearA = (as.length > 0 && /\\d{4}/.test(as.at(-1)!)) ? as.pop()! : null;\n const yearB = (bs.length > 0 && /\\d{4}/.test(bs.at(-1)!)) ? bs.pop()! : null;\n const etalA = as.length > 0 && /\\s*et\\.?\\s*al\\.?/.test(as.at(-1)!);\n const etalB = bs.length > 0 && /\\s*et\\.?\\s*al\\.?/.test(bs.at(-1)!);\n if (etalA) {\n as[as.length - 1] = as[as.length - 1].replace(/\\s*et\\.?\\s*al\\.?/, \"\");\n }\n if (etalB) {\n bs[bs.length - 1] = bs[bs.length - 1].replace(/\\s*et\\.?\\s*al\\.?/, \"\");\n }\n\n if (!etalA && !etalB && as.length != bs.length) return null;\n\n const result: string[] = [];\n let i = 0;\n for (; i < as.length && i < bs.length; i++) {\n const r = unifySingleName(as[i], bs[i]);\n if (r !== null) result.push(r);\n else return null;\n }\n for (let j = i; j < as.length; j++) {\n if (as[j]) result.push(as[j]);\n }\n for (let j = i; j < bs.length; j++) {\n if (bs[j]) result.push(bs[j]);\n }\n\n if (yearA && yearB) {\n if (yearA === yearB) result.push(yearA);\n else return null;\n } else if (yearA) {\n result.push(yearA);\n } else if (yearB) {\n result.push(yearB);\n }\n\n return result.join(\", \");\n}\n\nfunction unifySingleName(a: string, b: string) {\n let prefixA = a.replaceAll(\"-\", \" \");\n let prefixB = b.replaceAll(\"-\", \" \");\n if (prefixA.endsWith(\".\") || prefixB.endsWith(\".\")) {\n // might be abbreviation\n // normalize to get compatible string lengths\n const longA = prefixA.normalize(\"NFKC\");\n const longB = prefixB.normalize(\"NFKC\");\n const indexA = longA.lastIndexOf(\".\");\n const indexB = longB.lastIndexOf(\".\");\n const index = indexA !== -1\n ? (indexB !== -1 ? Math.min(indexA, indexB) : indexA)\n : indexB;\n prefixA = longA.substring(0, index);\n prefixB = longB.substring(0, index);\n }\n\n if (isEquivalent(prefixA, prefixB)) {\n // normalize such that accents are represented with combining characters\n // so that the version with accents is longer\n const normA = a.normalize(\"NFD\");\n const normB = b.normalize(\"NFD\");\n return normA.length >= normB.length ? a : b;\n }\n return null;\n}\n\nfunction isEquivalent(a: string, b: string): boolean {\n return a.localeCompare(b, \"en\", {\n sensitivity: \"base\", // a = \u00E4, A = a, a \u2260 b\n usage: \"search\",\n }) === 0;\n}\n", "import type { SparqlEndpoint, SparqlJson } from \"./mod.ts\";\nimport * as Queries from \"./Queries.ts\";\nimport { unifyAuthorithy } from \"./UnifyAuthorities.ts\";\n\n/** Finds all synonyms of a taxon */\nexport class SynonymGroup implements AsyncIterable {\n /** Indicates whether the SynonymGroup has found all synonyms.\n *\n * @readonly\n */\n isFinished = false;\n /** Used internally to watch for new names found */\n private monitor: EventTarget = new EventTarget();\n\n /** Used internally to abort in-flight network requests when SynonymGroup is aborted */\n private controller = new AbortController();\n\n /** The SparqlEndpoint used */\n private sparqlEndpoint: SparqlEndpoint;\n\n private fetchOptions: RequestInit = {\n signal: this.controller.signal,\n cache: \"force-cache\",\n };\n\n /**\n * List of names found so-far.\n *\n * Contains full list of synonyms _if_ .isFinished and not .isAborted\n *\n * @readonly\n */\n names: Name[] = [];\n /**\n * Add a new Name to this.names.\n *\n * Note: does not deduplicate on its own\n *\n * @internal */\n private pushName(name: Name) {\n this.names.push(name);\n this.monitor.dispatchEvent(new CustomEvent(\"updated\"));\n }\n\n /**\n * Call when all synonyms are found\n *\n * @internal */\n private finish() {\n this.isFinished = true;\n this.monitor.dispatchEvent(new CustomEvent(\"updated\"));\n }\n\n /** contains TN, TC, CoL uris of synonyms which are in-flight somehow or are done already */\n private expanded = new Set(); // new Map();\n\n /** contains CoL uris where we don't need to check for Col \"acceptedName\" links\n *\n * col -> accepted col\n */\n private acceptedCol = new Map();\n\n /**\n * Used internally to deduplicate treatments, maps from URI to Object.\n *\n * Contains full list of treatments _if_ .isFinished and not .isAborted\n *\n * @readonly\n */\n treatments: Map = new Map();\n\n /**\n * Whether to show taxa deprecated by CoL that would not have been found otherwise.\n * This significantly increases the number of results in some cases.\n */\n ignoreDeprecatedCoL: boolean;\n\n /**\n * if set to true, subTaxa of the search term are also considered as starting points.\n *\n * Note that \"intermediate\" ranks like subGenus and section are always included when searching for a genus by latin name.\n */\n startWithSubTaxa: boolean;\n\n /**\n * Constructs a SynonymGroup\n *\n * @param sparqlEndpoint SPARQL-Endpoint to query\n * @param taxonName either a string of the form \"Genus species infraspecific\" (species & infraspecific names optional), or an URI of a http://filteredpush.org/ontologies/oa/dwcFP#TaxonConcept or ...#TaxonName or a CoL taxon URI\n * @param [ignoreDeprecatedCoL=true] Whether to show taxa deprecated by CoL that would not have been found otherwise\n * @param [startWithSubTaxa=false] if set to true, subTaxa of the search term are also considered as starting points.\n */\n constructor(\n sparqlEndpoint: SparqlEndpoint,\n taxonName: string,\n ignoreDeprecatedCoL = true,\n startWithSubTaxa = false,\n ) {\n this.sparqlEndpoint = sparqlEndpoint;\n this.ignoreDeprecatedCoL = ignoreDeprecatedCoL;\n this.startWithSubTaxa = startWithSubTaxa;\n\n if (taxonName.startsWith(\"http\")) {\n this.getName(taxonName, { searchTerm: true, subTaxon: false })\n .catch((e) => {\n console.log(\"SynoGroup Failure: \", e);\n this.controller.abort(\"SynoGroup Failed\");\n })\n .finally(() => this.finish());\n } else {\n const name = [\n ...taxonName.split(\" \").filter((n) => !!n),\n undefined,\n undefined,\n ] as [string, string | undefined, string | undefined];\n this.getNameFromLatin(name, { searchTerm: true, subTaxon: false })\n .finally(\n () => this.finish(),\n );\n }\n }\n\n /**\n * Finds the given name (identified by taxon-name, taxon-concept or CoL uri) among the list of synonyms.\n *\n * Will reject when the SynonymGroup finishes but the name was not found \u2014 this means that this was not a synonym.\n */\n findName(uri: string): Promise {\n let name: Name | AuthorizedName | undefined;\n for (const n of this.names) {\n if (n.taxonNameURI === uri || n.col?.colURI === uri) {\n name = n;\n break;\n }\n const an = n.authorizedNames.find((an) =>\n an.col?.colURI === uri || an.taxonConceptURIs.includes(uri)\n );\n if (an) {\n name = an;\n break;\n }\n }\n if (name) return Promise.resolve(name);\n return new Promise((resolve, reject) => {\n this.monitor.addEventListener(\"updated\", () => {\n if (this.names.length === 0 || this.isFinished) reject();\n const n = this.names.at(-1)!;\n if (n.taxonNameURI === uri || n.col?.colURI === uri) {\n resolve(n);\n return;\n }\n const an = n.authorizedNames.find((an) =>\n an.col?.colURI === uri || an.taxonConceptURIs.includes(uri)\n );\n if (an) {\n resolve(an);\n return;\n }\n });\n });\n }\n\n /** @internal */\n private async getName(\n taxonName: string,\n justification: Justification,\n ): Promise {\n if (this.expanded.has(taxonName)) {\n console.log(\"Skipping known\", taxonName);\n return;\n }\n\n if (this.controller.signal?.aborted) return Promise.reject();\n\n let json: SparqlJson | undefined;\n\n if (taxonName.startsWith(\"https://www.catalogueoflife.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromCol(taxonName),\n this.fetchOptions,\n `NameFromCol ${taxonName}`,\n );\n } else if (taxonName.startsWith(\"http://taxon-concept.plazi.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromTC(taxonName),\n this.fetchOptions,\n `NameFromTC ${taxonName}`,\n );\n } else if (taxonName.startsWith(\"http://taxon-name.plazi.org\")) {\n json = await this.sparqlEndpoint.getSparqlResultSet(\n Queries.getNameFromTN(taxonName),\n this.fetchOptions,\n `NameFromTN ${taxonName}`,\n );\n } else {\n throw `Cannot handle name-uri <${taxonName}> !`;\n }\n\n await this.handleName(json!, justification);\n\n if (\n this.startWithSubTaxa && justification.searchTerm &&\n !justification.subTaxon\n ) {\n await this.getSubtaxa(taxonName);\n }\n }\n\n /** @internal */\n private async getSubtaxa(url: string): Promise {\n const query = url.startsWith(\"http://taxon-concept.plazi.org\")\n ? `\nPREFIX trt: \nSELECT DISTINCT ?sub WHERE {\n BIND(<${url}> as ?url)\n ?sub trt:hasParentName*/^trt:hasTaxonName ?url .\n}\nLIMIT 5000`\n : `\nPREFIX dwc: \nPREFIX trt: \nSELECT DISTINCT ?sub WHERE {\n BIND(<${url}> as ?url)\n ?sub (dwc:parent|trt:hasParentName)* ?url .\n}\nLIMIT 5000`;\n\n if (this.controller.signal?.aborted) return Promise.reject();\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n this.fetchOptions,\n `Subtaxa ${url}`,\n );\n\n const names = json.results.bindings\n .map((n) => n.sub?.value)\n .filter((n) => n && !this.expanded.has(n)) as string[];\n\n await Promise.allSettled(\n names.map((n) => this.getName(n, { searchTerm: true, subTaxon: true })),\n );\n }\n\n /** @internal */\n private async getNameFromLatin(\n [genus, species, infrasp]: [string, string | undefined, string | undefined],\n justification: Justification,\n ): Promise {\n const query = `\n PREFIX dwc: \nSELECT DISTINCT ?uri WHERE {\n ?uri dwc:genus|dwc:genericName \"${genus}\" .\n ${\n species\n ? `?uri dwc:species|dwc:specificEpithet \"${species}\" .`\n : \"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species . }\"\n }\n ${\n infrasp\n ? `?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet \"${infrasp}\" .`\n : \"FILTER NOT EXISTS { ?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet ?infrasp . }\"\n }\n}\nLIMIT 500`;\n\n if (this.controller.signal?.aborted) return Promise.reject();\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n this.fetchOptions,\n `NameFromLatin ${genus} ${species} ${infrasp}`,\n );\n\n const names = json.results.bindings\n .map((n) => n.uri?.value)\n .filter((n) => n && !this.expanded.has(n)) as string[];\n\n await Promise.allSettled(names.map((n) => this.getName(n, justification)));\n }\n\n /**\n * Note this makes some assumptions on which variables are present in the bindings\n *\n * @internal */\n private async handleName(\n json: SparqlJson,\n justification: Justification,\n ): Promise {\n const treatmentPromises: Treatment[] = [];\n\n const abbreviateRank = (rank: string) => {\n switch (rank) {\n case \"variety\":\n return \"var.\";\n case \"subspecies\":\n return \"subsp.\";\n case \"form\":\n return \"f.\";\n default:\n return rank;\n }\n };\n\n const displayName: string = (json.results.bindings[0].name\n ? (\n json.results.bindings[0].authority\n ? json.results.bindings[0].name.value\n .replace(\n json.results.bindings[0].authority.value,\n \"\",\n )\n : json.results.bindings[0].name.value\n )\n : json.results.bindings[0].genus!.value +\n (json.results.bindings[0].section?.value\n ? ` sect. ${json.results.bindings[0].section.value}`\n : \"\") +\n (json.results.bindings[0].subgenus?.value\n ? ` (${json.results.bindings[0].subgenus.value})`\n : \"\") +\n (json.results.bindings[0].species?.value\n ? ` ${json.results.bindings[0].species.value}`\n : \"\") +\n (json.results.bindings[0].infrasp?.value\n ? ` ${abbreviateRank(json.results.bindings[0].rank!.value)} ${\n json.results.bindings[0].infrasp.value\n }`\n : \"\")).trim();\n\n // Case where the CoL-taxon has no authority. There should only be one of these.\n let unathorizedCol: { colURI: string; acceptedURI: string } | undefined;\n\n // there can be multiple CoL-taxa with same latin name, e.g. Leontopodium alpinum has 3T6ZY and 3T6ZX.\n const authorizedNames: AuthorizedName[] = [];\n\n const taxonNameURI = json.results.bindings[0].tn?.value;\n if (taxonNameURI) {\n if (this.expanded.has(taxonNameURI)) return;\n this.expanded.add(taxonNameURI); //, NameStatus.madeName);\n }\n\n const expandedHere = new Set();\n\n for (const t of json.results.bindings) {\n if (t.col) {\n const colURI = t.col.value;\n if (!t.authority?.value) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n if (unathorizedCol && unathorizedCol.colURI !== colURI) {\n console.log(\"Duplicate unathorized COL:\", unathorizedCol, colURI);\n }\n unathorizedCol = {\n colURI,\n acceptedURI: t.acceptedcol?.value ?? \"INVALID COL\",\n };\n } else if (!authorizedNames.find((e) => e.col?.colURI === colURI)) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n if (!expandedHere.has(colURI)) {\n expandedHere.add(colURI);\n // TODO: handle unification of names\n // might not be neccessary, assuming all CoL-taxa are non-unifiable and\n // they are always handled first\n authorizedNames.push({\n displayName,\n authority: t.authority!.value,\n authorities: [t.authority!.value],\n col: {\n colURI: t.col.value,\n acceptedURI: t.acceptedcol?.value ?? \"INAVLID COL\",\n },\n taxonConceptURIs: [],\n treatments: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n cite: new Set(),\n },\n });\n }\n }\n }\n\n if (t.tc && t.tcAuth && t.tcAuth.value) {\n if (this.expanded.has(t.tc.value)) {\n console.log(\"Skipping known\", t.tc.value);\n return;\n } else if (!expandedHere.has(t.tc.value)) {\n expandedHere.add(t.tc.value);\n\n const def = this.makeTreatmentSet(t.defs?.value.split(\"|\"));\n const aug = this.makeTreatmentSet(t.augs?.value.split(\"|\"));\n const dpr = this.makeTreatmentSet(t.dprs?.value.split(\"|\"));\n const cite = this.makeTreatmentSet(t.cites?.value.split(\"|\"));\n\n def.forEach((t) => treatmentPromises.push(t));\n aug.forEach((t) => treatmentPromises.push(t));\n dpr.forEach((t) => treatmentPromises.push(t));\n\n const prevName = authorizedNames.find((e) =>\n unifyAuthorithy(e.authority, t.tcAuth!.value) !== null\n // t.tcAuth!.value.split(\" / \").some((auth) =>\n // unifyAuthorithy(e.authority, auth) !== null\n // )\n );\n if (prevName) {\n // TODO: I feel like this could be made much more efficient -- we are unifying repeatedly\n const best = t.tcAuth!.value; // .split(\" / \").find((auth) =>\n // unifyAuthorithy(prevName.authority, auth) !== null\n // )!;\n\n prevName.authority = unifyAuthorithy(prevName.authority, best)!;\n prevName.authorities.push(...t.tcAuth.value.split(\" / \"));\n prevName.taxonConceptURIs.push(t.tc.value);\n prevName.treatments = {\n def: prevName.treatments.def.union(def),\n aug: prevName.treatments.aug.union(aug),\n dpr: prevName.treatments.dpr.union(dpr),\n cite: prevName.treatments.cite.union(cite),\n };\n } else {\n authorizedNames.push({\n displayName,\n authority: t.tcAuth.value,\n authorities: t.tcAuth.value.split(\" / \"),\n taxonConceptURIs: [t.tc.value],\n treatments: {\n def,\n aug,\n dpr,\n cite,\n },\n });\n }\n }\n }\n }\n\n const treats = this.makeTreatmentSet(\n json.results.bindings[0].tntreats?.value.split(\"|\"),\n );\n treats.forEach((t) => treatmentPromises.push(t));\n\n const name: Name = {\n kingdom: json.results.bindings[0].kingdom!.value,\n displayName,\n rank: json.results.bindings[0].rank!.value,\n taxonNameURI,\n authorizedNames: authorizedNames,\n col: unathorizedCol,\n justification,\n treatments: {\n treats,\n cite: this.makeTreatmentSet(\n json.results.bindings[0].tncites?.value.split(\"|\"),\n ),\n },\n vernacularNames: taxonNameURI\n ? this.getVernacular(taxonNameURI)\n : Promise.resolve(new Map()),\n };\n\n for (const authName of name.authorizedNames) {\n if (authName.col) this.expanded.add(authName.col.colURI);\n for (const tc of authName.taxonConceptURIs) this.expanded.add(tc);\n }\n\n this.pushName(name);\n\n /** Map */\n const newSynonyms = new Map();\n (await Promise.all(\n treatmentPromises.map((treat) =>\n treat.details.then((d): [Treatment, TreatmentDetails] => {\n return [treat, d];\n })\n ),\n )).map(([treat, d]) => {\n d.treats.aug.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.def.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.dpr.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n d.treats.treattn.difference(this.expanded).forEach((s) =>\n newSynonyms.set(s, treat)\n );\n });\n\n if (unathorizedCol) {\n await this.findColSynonyms(unathorizedCol.colURI, name);\n }\n\n await Promise.allSettled(\n [\n ...authorizedNames\n .filter((n) => n.col)\n .map((n) => this.findColSynonyms(n.col!.colURI, name)),\n ...[...newSynonyms].map(([n, treatment]) =>\n this.getName(n, { searchTerm: false, parent: name, treatment })\n ),\n ],\n );\n }\n\n /** @internal */\n private async findColSynonyms(\n colUri: string,\n parent: Name,\n ): Promise {\n const query = `\nPREFIX dwc: \nSELECT DISTINCT ?current ?current_status (GROUP_CONCAT(DISTINCT ?dpr; separator=\"|\") AS ?dprs) WHERE {\n BIND(<${colUri}> AS ?col)\n {\n ?col dwc:acceptedName ?current .\n ?dpr dwc:acceptedName ?current .\n OPTIONAL { ?current dwc:taxonomicStatus ?current_status . }\n } UNION {\n ?col dwc:taxonomicStatus ?current_status .\n OPTIONAL { ?dpr dwc:acceptedName ?col . }\n FILTER NOT EXISTS { ?col dwc:acceptedName ?_ . }\n BIND(?col AS ?current)\n }\n}\nGROUP BY ?current ?current_status`;\n\n if (this.acceptedCol.has(colUri)) {\n // we have already found this group of synonyms\n return [];\n }\n\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n this.fetchOptions,\n `AcceptedCol ${colUri}`,\n );\n\n const promises: Promise[] = [];\n\n for (const b of json.results.bindings) {\n for (const dpr of b.dprs!.value.split(\"|\")) {\n if (dpr) {\n if (!this.acceptedCol.has(b.current!.value)) {\n this.acceptedCol.set(b.current!.value, b.current!.value);\n promises.push(\n this.getName(b.current!.value, {\n searchTerm: false,\n parent,\n }),\n );\n }\n\n this.acceptedCol.set(dpr, b.current!.value);\n if (!this.ignoreDeprecatedCoL) {\n promises.push(\n this.getName(dpr, { searchTerm: false, parent }),\n );\n }\n }\n }\n }\n\n if (json.results.bindings.length === 0) {\n // the provided colUri is not in CoL\n // promises === []\n if (!this.acceptedCol.has(colUri)) {\n this.acceptedCol.set(colUri, \"INVALID COL\");\n }\n return Promise.all(promises);\n }\n\n if (!this.acceptedCol.has(colUri)) this.acceptedCol.set(colUri, colUri);\n return Promise.all(promises);\n }\n\n /** @internal */\n private async getVernacular(uri: string): Promise {\n const result: vernacularNames = new Map();\n const query =\n `SELECT DISTINCT ?n WHERE { <${uri}> ?n . }`;\n const bindings = (await this.sparqlEndpoint.getSparqlResultSet(\n query,\n this.fetchOptions,\n `Vernacular ${uri}`,\n )).results.bindings;\n for (const b of bindings) {\n if (b.n?.value) {\n if (b.n[\"xml:lang\"]) {\n if (result.has(b.n[\"xml:lang\"])) {\n result.get(b.n[\"xml:lang\"])!.push(b.n.value);\n } else result.set(b.n[\"xml:lang\"], [b.n.value]);\n } else {\n if (result.has(\"??\")) result.get(\"??\")!.push(b.n.value);\n else result.set(\"??\", [b.n.value]);\n }\n }\n }\n return result;\n }\n\n /** @internal\n *\n * the supplied \"urls\" must be of the form \"URL>DATE\"\n */\n private makeTreatmentSet(urls?: string[]): Set {\n if (!urls) return new Set();\n return new Set(\n urls.filter((url) => !!url).map((url_d) => {\n const [url, date] = url_d.split(\">\");\n if (!this.treatments.has(url)) {\n const details = this.getTreatmentDetails(url);\n this.treatments.set(url, {\n url,\n date: date ? parseInt(date, 10) : undefined,\n details,\n });\n }\n return this.treatments.get(url) as Treatment;\n }),\n );\n }\n\n /** @internal */\n private async getTreatmentDetails(\n treatmentUri: string,\n ): Promise {\n const query = `\nPREFIX dc: \nPREFIX dwc: \nPREFIX dwcFP: \nPREFIX cito: \nPREFIX trt: \nSELECT DISTINCT\n ?date ?title ?mc\n (group_concat(DISTINCT ?catalogNumber;separator=\" / \") as ?catalogNumbers)\n (group_concat(DISTINCT ?collectionCode;separator=\" / \") as ?collectionCodes)\n (group_concat(DISTINCT ?typeStatus;separator=\" / \") as ?typeStatuss)\n (group_concat(DISTINCT ?countryCode;separator=\" / \") as ?countryCodes)\n (group_concat(DISTINCT ?stateProvince;separator=\" / \") as ?stateProvinces)\n (group_concat(DISTINCT ?municipality;separator=\" / \") as ?municipalitys)\n (group_concat(DISTINCT ?county;separator=\" / \") as ?countys)\n (group_concat(DISTINCT ?locality;separator=\" / \") as ?localitys)\n (group_concat(DISTINCT ?verbatimLocality;separator=\" / \") as ?verbatimLocalitys)\n (group_concat(DISTINCT ?recordedBy;separator=\" / \") as ?recordedBys)\n (group_concat(DISTINCT ?eventDate;separator=\" / \") as ?eventDates)\n (group_concat(DISTINCT ?samplingProtocol;separator=\" / \") as ?samplingProtocols)\n (group_concat(DISTINCT ?decimalLatitude;separator=\" / \") as ?decimalLatitudes)\n (group_concat(DISTINCT ?decimalLongitude;separator=\" / \") as ?decimalLongitudes)\n (group_concat(DISTINCT ?verbatimElevation;separator=\" / \") as ?verbatimElevations)\n (group_concat(DISTINCT ?gbifOccurrenceId;separator=\" / \") as ?gbifOccurrenceIds)\n (group_concat(DISTINCT ?gbifSpecimenId;separator=\" / \") as ?gbifSpecimenIds)\n (group_concat(DISTINCT ?creator;separator=\"; \") as ?creators)\n (group_concat(DISTINCT ?httpUri;separator=\"|\") as ?httpUris)\n (group_concat(DISTINCT ?aug;separator=\"|\") as ?augs)\n (group_concat(DISTINCT ?def;separator=\"|\") as ?defs)\n (group_concat(DISTINCT ?dpr;separator=\"|\") as ?dprs)\n (group_concat(DISTINCT ?cite;separator=\"|\") as ?cites)\n (group_concat(DISTINCT ?trttn;separator=\"|\") as ?trttns)\n (group_concat(DISTINCT ?citetn;separator=\"|\") as ?citetns)\nWHERE {\n BIND (<${treatmentUri}> as ?treatment)\n ?treatment dc:creator ?creator .\n OPTIONAL { ?treatment dc:title ?title }\n OPTIONAL { ?treatment trt:augmentsTaxonConcept ?aug . }\n OPTIONAL { ?treatment trt:definesTaxonConcept ?def . }\n OPTIONAL { ?treatment trt:deprecates ?dpr . }\n OPTIONAL { ?treatment cito:cites ?cite . ?cite a dwcFP:TaxonConcept . }\n OPTIONAL { ?treatment trt:treatsTaxonName ?trttn . }\n OPTIONAL { ?treatment trt:citesTaxonName ?citetn . }\n OPTIONAL {\n ?treatment dwc:basisOfRecord ?mc .\n ?mc dwc:catalogNumber ?catalogNumber .\n OPTIONAL { ?mc dwc:collectionCode ?collectionCode . }\n OPTIONAL { ?mc dwc:typeStatus ?typeStatus . }\n OPTIONAL { ?mc dwc:countryCode ?countryCode . }\n OPTIONAL { ?mc dwc:stateProvince ?stateProvince . }\n OPTIONAL { ?mc dwc:municipality ?municipality . }\n OPTIONAL { ?mc dwc:county ?county . }\n OPTIONAL { ?mc dwc:locality ?locality . }\n OPTIONAL { ?mc dwc:verbatimLocality ?verbatimLocality . }\n OPTIONAL { ?mc dwc:recordedBy ?recordedBy . }\n OPTIONAL { ?mc dwc:eventDate ?eventDate . }\n OPTIONAL { ?mc dwc:samplingProtocol ?samplingProtocol . }\n OPTIONAL { ?mc dwc:decimalLatitude ?decimalLatitude . }\n OPTIONAL { ?mc dwc:decimalLongitude ?decimalLongitude . }\n OPTIONAL { ?mc dwc:verbatimElevation ?verbatimElevation . }\n OPTIONAL { ?mc trt:gbifOccurrenceId ?gbifOccurrenceId . }\n OPTIONAL { ?mc trt:gbifSpecimenId ?gbifSpecimenId . }\n OPTIONAL { ?mc trt:httpUri ?httpUri . }\n }\n}\nGROUP BY ?date ?title ?mc`;\n if (this.controller.signal.aborted) {\n return {\n materialCitations: [],\n figureCitations: [],\n treats: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n citetc: new Set(),\n treattn: new Set(),\n citetn: new Set(),\n },\n };\n }\n try {\n const json = await this.sparqlEndpoint.getSparqlResultSet(\n query,\n this.fetchOptions,\n `TreatmentDetails ${treatmentUri}`,\n );\n const materialCitations: MaterialCitation[] = json.results.bindings\n .filter((t) => t.mc && t.catalogNumbers?.value)\n .map((t) => {\n const httpUri = t.httpUris?.value?.split(\"|\");\n return {\n \"catalogNumber\": t.catalogNumbers!.value,\n \"collectionCode\": t.collectionCodes?.value || undefined,\n \"typeStatus\": t.typeStatuss?.value || undefined,\n \"countryCode\": t.countryCodes?.value || undefined,\n \"stateProvince\": t.stateProvinces?.value || undefined,\n \"municipality\": t.municipalitys?.value || undefined,\n \"county\": t.countys?.value || undefined,\n \"locality\": t.localitys?.value || undefined,\n \"verbatimLocality\": t.verbatimLocalitys?.value || undefined,\n \"recordedBy\": t.recordedBys?.value || undefined,\n \"eventDate\": t.eventDates?.value || undefined,\n \"samplingProtocol\": t.samplingProtocols?.value || undefined,\n \"decimalLatitude\": t.decimalLatitudes?.value || undefined,\n \"decimalLongitude\": t.decimalLongitudes?.value || undefined,\n \"verbatimElevation\": t.verbatimElevations?.value || undefined,\n \"gbifOccurrenceId\": t.gbifOccurrenceIds?.value || undefined,\n \"gbifSpecimenId\": t.gbifSpecimenIds?.value || undefined,\n httpUri: httpUri?.length ? httpUri : undefined,\n };\n });\n const figureQuery = `\nPREFIX cito: \nPREFIX fabio: \nPREFIX dc: \nSELECT DISTINCT ?url ?description WHERE {\n <${treatmentUri}> cito:cites ?cites .\n ?cites a fabio:Figure ;\n fabio:hasRepresentation ?url .\n OPTIONAL { ?cites dc:description ?description . }\n} `;\n const figures = (await this.sparqlEndpoint.getSparqlResultSet(\n figureQuery,\n this.fetchOptions,\n `TreatmentDetails/Figures ${treatmentUri}`,\n )).results.bindings;\n const figureCitations = figures.filter((f) => f.url?.value).map(\n (f) => {\n return { url: f.url!.value, description: f.description?.value };\n },\n );\n return {\n creators: json.results.bindings[0]?.creators?.value,\n title: json.results.bindings[0]?.title?.value,\n materialCitations,\n figureCitations,\n treats: {\n def: new Set(\n json.results.bindings[0]?.defs?.value\n ? json.results.bindings[0].defs.value.split(\"|\")\n : undefined,\n ),\n aug: new Set(\n json.results.bindings[0]?.augs?.value\n ? json.results.bindings[0].augs.value.split(\"|\")\n : undefined,\n ),\n dpr: new Set(\n json.results.bindings[0]?.dprs?.value\n ? json.results.bindings[0].dprs.value.split(\"|\")\n : undefined,\n ),\n citetc: new Set(\n json.results.bindings[0]?.cites?.value\n ? json.results.bindings[0].cites.value.split(\"|\")\n : undefined,\n ),\n treattn: new Set(\n json.results.bindings[0]?.trttns?.value\n ? json.results.bindings[0].trttns.value.split(\"|\")\n : undefined,\n ),\n citetn: new Set(\n json.results.bindings[0]?.citetns?.value\n ? json.results.bindings[0].citetns.value.split(\"|\")\n : undefined,\n ),\n },\n };\n } catch (error) {\n console.warn(\"SPARQL Error: \" + error);\n return {\n materialCitations: [],\n figureCitations: [],\n treats: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n citetc: new Set(),\n treattn: new Set(),\n citetn: new Set(),\n },\n };\n }\n }\n\n /** Allows iterating over the synonyms while they are found */\n [Symbol.asyncIterator](): AsyncIterator {\n let returnedSoFar = 0;\n return {\n next: () =>\n new Promise>(\n (resolve, reject) => {\n const callback = () => {\n if (this.controller.signal.aborted) {\n reject(new Error(\"SynyonymGroup has been aborted\"));\n } else if (returnedSoFar < this.names.length) {\n resolve({ value: this.names[returnedSoFar++] });\n } else if (this.isFinished) {\n resolve({ done: true, value: true });\n } else {\n const listener = () => {\n this.monitor.removeEventListener(\"updated\", listener);\n callback();\n };\n this.monitor.addEventListener(\"updated\", listener);\n }\n };\n callback();\n },\n ),\n };\n }\n}\n\n// TODO: CoL taxa without authority -- associate them with the Name directly\n// eg. 5KTTT is \"Quercus robur subsp. robur\" w/o authority\n\n/** The central object.\n *\n * Each `Name` exists because of a taxon-name, taxon-concept or col-taxon in the data.\n * Each `Name` is uniquely determined by its human-readable latin name (for taxa ranking below genus, this is a multi-part name \u2014 binomial or trinomial) and kingdom.\n */\nexport type Name = {\n /** taxonomic kingdom\n *\n * may be empty for some CoL-taxa with missing ancestors */\n kingdom: string;\n /** Human-readable name */\n displayName: string;\n /** taxonomic rank */\n rank: string;\n\n /** vernacular names */\n vernacularNames: Promise;\n\n // /** Contains the family tree / upper taxons accorindg to CoL / treatmentbank.\n // * //TODO */\n // trees: Promise<{\n // col?: Tree;\n // tb?: Tree;\n // }>;\n\n /** The URI of the respective `dwcFP:TaxonName` if it exists */\n taxonNameURI?: string;\n\n /** Catalogue of Life-Data */\n col?: {\n /** The URI of the respective CoL-taxon if it exists\n *\n * Note that this is only for CoL-taxa which do not have an authority.\n */\n colURI: string;\n /** The URI of the corresponding accepted CoL-taxon if it exists.\n *\n * The same as URI if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedURI: string;\n };\n\n /** All `AuthorizedName`s with this name */\n authorizedNames: AuthorizedName[];\n\n /** How this name was found */\n justification: Justification;\n\n /** treatments directly associated with .taxonNameUri */\n treatments: {\n treats: Set;\n cite: Set;\n };\n};\n\n/**\n * A map from language tags (IETF) to an array of vernacular names.\n */\nexport type vernacularNames = Map;\n\n/** Why a given Name was found (ther migth be other possible justifications) */\nexport type Justification = {\n searchTerm: true;\n /** indicates that this is a subTaxon of the parent */\n subTaxon: boolean;\n} | {\n searchTerm: false;\n parent: Name;\n /** if missing, indicates synonymy according to CoL or subTaxon */\n treatment?: Treatment;\n};\n\n/**\n * Corresponds to a taxon-concept or a CoL-Taxon\n */\nexport type AuthorizedName = {\n // TODO: neccesary?\n /** this may not be neccesary, as `AuthorizedName`s should only appear within a `Name` */\n // name: Name;\n /** Human-readable name */\n displayName: string;\n /** Human-readable authority */\n authority: string;\n /**\n * Human-readable authorities as given in the Data.\n */\n authorities: string[];\n\n /** The URIs of the respective `dwcFP:TaxonConcept` if it exists */\n taxonConceptURIs: string[];\n\n /** Catalogue of Life-Data */\n col?: {\n /** The URI of the respective CoL-taxon if it exists */\n colURI: string;\n /** The URI of the corresponding accepted CoL-taxon if it exists.\n *\n * The same as URI if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedURI: string;\n };\n\n // TODO: sensible?\n // /** these are CoL-taxa linked in the rdf, which differ lexically */\n // seeAlsoCol: string[];\n\n /** treatments directly associated with .taxonConceptURI */\n treatments: {\n def: Set;\n aug: Set;\n dpr: Set;\n cite: Set;\n };\n};\n\n/** A plazi-treatment */\nexport type Treatment = {\n url: string;\n date?: number;\n\n /** Details are behind a promise becuase they are loaded with a separate query. */\n details: Promise;\n};\n\n/** Details of a treatment */\nexport type TreatmentDetails = {\n materialCitations: MaterialCitation[];\n figureCitations: FigureCitation[];\n creators?: string;\n title?: string;\n treats: {\n def: Set;\n aug: Set;\n dpr: Set;\n citetc: Set;\n treattn: Set;\n citetn: Set;\n };\n};\n\n/** A cited material */\nexport type MaterialCitation = {\n \"catalogNumber\": string;\n \"collectionCode\"?: string;\n \"typeStatus\"?: string;\n \"countryCode\"?: string;\n \"stateProvince\"?: string;\n \"municipality\"?: string;\n \"county\"?: string;\n \"locality\"?: string;\n \"verbatimLocality\"?: string;\n \"recordedBy\"?: string;\n \"eventDate\"?: string;\n \"samplingProtocol\"?: string;\n \"decimalLatitude\"?: string;\n \"decimalLongitude\"?: string;\n \"verbatimElevation\"?: string;\n \"gbifOccurrenceId\"?: string;\n \"gbifSpecimenId\"?: string;\n \"httpUri\"?: string[];\n};\n\n/** A cited figure */\nexport type FigureCitation = {\n url: string;\n description?: string;\n};\n", "// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.\n// This module is browser compatible.\n\n/**\n * Returns all distinct elements in the given array, preserving order by first\n * occurrence.\n *\n * @typeParam T The type of the elements in the input array.\n *\n * @param array The array to filter for distinct elements.\n *\n * @returns An array of distinct elements in the input array.\n *\n * @example Basic usage\n * ```ts\n * import { distinct } from \"@std/collections/distinct\";\n * import { assertEquals } from \"@std/assert\";\n *\n * const numbers = [3, 2, 5, 2, 5];\n * const distinctNumbers = distinct(numbers);\n *\n * assertEquals(distinctNumbers, [3, 2, 5]);\n * ```\n */\nexport function distinct(array: Iterable): T[] {\n const set = new Set(array);\n\n return Array.from(set);\n}\n", "/// \nimport {\n type AuthorizedName,\n type Name,\n SparqlEndpoint,\n SynonymGroup,\n type Treatment,\n} from \"../mod.ts\";\nimport { distinct } from \"jsr:@std/collections/distinct\";\n\nconst params = new URLSearchParams(document.location.search);\nconst HIDE_COL_ONLY_SYNONYMS = !params.has(\"show_col\");\nconst START_WITH_SUBTAXA = params.has(\"subtaxa\");\nconst SORT_TREATMENTS_BY_TYPE = params.has(\"sort_treatments_by_type\");\nconst ENDPOINT_URL = params.get(\"server\") ||\n \"https://treatment.ld.plazi.org/sparql\";\nconst NAME = params.get(\"q\") ||\n \"https://www.catalogueoflife.org/data/taxon/3WD9M\";\n\nconst root = document.getElementById(\"root\") as HTMLDivElement;\n\nenum SynoStatus {\n Def = \"def\",\n Aug = \"aug\",\n Dpr = \"dpr\",\n Cite = \"cite\",\n}\n\nconst icons = {\n def:\n ``,\n aug:\n ``,\n dpr:\n ``,\n cite:\n ``,\n unknown:\n ``,\n\n col_aug:\n ``,\n col_dpr:\n ``,\n\n link:\n ``,\n\n expand:\n ``,\n collapse:\n ``,\n\n east:\n ``,\n west:\n ``,\n empty: ``,\n};\n\nconst indicator = document.createElement(\"div\");\nroot.insertAdjacentElement(\"beforebegin\", indicator);\nindicator.append(`Finding Synonyms for ${NAME} `);\nconst progress = document.createElement(\"progress\");\nindicator.append(progress);\n\nconst timeStart = performance.now();\n\nconst sparqlEndpoint = new SparqlEndpoint(ENDPOINT_URL);\nconst synoGroup = new SynonymGroup(\n sparqlEndpoint,\n NAME,\n HIDE_COL_ONLY_SYNONYMS,\n START_WITH_SUBTAXA,\n);\n\nclass SynoTreatment extends HTMLElement {\n constructor(trt: Treatment, status: SynoStatus) {\n super();\n\n this.innerHTML = icons[status] ?? icons.unknown;\n\n const button = document.createElement(\"button\");\n button.classList.add(\"icon\", \"button\");\n button.innerHTML = icons.expand;\n button.addEventListener(\"click\", () => {\n if (this.classList.toggle(\"expanded\")) {\n button.innerHTML = icons.collapse;\n } else {\n button.innerHTML = icons.expand;\n }\n });\n\n const date = document.createElement(\"span\");\n if (trt.date) date.innerText = \"\" + trt.date;\n else {\n date.classList.add(\"missing\");\n date.innerText = \"No Date\";\n }\n this.append(date);\n\n const spinner = document.createElement(\"progress\");\n this.append(\": \", spinner);\n\n const url = document.createElement(\"a\");\n url.classList.add(\"treatment\", \"uri\");\n url.href = trt.url;\n url.target = \"_blank\";\n url.innerText = trt.url.replace(\"http://treatment.plazi.org/id/\", \"\");\n url.innerHTML += icons.link;\n this.append(\" \", url);\n\n this.append(button);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\", \"details\");\n this.append(names);\n\n trt.details.then((details) => {\n const creators = document.createElement(\"span\");\n const title = document.createElement(\"i\");\n spinner.replaceWith(creators, \" \", title);\n\n if (details.creators) creators.innerText = details.creators;\n else {\n creators.classList.add(\"missing\");\n creators.innerText = \"No Authors\";\n }\n\n if (details.title) title.innerText = \"\u201C\" + details.title + \"\u201D\";\n else {\n title.classList.add(\"missing\");\n title.innerText = \"No Title\";\n }\n\n if (details.treats.def.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.east;\n line.innerHTML = icons.east;\n line.innerHTML += icons.def;\n if (status === SynoStatus.Def || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.def.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.aug.size > 0 || details.treats.treattn.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.east;\n line.innerHTML = icons.east;\n line.innerHTML += icons.aug;\n if (status === SynoStatus.Aug || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.aug.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n details.treats.treattn.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-name.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.dpr.size > 0) {\n const line = document.createElement(\"div\");\n // line.innerHTML = status === SynoStatus.Cite ? icons.line : icons.west;\n line.innerHTML = icons.west;\n line.innerHTML += icons.dpr;\n if (status === SynoStatus.Dpr || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n }\n names.append(line);\n\n details.treats.dpr.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.treats.citetc.size > 0 || details.treats.citetn.size > 0) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.empty + icons.cite;\n // if (status === SynoStatus.Dpr || status === SynoStatus.Cite) {\n line.classList.add(\"hidden\");\n // }\n names.append(line);\n\n details.treats.citetc.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-concept.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n details.treats.citetn.forEach((n) => {\n const url = document.createElement(\"a\");\n url.classList.add(\"taxon\", \"uri\");\n const short = n.replace(\"http://taxon-name.plazi.org/id/\", \"\");\n url.innerText = short;\n url.href = \"#\" + short;\n url.title = \"show name\";\n line.append(\" \", url);\n synoGroup.findName(n).then((nn) => {\n url.classList.remove(\"uri\");\n if ((nn as AuthorizedName).authority) {\n url.innerText = nn.displayName + \" \" +\n (nn as AuthorizedName).authority;\n } else url.innerText = nn.displayName;\n }, () => {\n url.removeAttribute(\"href\");\n });\n });\n }\n if (details.figureCitations.length > 0) {\n const line = document.createElement(\"div\");\n line.classList.add(\"figures\", \"hidden\");\n names.append(line);\n for (const figure of details.figureCitations) {\n const el = document.createElement(\"figure\");\n line.append(el);\n const img = document.createElement(\"img\");\n img.src = figure.url;\n img.loading = \"lazy\";\n img.alt = figure.description ?? \"Cited Figure without caption\";\n el.append(img);\n const caption = document.createElement(\"figcaption\");\n caption.innerText = figure.description ?? \"\";\n el.append(caption);\n }\n }\n if (details.materialCitations.length > 0) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.empty + icons.cite +\n \" Material Citations:
-\";\n line.classList.add(\"hidden\");\n names.append(line);\n line.innerText += details.materialCitations.map((c) =>\n JSON.stringify(c)\n .replaceAll(\"{\", \"\")\n .replaceAll(\"}\", \"\")\n .replaceAll('\":', \": \")\n .replaceAll(\",\", \", \")\n .replaceAll('\"', \"\")\n ).join(\"\\n -\");\n }\n });\n }\n}\ncustomElements.define(\"syno-treatment\", SynoTreatment);\n\nclass SynoName extends HTMLElement {\n constructor(name: Name) {\n super();\n\n const title = document.createElement(\"h2\");\n const name_title = document.createElement(\"i\");\n name_title.innerText = name.displayName;\n title.append(name_title);\n this.append(title);\n\n const rank_badge = document.createElement(\"span\");\n rank_badge.classList.add(\"rank\");\n rank_badge.innerText = name.rank;\n const kingdom_badge = document.createElement(\"span\");\n kingdom_badge.classList.add(\"rank\");\n kingdom_badge.innerText = name.kingdom || \"Missing Kingdom\";\n title.append(\" \", kingdom_badge, \" \", rank_badge);\n\n if (name.taxonNameURI) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n const short = name.taxonNameURI.replace(\n \"http://taxon-name.plazi.org/id/\",\n \"\",\n );\n name_uri.innerText = short;\n name_uri.id = short;\n name_uri.href = name.taxonNameURI;\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n title.append(\" \", name_uri);\n }\n\n const vernacular = document.createElement(\"div\");\n vernacular.classList.add(\"vernacular\");\n name.vernacularNames.then((names) => {\n if (names.size > 0) {\n vernacular.innerText = \"\u201C\" +\n distinct([...names.values()].flat()).join(\"\u201D, \u201C\") + \"\u201D\";\n }\n });\n this.append(vernacular);\n\n const treatments = document.createElement(\"ul\");\n this.append(treatments);\n\n if (name.col) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.col.colURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.id = id;\n col_uri.href = name.col.colURI;\n col_uri.target = \"_blank\";\n col_uri.innerHTML += icons.link;\n title.append(\" \", col_uri);\n\n const li = document.createElement(\"div\");\n li.classList.add(\"treatmentline\");\n li.innerHTML = name.col.acceptedURI !== name.col.colURI\n ? icons.col_dpr\n : icons.col_aug;\n treatments.append(li);\n\n const creators = document.createElement(\"span\");\n creators.innerText = \"Catalogue of Life\";\n li.append(creators);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\");\n li.append(names);\n\n if (name.col.acceptedURI !== name.col.colURI) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.east + icons.col_aug;\n names.append(line);\n\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.col.acceptedURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.href = `#${id}`;\n col_uri.title = \"show name\";\n line.append(col_uri);\n synoGroup.findName(name.col.acceptedURI).then((n) => {\n if ((n as AuthorizedName).authority) {\n col_uri.innerText = n.displayName + \" \" +\n (n as AuthorizedName).authority;\n } else col_uri.innerText = n.displayName;\n }, () => {\n col_uri.removeAttribute(\"href\");\n });\n }\n }\n if (name.treatments.treats.size > 0 || name.treatments.cite.size > 0) {\n for (const trt of name.treatments.treats) {\n const li = new SynoTreatment(trt, SynoStatus.Aug);\n treatments.append(li);\n }\n for (const trt of name.treatments.cite) {\n const li = new SynoTreatment(trt, SynoStatus.Cite);\n treatments.append(li);\n }\n }\n\n const justification = document.createElement(\"abbr\");\n justification.classList.add(\"justification\");\n justification.innerText = \"...?\";\n justify(name).then((just) => justification.title = `This ${just}`);\n title.append(\" \", justification);\n\n for (const authorizedName of name.authorizedNames) {\n const authName = document.createElement(\"h3\");\n const name_title = document.createElement(\"i\");\n name_title.innerText = authorizedName.displayName;\n name_title.classList.add(\"gray\");\n authName.append(name_title);\n authName.append(\" \", authorizedName.authority);\n this.append(authName);\n\n const treatments = document.createElement(\"ul\");\n this.append(treatments);\n\n if (authorizedName.taxonConceptURIs[0]) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n // TODO handle other URIs\n const short = authorizedName.taxonConceptURIs[0].replace(\n \"http://taxon-concept.plazi.org/id/\",\n \"\",\n );\n name_uri.innerText = short;\n name_uri.id = short;\n name_uri.href = authorizedName.taxonConceptURIs[0];\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n authName.append(\" \", name_uri);\n }\n if (authorizedName.col) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.col.colURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.id = id;\n col_uri.href = authorizedName.col.colURI;\n col_uri.target = \"_blank\";\n col_uri.innerHTML += icons.link;\n authName.append(\" \", col_uri);\n\n const li = document.createElement(\"div\");\n li.classList.add(\"treatmentline\");\n li.innerHTML =\n authorizedName.col.acceptedURI !== authorizedName.col.colURI\n ? icons.col_dpr\n : icons.col_aug;\n treatments.append(li);\n\n const creators = document.createElement(\"span\");\n creators.innerText = \"Catalogue of Life\";\n li.append(creators);\n\n const names = document.createElement(\"div\");\n names.classList.add(\"indent\");\n li.append(names);\n\n if (authorizedName.col.acceptedURI !== authorizedName.col.colURI) {\n const line = document.createElement(\"div\");\n line.innerHTML = icons.east + icons.col_aug;\n names.append(line);\n\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.col.acceptedURI.replace(\n \"https://www.catalogueoflife.org/data/taxon/\",\n \"\",\n );\n col_uri.innerText = id;\n col_uri.href = `#${id}`;\n col_uri.title = \"show name\";\n line.append(\" \", col_uri);\n synoGroup.findName(authorizedName.col.acceptedURI).then((n) => {\n col_uri.classList.remove(\"uri\");\n if ((n as AuthorizedName).authority) {\n col_uri.innerText = n.displayName + \" \" +\n (n as AuthorizedName).authority;\n } else col_uri.innerText = n.displayName;\n }, () => {\n col_uri.removeAttribute(\"href\");\n });\n }\n }\n\n const treatments_array: { trt: Treatment; status: SynoStatus }[] = [];\n\n for (const trt of authorizedName.treatments.def) {\n treatments_array.push({ trt, status: SynoStatus.Def });\n }\n for (const trt of authorizedName.treatments.aug) {\n treatments_array.push({ trt, status: SynoStatus.Aug });\n }\n for (const trt of authorizedName.treatments.dpr) {\n treatments_array.push({ trt, status: SynoStatus.Dpr });\n }\n for (const trt of authorizedName.treatments.cite) {\n treatments_array.push({ trt, status: SynoStatus.Cite });\n }\n\n if (!SORT_TREATMENTS_BY_TYPE) {\n treatments_array.sort((a, b) => {\n if (a.trt.date && b.trt.date) return a.trt.date - b.trt.date;\n if (a.trt.date) return 1;\n if (b.trt.date) return -1;\n return 0;\n });\n }\n\n for (const { trt, status } of treatments_array) {\n const li = new SynoTreatment(trt, status);\n treatments.append(li);\n }\n }\n }\n}\ncustomElements.define(\"syno-name\", SynoName);\n\nasync function justify(name: Name): Promise {\n if (name.justification.searchTerm) {\n if (name.justification.subTaxon) {\n return \"is a sub-taxon of the search term.\";\n } else return \"is the search term.\";\n } else if (name.justification.treatment) {\n const details = await name.justification.treatment.details;\n const parent = await justify(name.justification.parent);\n return `is, according to ${details.creators} ${name.justification.treatment.date},\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n // return `is, according to ${details.creators} ${details.date} \u201C${details.title||\"No Title\"}\u201D ${name.justification.treatment.url},\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n } else {\n const parent = await justify(name.justification.parent);\n return `is, according to the Catalogue of Life,\\n a synonym of ${name.justification.parent.displayName} which ${parent}`;\n }\n}\n\nfor await (const name of synoGroup) {\n const element = new SynoName(name);\n root.append(element);\n}\n\nconst timeEnd = performance.now();\n\nindicator.innerHTML = \"\";\nindicator.innerText =\n `Found ${synoGroup.names.length} names with ${synoGroup.treatments.size} treatments. This took ${\n (timeEnd - timeStart) / 1000\n } seconds.`;\nif (synoGroup.names.length === 0) root.append(\":[\");\n"], + "mappings": "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", "names": ["sleep", "ms", "resolve", "SparqlEndpoint", "sparqlEnpointUri", "query", "fetchOptions", "_reason", "retryCount", "sendRequest", "response", "error", "wait", "preamble", "postamble", "getNameFromCol", "colUri", "getNameFromTC", "tcUri", "getNameFromTN", "tnUri", "unifyAuthorithy", "a", "b", "as", "bs", "yearA", "yearB", "etalA", "etalB", "result", "i", "r", "unifySingleName", "j", "prefixA", "prefixB", "longA", "longB", "indexA", "indexB", "index", "isEquivalent", "normA", "normB", "SynonymGroup", "name", "sparqlEndpoint", "taxonName", "ignoreDeprecatedCoL", "startWithSubTaxa", "e", "n", "uri", "an", "resolve", "reject", "justification", "json", "getNameFromCol", "getNameFromTC", "getNameFromTN", "url", "query", "names", "genus", "species", "infrasp", "treatmentPromises", "abbreviateRank", "rank", "displayName", "unathorizedCol", "authorizedNames", "taxonNameURI", "expandedHere", "t", "colURI", "def", "aug", "dpr", "cite", "prevName", "unifyAuthorithy", "best", "treats", "authName", "tc", "newSynonyms", "treat", "d", "s", "treatment", "colUri", "parent", "promises", "b", "result", "bindings", "urls", "url_d", "date", "details", "treatmentUri", "materialCitations", "httpUri", "figureQuery", "figureCitations", "f", "error", "returnedSoFar", "callback", "listener", "distinct", "array", "set", "params", "HIDE_COL_ONLY_SYNONYMS", "START_WITH_SUBTAXA", "SORT_TREATMENTS_BY_TYPE", "ENDPOINT_URL", "NAME", "root", "icons", "indicator", "root", "NAME", "progress", "timeStart", "sparqlEndpoint", "SparqlEndpoint", "ENDPOINT_URL", "synoGroup", "SynonymGroup", "HIDE_COL_ONLY_SYNONYMS", "START_WITH_SUBTAXA", "SynoTreatment", "trt", "status", "button", "date", "spinner", "url", "names", "details", "creators", "title", "line", "n", "short", "nn", "figure", "el", "img", "caption", "c", "SynoName", "name", "name_title", "rank_badge", "kingdom_badge", "name_uri", "vernacular", "distinct", "treatments", "col_uri", "id", "li", "justification", "justify", "just", "authorizedName", "authName", "treatments_array", "SORT_TREATMENTS_BY_TYPE", "a", "b", "parent", "element", "timeEnd"] }