From ba768ca65c36520041cf41e2d7b9b2072834faee Mon Sep 17 00:00:00 2001 From: nleanba <25827850+nleanba@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:35:10 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20plazi/sy?= =?UTF-8?q?nolib@57a06848d467f9ab065c7568acde4ec1fb99d463=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.css | 19 +-- index.html | 6 +- index.js | 374 ++++++++++++++++++++++++++------------------------- index.js.map | 6 +- index.ts | 5 +- 5 files changed, 204 insertions(+), 206 deletions(-) diff --git a/index.css b/index.css index 81e8e5b..6fedae9 100644 --- a/index.css +++ b/index.css @@ -96,13 +96,13 @@ syno-treatment, transition: all 200ms; clear: both; - &>svg { + & > svg { height: 1rem; vertical-align: sub; margin: 0 0.2rem 0 -1.2rem; } - >.icon.button { + > .icon.button { float: right; } @@ -114,10 +114,6 @@ syno-treatment, max-height: 0; overflow: hidden; transition: all 200ms; - - & img { - display: none; - } } &.expanded { @@ -131,17 +127,13 @@ syno-treatment, .hidden { max-height: 200rem; overflow: auto; - - & img { - display: unset; - } } } } .figures { display: grid; - grid-template-columns: repeat( auto-fill, minmax(12rem, 1fr) ); + grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); grid-template-rows: masonry; margin: 0.2rem 0 0.2rem 2.2rem; gap: 1rem; @@ -155,7 +147,6 @@ syno-treatment, } } - .icon.button { border-radius: 1rem; border: none; @@ -166,7 +157,7 @@ syno-treatment, padding: 0; position: relative; - &>svg { + & > svg { height: 1rem; margin: 0; } @@ -204,4 +195,4 @@ syno-treatment, .gray { color: #666666; -} \ No newline at end of file +} diff --git a/index.html b/index.html index c65e1c5..0643f32 100644 --- a/index.html +++ b/index.html @@ -29,9 +29,9 @@

SynoLib


- Expand a treatment with the button on the right to show all cited taxa, figures and materials. Click on a taxon identifier - beneath a treatment to scroll to that name — if it is (already) in the - list. + Expand a treatment with the button on the right to show all cited taxa, + figures and materials. Click on a taxon identifier beneath a treatment to + scroll to that name — if it is (already) in the list.

diff --git a/index.js b/index.js index 1e44063..f641a17 100644 --- a/index.js +++ b/index.js @@ -1,28 +1,31 @@ -async function U(h){return await new Promise(i=>{setTimeout(i,h)})}var A=class{constructor(t){this.sparqlEnpointUri=t}async getSparqlResultSet(t,i={},s=""){ -i.headers=i.headers||{},i.headers.Accept="application/sparql-results+json";let l=0,c=async()=>{try{let d=await fetch(this. -sparqlEnpointUri+"?query="+encodeURIComponent(t),i);if(!d.ok)throw new Error("Response not ok. Status "+d.status);return await d. -json()}catch(d){if(i.signal?.aborted)throw d;if(l<10){let u=50*(1<{setTimeout(r,T)})}var O=class{constructor(t){this.sparqlEnpointUri=t}async getSparqlResultSet(t,r={},s=""){ +r.headers=r.headers||{},r.headers.Accept="application/sparql-results+json";let u=0,o=async()=>{try{let l=await fetch(this. +sparqlEnpointUri+"?query="+encodeURIComponent(t),r);if(!l.ok)throw new Error("Response not ok. Status "+l.status);return await l. +json()}catch(l){if(r.signal?.aborted)throw l;if(u<10){let m=50*(1< +`,l),l}};return await o()}};var x=`PREFIX dc: PREFIX dwc: PREFIX dwcFP: PREFIX cito: PREFIX trt: -SELECT DISTINCT ?tn ?tc ?col ?rank ?genus ?subgenus ?species ?infrasp ?name ?authority +SELECT DISTINCT ?kingdom ?tn ?tc ?col ?rank ?genus ?subgenus ?species ?infrasp ?name ?authority (group_concat(DISTINCT ?tcauth;separator=" / ") AS ?tcAuth) (group_concat(DISTINCT ?aug;separator="|") as ?augs) (group_concat(DISTINCT ?def;separator="|") as ?defs) (group_concat(DISTINCT ?dpr;separator="|") as ?dprs) (group_concat(DISTINCT ?cite;separator="|") as ?cites) (group_concat(DISTINCT ?trtn;separator="|") as ?tntreats) - (group_concat(DISTINCT ?citetn;separator="|") as ?tncites)`,P="GROUP BY ?tn ?tc ?col ?rank ?genus ?subgenus ?species ?\ -infrasp ?name ?authority",q=h=>`${x} WHERE { -BIND(<${h}> as ?col) + (group_concat(DISTINCT ?citetn;separator="|") as ?tncites)`,P="GROUP BY ?kingdom ?tn ?tc ?col ?rank ?genus ?subgenus ?\ +species ?infrasp ?name ?authority",k=T=>`${x} WHERE { +BIND(<${T}> as ?col) ?col dwc:taxonRank ?rank . ?col dwc:scientificName ?name . ?col dwc:genericName ?genus . - # TODO # ?col dwc:parent* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?kingdom . + OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?colkingdom . } + BIND(COALESCE(?colkingdom, "") AS ?kingdom) + OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . } + BIND(COALESCE(?colsubgenus, "") AS ?subgenus) OPTIONAL { ?col dwc:specificEpithet ?species . OPTIONAL { ?col dwc:infraspecificEpithet ?infrasp . } @@ -33,22 +36,15 @@ BIND(<${h}> as ?col) ?tn dwc:rank ?trank ; a dwcFP:TaxonName . FILTER(LCASE(?rank) = LCASE(?trank)) - ?tn dwc:genus ?genus . ?tn dwc:kingdom ?kingdom . - { - ?col dwc:specificEpithet ?species . - ?tn dwc:species ?species . - { - ?col dwc:infraspecificEpithet ?infrasp . - ?tn dwc:subSpecies|dwc:variety|dwc:form ?infrasp . - } UNION { - FILTER NOT EXISTS { ?col dwc:infraspecificEpithet ?infrasp . } - FILTER NOT EXISTS { ?tn dwc:subSpecies|dwc:variety|dwc:form ?infrasp . } - } - } UNION { - FILTER NOT EXISTS { ?col dwc:specificEpithet ?species . } - FILTER NOT EXISTS { ?tn dwc:species ?species . } - } + ?tn dwc:genus ?genus . + + OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . } + FILTER(?subgenus = COALESCE(?tnsubgenus, "")) + OPTIONAL { ?tn dwc:species ?tnspecies . } + FILTER(?species = COALESCE(?tnspecies, "")) + OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . } + FILTER(?infrasp = COALESCE(?tninfrasp, "")) OPTIONAL { ?trtnt trt:treatsTaxonName ?tn ; trt:publishedIn/dc:date ?trtndate . @@ -82,8 +78,8 @@ BIND(<${h}> as ?col) } } ${P} -LIMIT 500`,k=h=>`${x} WHERE { - <${h}> trt:hasTaxonName ?tn . +LIMIT 500`,_=T=>`${x} WHERE { + <${T}> trt:hasTaxonName ?tn . ?tc trt:hasTaxonName ?tn ; dwc:scientificNameAuthorship ?tcauth ; a dwcFP:TaxonConcept . @@ -92,13 +88,14 @@ LIMIT 500`,k=h=>`${x} WHERE { ?tn dwc:rank ?tnrank . ?tn dwc:kingdom ?kingdom . ?tn dwc:genus ?genus . - OPTIONAL { ?tn dwc:subGenus ?subgenus . } + OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . } OPTIONAL { ?tn dwc:species ?tnspecies . OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . } } BIND(LCASE(?tnrank) AS ?rank) + BIND(COALESCE(?tnsubgenus, "") AS ?subgenus) BIND(COALESCE(?tnspecies, "") AS ?species) BIND(COALESCE(?tninfrasp, "") AS ?infrasp) @@ -106,8 +103,11 @@ LIMIT 500`,k=h=>`${x} WHERE { ?col dwc:taxonRank ?rank . ?col dwc:scientificName ?name . # Note: contains authority ?col dwc:genericName ?genus . - # TODO # ?col dwc:parent* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?kingdom . + OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?colkingdom . } + FILTER(?kingdom = COALESCE(?colkingdom, "")) + OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . } + FILTER(?subgenus = COALESCE(?colsubgenus, "")) OPTIONAL { ?col dwc:specificEpithet ?colspecies . } FILTER(?species = COALESCE(?colspecies, "")) OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . } @@ -142,19 +142,20 @@ LIMIT 500`,k=h=>`${x} WHERE { } } ${P} -LIMIT 500`,_=h=>`${x} WHERE { - BIND(<${h}> as ?tn) +LIMIT 500`,F=T=>`${x} WHERE { + BIND(<${T}> as ?tn) ?tn a dwcFP:TaxonName . ?tn dwc:rank ?tnrank . ?tn dwc:genus ?genus . ?tn dwc:kingdom ?kingdom . - OPTIONAL { ?tn dwc:subGenus ?subgenus . } + OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . } OPTIONAL { ?tn dwc:species ?tnspecies . OPTIONAL { ?tn dwc:subSpecies|dwc:variety|dwc:form ?tninfrasp . } } BIND(LCASE(?tnrank) AS ?rank) + BIND(COALESCE(?tnsubgenus, "") AS ?subgenus) BIND(COALESCE(?tnspecies, "") AS ?species) BIND(COALESCE(?tninfrasp, "") AS ?infrasp) @@ -162,8 +163,11 @@ LIMIT 500`,_=h=>`${x} WHERE { ?col dwc:taxonRank ?rank . ?col dwc:scientificName ?name . # Note: contains authority ?col dwc:genericName ?genus . - # TODO # ?col dwc:parent* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?kingdom . + OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank "kingdom" ; dwc:taxonName ?colkingdom . } + FILTER(?kingdom = COALESCE(?colkingdom, "")) + OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . } + FILTER(?subgenus = COALESCE(?colsubgenus, "")) OPTIONAL { ?col dwc:specificEpithet ?colspecies . } FILTER(?species = COALESCE(?colspecies, "")) OPTIONAL { ?col dwc:infraspecificEpithet ?colinfrasp . } @@ -202,23 +206,23 @@ LIMIT 500`,_=h=>`${x} WHERE { } } ${P} -LIMIT 500`;var O=class{isFinished=!1;monitor=new EventTarget;controller=new AbortController;sparqlEndpoint;names=[];pushName(t){this. +LIMIT 500`;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,i,s=!0,l=!1){ -if(this.sparqlEndpoint=t,this.ignoreDeprecatedCoL=s,this.startWithSubTaxa=l,i.startsWith("http"))this.getName(i,{searchTerm:!0, -subTaxon:!1}).catch(c=>{console.log("SynoGroup Failure: ",c),this.controller.abort("SynoGroup Failed")}).finally(()=>this. -finish());else{let c=[...i.split(" ").filter(d=>!!d),void 0,void 0];this.getNameFromLatin(c,{searchTerm:!0,subTaxon:!1}). -finally(()=>this.finish())}}findName(t){let i;for(let s of this.names){if(s.taxonNameURI===t||s.colURI===t){i=s;break}let l=s. -authorizedNames.find(c=>c.taxonConceptURI===t||c.colURI===t);if(l){i=l;break}}return i?Promise.resolve(i):new Promise((s,l)=>{ -this.monitor.addEventListener("updated",()=>{(this.names.length===0||this.isFinished)&&l();let c=this.names.at(-1);if(c. -taxonNameURI===t||c.colURI===t){s(c);return}let d=c.authorizedNames.find(u=>u.taxonConceptURI===t||u.colURI===t);if(d){s( -d);return}})})}async getName(t,i){if(this.expanded.has(t)){console.log("Skipping known",t);return}if(this.controller.signal?. +new CustomEvent("updated"))}expanded=new Set;acceptedCol=new Map;treatments=new Map;ignoreDeprecatedCoL;startWithSubTaxa;constructor(t,r,s=!0,u=!1){ +if(this.sparqlEndpoint=t,this.ignoreDeprecatedCoL=s,this.startWithSubTaxa=u,r.startsWith("http"))this.getName(r,{searchTerm:!0, +subTaxon:!1}).catch(o=>{console.log("SynoGroup Failure: ",o),this.controller.abort("SynoGroup Failed")}).finally(()=>this. +finish());else{let o=[...r.split(" ").filter(l=>!!l),void 0,void 0];this.getNameFromLatin(o,{searchTerm:!0,subTaxon:!1}). +finally(()=>this.finish())}}findName(t){let r;for(let s of this.names){if(s.taxonNameURI===t||s.colURI===t){r=s;break}let u=s. +authorizedNames.find(o=>o.taxonConceptURI===t||o.colURI===t);if(u){r=u;break}}return r?Promise.resolve(r):new Promise((s,u)=>{ +this.monitor.addEventListener("updated",()=>{(this.names.length===0||this.isFinished)&&u();let o=this.names.at(-1);if(o. +taxonNameURI===t||o.colURI===t){s(o);return}let l=o.authorizedNames.find(m=>m.taxonConceptURI===t||m.colURI===t);if(l){s( +l);return}})})}async getName(t,r){if(this.expanded.has(t)){console.log("Skipping known",t);return}if(this.controller.signal?. aborted)return Promise.reject();let s;if(t.startsWith("https://www.catalogueoflife.org"))s=await this.sparqlEndpoint.getSparqlResultSet( -q(t),{signal:this.controller.signal},`NameFromCol ${t}`);else if(t.startsWith("http://taxon-concept.plazi.org"))s=await this. -sparqlEndpoint.getSparqlResultSet(k(t),{signal:this.controller.signal},`NameFromTC ${t}`);else if(t.startsWith("http://t\ -axon-name.plazi.org"))s=await this.sparqlEndpoint.getSparqlResultSet(_(t),{signal:this.controller.signal},`NameFromTN ${t}`);else -throw`Cannot handle name-uri <${t}> !`;await this.handleName(s,i),this.startWithSubTaxa&&i.searchTerm&&!i.subTaxon&&await this. -getSubtaxa(t)}async getSubtaxa(t){let i=t.startsWith("http://taxon-concept.plazi.org")?` +k(t),{signal:this.controller.signal},`NameFromCol ${t}`);else if(t.startsWith("http://taxon-concept.plazi.org"))s=await this. +sparqlEndpoint.getSparqlResultSet(_(t),{signal:this.controller.signal},`NameFromTC ${t}`);else if(t.startsWith("http://t\ +axon-name.plazi.org"))s=await this.sparqlEndpoint.getSparqlResultSet(F(t),{signal:this.controller.signal},`NameFromTN ${t}`);else +throw`Cannot handle name-uri <${t}> !`;await this.handleName(s,r),this.startWithSubTaxa&&r.searchTerm&&!r.subTaxon&&await this. +getSubtaxa(t)}async getSubtaxa(t){let r=t.startsWith("http://taxon-concept.plazi.org")?` PREFIX trt: SELECT DISTINCT ?sub WHERE { BIND(<${t}> as ?url) @@ -231,46 +235,46 @@ 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( -i,{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,i,s],l){let c=`\ +LIMIT 5000`;if(this.controller.signal?.aborted)return Promise.reject();let u=(await this.sparqlEndpoint.getSparqlResultSet( +r,{signal:this.controller.signal},`Subtaxa ${t}`)).results.bindings.map(o=>o.sub?.value).filter(o=>o&&!this.expanded.has( +o));await Promise.allSettled(u.map(o=>this.getName(o,{searchTerm:!0,subTaxon:!0})))}async getNameFromLatin([t,r,s],u){let o=`\ PREFIX dwc: SELECT DISTINCT ?uri WHERE { ?uri dwc:genus|dwc:genericName "${t}" . - ${i?`?uri dwc:species|dwc:specificEpithet "${i}" .`:"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species\ + ${r?`?uri dwc:species|dwc:specificEpithet "${r}" .`:"FILTER NOT EXISTS { ?uri dwc:species|dwc:specificEpithet ?species\ . }"} ${s?`?uri dwc:subSpecies|dwc:variety|dwc:form|dwc:infraspecificEpithet "${s}" .`:"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 u=(await this.sparqlEndpoint.getSparqlResultSet( -c,{signal:this.controller.signal},`NameFromLatin ${t} ${i} ${s}`)).results.bindings.map(a=>a.uri?.value).filter(a=>a&&!this. -expanded.has(a));await Promise.allSettled(u.map(a=>this.getName(a,l)))}async handleName(t,i){let s=[],l=n=>{switch(n){case"\ -variety":return"var.";case"subspecies":return"subsp.";case"form":return"f.";default:return n}},c=(t.results.bindings[0]. +LIMIT 500`;if(this.controller.signal?.aborted)return Promise.reject();let m=(await this.sparqlEndpoint.getSparqlResultSet( +o,{signal:this.controller.signal},`NameFromLatin ${t} ${r} ${s}`)).results.bindings.map(i=>i.uri?.value).filter(i=>i&&!this. +expanded.has(i));await Promise.allSettled(m.map(i=>this.getName(i,u)))}async handleName(t,r){let s=[],u=e=>{switch(e){case"\ +variety":return"var.";case"subspecies":return"subsp.";case"form":return"f.";default:return e}},o=(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].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(),d,u=[],a=[],m=t.results.bindings[0].tn?.value;if(m){if(this.expanded.has(m))return;this.expanded.add(m)}for(let n of t. -results.bindings){if(n.col){let r=n.col.value;if(n.authority?.value){if(!u.find(f=>f.colURI===r)){if(this.expanded.has(r)){ -console.log("Skipping known",r);return}u.push({displayName:c,authority:n.authority.value,colURI:n.col.value,treatments:{ -def:new Set,aug:new Set,dpr:new Set,cite:new Set}})}}else{if(this.expanded.has(r)){console.log("Skipping known",r);return} -d&&d!==r&&console.log("Duplicate unathorized COL:",d,r),d=r}}if(n.tc&&n.tcAuth&&n.tcAuth.value){let r=this.makeTreatmentSet( -n.defs?.value.split("|")),f=this.makeTreatmentSet(n.augs?.value.split("|")),S=this.makeTreatmentSet(n.dprs?.value.split( -"|")),w=this.makeTreatmentSet(n.cites?.value.split("|")),N=u.find(v=>n.tcAuth.value.split(" / ").includes(v.authority)); -if(N)N.authority=n.tcAuth?.value,N.taxonConceptURI=n.tc.value,N.treatments={def:r,aug:f,dpr:S,cite:w};else{if(this.expanded. -has(n.tc.value))return;a.push({displayName:c,authority:n.tcAuth.value,taxonConceptURI:n.tc.value,treatments:{def:r,aug:f, -dpr:S,cite:w}})}r.forEach(v=>s.push(v)),f.forEach(v=>s.push(v)),S.forEach(v=>s.push(v))}}let T=this.makeTreatmentSet(t.results. -bindings[0].tntreats?.value.split("|"));T.forEach(n=>s.push(n));let o={displayName:c,rank:t.results.bindings[0].rank.value, -taxonNameURI:m,authorizedNames:[...u,...a],colURI:d,justification:i,treatments:{treats:T,cite:this.makeTreatmentSet(t.results. -bindings[0].tncites?.value.split("|"))},vernacularNames:m?this.getVernacular(m):Promise.resolve(new Map)};for(let n of o. -authorizedNames)n.colURI&&this.expanded.add(n.colURI),n.taxonConceptURI&&this.expanded.add(n.taxonConceptURI);let p=[];if(d){ -let[n,r]=await this.getAcceptedCol(d,o);o.acceptedColURI=n,p.push(...r)}await Promise.all(u.map(async n=>{let[r,f]=await this. -getAcceptedCol(n.colURI,o);n.acceptedColURI=r,p.push(...f)})),this.pushName(o);let e=new Map;(await Promise.all(s.map(n=>n. -details.then(r=>[n,r])))).map(([n,r])=>{r.treats.aug.difference(this.expanded).forEach(f=>e.set(f,n)),r.treats.def.difference( -this.expanded).forEach(f=>e.set(f,n)),r.treats.dpr.difference(this.expanded).forEach(f=>e.set(f,n)),r.treats.treattn.difference( -this.expanded).forEach(f=>e.set(f,n))}),await Promise.allSettled([...p,...[...e].map(([n,r])=>this.getName(n,{searchTerm:!1, -parent:o,treatment:r}))])}async getAcceptedCol(t,i){let s=` +results.bindings[0].infrasp?.value?` ${u(t.results.bindings[0].rank.value)} ${t.results.bindings[0].infrasp.value}`:"")). +trim(),l,m=[],i=[],c=t.results.bindings[0].tn?.value;if(c){if(this.expanded.has(c))return;this.expanded.add(c)}for(let e of t. +results.bindings){if(e.col){let n=e.col.value;if(e.authority?.value){if(!m.find(h=>h.colURI===n)){if(this.expanded.has(n)){ +console.log("Skipping known",n);return}m.push({displayName:o,authority:e.authority.value,colURI:e.col.value,treatments:{ +def:new Set,aug:new Set,dpr:new Set,cite:new Set}})}}else{if(this.expanded.has(n)){console.log("Skipping known",n);return} +l&&l!==n&&console.log("Duplicate unathorized COL:",l,n),l=n}}if(e.tc&&e.tcAuth&&e.tcAuth.value){let n=this.makeTreatmentSet( +e.defs?.value.split("|")),h=this.makeTreatmentSet(e.augs?.value.split("|")),v=this.makeTreatmentSet(e.dprs?.value.split( +"|")),w=this.makeTreatmentSet(e.cites?.value.split("|")),S=m.find(N=>e.tcAuth.value.split(" / ").includes(N.authority)); +if(S)S.authority=e.tcAuth?.value,S.taxonConceptURI=e.tc.value,S.treatments={def:n,aug:h,dpr:v,cite:w};else{if(this.expanded. +has(e.tc.value))return;i.push({displayName:o,authority:e.tcAuth.value,taxonConceptURI:e.tc.value,treatments:{def:n,aug:h, +dpr:v,cite:w}})}n.forEach(N=>s.push(N)),h.forEach(N=>s.push(N)),v.forEach(N=>s.push(N))}}let f=this.makeTreatmentSet(t.results. +bindings[0].tntreats?.value.split("|"));f.forEach(e=>s.push(e));let d={kingdom:t.results.bindings[0].kingdom.value,displayName:o, +rank:t.results.bindings[0].rank.value,taxonNameURI:c,authorizedNames:[...m,...i],colURI:l,justification:r,treatments:{treats:f, +cite:this.makeTreatmentSet(t.results.bindings[0].tncites?.value.split("|"))},vernacularNames:c?this.getVernacular(c):Promise. +resolve(new Map)};for(let e of d.authorizedNames)e.colURI&&this.expanded.add(e.colURI),e.taxonConceptURI&&this.expanded. +add(e.taxonConceptURI);let p=[];if(l){let[e,n]=await this.getAcceptedCol(l,d);d.acceptedColURI=e,p.push(...n)}await Promise. +all(m.map(async e=>{let[n,h]=await this.getAcceptedCol(e.colURI,d);e.acceptedColURI=n,p.push(...h)})),this.pushName(d);let a=new Map; +(await Promise.all(s.map(e=>e.details.then(n=>[e,n])))).map(([e,n])=>{n.treats.aug.difference(this.expanded).forEach(h=>a. +set(h,e)),n.treats.def.difference(this.expanded).forEach(h=>a.set(h,e)),n.treats.dpr.difference(this.expanded).forEach(h=>a. +set(h,e)),n.treats.treattn.difference(this.expanded).forEach(h=>a.set(h,e))}),await Promise.allSettled([...p,...[...a].map( +([e,n])=>this.getName(e,{searchTerm:!1,parent:d,treatment:n}))])}async getAcceptedCol(t,r){let s=` PREFIX dwc: SELECT DISTINCT ?current ?current_status (GROUP_CONCAT(DISTINCT ?dpr; separator="|") AS ?dprs) WHERE { BIND(<${t}> AS ?col) @@ -285,19 +289,19 @@ 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[this.acceptedCol.get(t),[]];let l=await this.sparqlEndpoint. -getSparqlResultSet(s,{signal:this.controller.signal},`AcceptedCol ${t}`),c=[];for(let d of l.results.bindings)for(let u of d. -dprs.value.split("|"))u&&(this.acceptedCol.has(d.current.value)||(this.acceptedCol.set(d.current.value,d.current.value), -c.push(this.getName(d.current.value,{searchTerm:!1,parent:i}))),this.acceptedCol.set(u,d.current.value),this.ignoreDeprecatedCoL|| -c.push(this.getName(u,{searchTerm:!1,parent:i})));return l.results.bindings.length===0?(this.acceptedCol.has(t)||this.acceptedCol. -set(t,"INVALID COL"),[this.acceptedCol.get(t),c]):(this.acceptedCol.has(t)||this.acceptedCol.set(t,t),[this.acceptedCol. -get(t),c])}async getVernacular(t){let i=new Map,s=`SELECT DISTINCT ?n WHERE { <${t}> ?n . }`,l=(await this.sparqlEndpoint.getSparqlResultSet(s,{signal:this.controller.signal},`Vernacular ${t}`)). -results.bindings;for(let c of l)c.n?.value&&(c.n["xml:lang"]?i.has(c.n["xml:lang"])?i.get(c.n["xml:lang"]).push(c.n.value): -i.set(c.n["xml:lang"],[c.n.value]):i.has("??")?i.get("??").push(c.n.value):i.set("??",[c.n.value]));return i}makeTreatmentSet(t){ -return t?new Set(t.filter(i=>!!i).map(i=>{let[s,l]=i.split(">");if(!this.treatments.has(s)){let c=this.getTreatmentDetails( -s);this.treatments.set(s,{url:s,date:l?parseInt(l,10):void 0,details:c})}return this.treatments.get(s)})):new Set}async getTreatmentDetails(t){ -let i=` +GROUP BY ?current ?current_status`;if(this.acceptedCol.has(t))return[this.acceptedCol.get(t),[]];let u=await this.sparqlEndpoint. +getSparqlResultSet(s,{signal:this.controller.signal},`AcceptedCol ${t}`),o=[];for(let l of u.results.bindings)for(let m of l. +dprs.value.split("|"))m&&(this.acceptedCol.has(l.current.value)||(this.acceptedCol.set(l.current.value,l.current.value), +o.push(this.getName(l.current.value,{searchTerm:!1,parent:r}))),this.acceptedCol.set(m,l.current.value),this.ignoreDeprecatedCoL|| +o.push(this.getName(m,{searchTerm:!1,parent:r})));return u.results.bindings.length===0?(this.acceptedCol.has(t)||this.acceptedCol. +set(t,"INVALID COL"),[this.acceptedCol.get(t),o]):(this.acceptedCol.has(t)||this.acceptedCol.set(t,t),[this.acceptedCol. +get(t),o])}async getVernacular(t){let r=new Map,s=`SELECT DISTINCT ?n WHERE { <${t}> ?n . }`,u=(await this.sparqlEndpoint.getSparqlResultSet(s,{signal:this.controller.signal},`Vernacular ${t}`)). +results.bindings;for(let o of u)o.n?.value&&(o.n["xml:lang"]?r.has(o.n["xml:lang"])?r.get(o.n["xml:lang"]).push(o.n.value): +r.set(o.n["xml:lang"],[o.n.value]):r.has("??")?r.get("??").push(o.n.value):r.set("??",[o.n.value]));return r}makeTreatmentSet(t){ +return t?new Set(t.filter(r=>!!r).map(r=>{let[s,u]=r.split(">");if(!this.treatments.has(s)){let o=this.getTreatmentDetails( +s);this.treatments.set(s,{url:s,date:u?parseInt(u,10):void 0,details:o})}return this.treatments.get(s)})):new Set}async getTreatmentDetails(t){ +let r=` PREFIX dc: PREFIX dwc: PREFIX dwcFP: @@ -364,14 +368,14 @@ 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 s=await this.sparqlEndpoint.getSparqlResultSet( -i,{signal:this.controller.signal},`TreatmentDetails ${t}`),l=s.results.bindings.filter(a=>a.mc&&a.catalogNumbers?.value). -map(a=>{let m=a.httpUris?.value?.split("|");return{catalogNumber:a.catalogNumbers.value,collectionCode:a.collectionCodes?. -value||void 0,typeStatus:a.typeStatuss?.value||void 0,countryCode:a.countryCodes?.value||void 0,stateProvince:a.stateProvinces?. -value||void 0,municipality:a.municipalitys?.value||void 0,county:a.countys?.value||void 0,locality:a.localitys?.value||void 0, -verbatimLocality:a.verbatimLocalitys?.value||void 0,recordedBy:a.recordedBys?.value||void 0,eventDate:a.eventDates?.value|| -void 0,samplingProtocol:a.samplingProtocols?.value||void 0,decimalLatitude:a.decimalLatitudes?.value||void 0,decimalLongitude:a. -decimalLongitudes?.value||void 0,verbatimElevation:a.verbatimElevations?.value||void 0,gbifOccurrenceId:a.gbifOccurrenceIds?. -value||void 0,gbifSpecimenId:a.gbifSpecimenIds?.value||void 0,httpUri:m?.length?m:void 0}}),c=` +r,{signal:this.controller.signal},`TreatmentDetails ${t}`),u=s.results.bindings.filter(i=>i.mc&&i.catalogNumbers?.value). +map(i=>{let c=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:c?.length?c:void 0}}),o=` PREFIX cito: PREFIX fabio: PREFIX dc: @@ -380,20 +384,20 @@ SELECT DISTINCT ?url ?description WHERE { ?cites a fabio:Figure ; fabio:hasRepresentation ?url . OPTIONAL { ?cites dc:description ?description . } -} `,u=(await this.sparqlEndpoint.getSparqlResultSet(c,{signal:this.controller.signal},`TreatmentDetails/Figures ${t}`)). -results.bindings.filter(a=>a.url?.value).map(a=>({url:a.url.value,description:a.description?.value}));return{creators:s. -results.bindings[0]?.creators?.value,title:s.results.bindings[0]?.title?.value,materialCitations:l,figureCitations:u,treats:{ +} `,m=(await this.sparqlEndpoint.getSparqlResultSet(o,{signal:this.controller.signal},`TreatmentDetails/Figures ${t}`)). +results.bindings.filter(i=>i.url?.value).map(i=>({url:i.url.value,description:i.description?.value}));return{creators:s. +results.bindings[0]?.creators?.value,title:s.results.bindings[0]?.title?.value,materialCitations:u,figureCitations:m,treats:{ def:new Set(s.results.bindings[0]?.defs?.value?s.results.bindings[0].defs.value.split("|"):void 0),aug:new Set(s.results. bindings[0]?.augs?.value?s.results.bindings[0].augs.value.split("|"):void 0),dpr:new Set(s.results.bindings[0]?.dprs?.value? s.results.bindings[0].dprs.value.split("|"):void 0),citetc:new Set(s.results.bindings[0]?.cites?.value?s.results.bindings[0]. cites.value.split("|"):void 0),treattn:new Set(s.results.bindings[0]?.trttns?.value?s.results.bindings[0].trttns.value.split( "|"):void 0),citetn:new Set(s.results.bindings[0]?.citetns?.value?s.results.bindings[0].citetns.value.split("|"):void 0)}}}catch(s){ return console.warn("SPARQL Error: "+s),{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((i,s)=>{let l=()=>{ -if(this.controller.signal.aborted)s(new Error("SynyonymGroup has been aborted"));else if(t{this.monitor.removeEventListener("updated",c), -l()};this.monitor.addEventListener("updated",c)}};l()})}}};function F(h){let t=new Set(h);return Array.from(t)}var E=new URLSearchParams(document.location.search),M=!E.has("show_col"),$=E.has("subtaxa"),H=E.has("sort_treatments_by_\ -type"),Q=E.get("server")||"https://treatment.ld.plazi.org/sparql",z=E.get("q")||"https://www.catalogueoflife.org/data/ta\ +citetc:new Set,treattn:new Set,citetn:new Set}}}}[Symbol.asyncIterator](){let t=0;return{next:()=>new Promise((r,s)=>{let u=()=>{ +if(this.controller.signal.aborted)s(new Error("SynyonymGroup has been aborted"));else if(t{this.monitor.removeEventListener("updated",o), +u()};this.monitor.addEventListener("updated",o)}};u()})}}};function z(T){let t=new Set(T);return Array.from(t)}var E=new URLSearchParams(document.location.search),$=!E.has("show_col"),H=E.has("subtaxa"),Q=E.has("sort_treatments_by_\ +type"),Z=E.get("server")||"https://treatment.ld.plazi.org/sparql",B=E.get("q")||"https://www.catalogueoflife.org/data/ta\ xon/3WD9M",D=document.getElementById("root");var g={def:'',collapse:'',west:'',empty:''},L=document.createElement("div");D.insertAdjacentElement( -"beforebegin",L);L.append(`Finding Synonyms for ${z} `);var X=document.createElement("progress");L.append(X);var Z=performance. -now(),W=new A(Q),I=new O(W,z,M,$),C=class extends HTMLElement{constructor(t,i){super(),this.innerHTML=g[i]??g.unknown;let s=document. +"beforebegin",L);L.append(`Finding Synonyms for ${B} `);var X=document.createElement("progress");L.append(X);var W=performance. +now(),J=new O(Z),I=new b(J,B,$,H),C=class extends HTMLElement{constructor(t,r){super(),this.innerHTML=g[r]??g.unknown;let s=document. createElement("button");s.classList.add("icon","button"),s.innerHTML=g.expand,s.addEventListener("click",()=>{this.classList. -toggle("expanded")?s.innerHTML=g.collapse:s.innerHTML=g.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. -append(": ",c);let d=document.createElement("a");d.classList.add("treatment","uri"),d.href=t.url,d.target="_blank",d.innerText= -t.url.replace("http://treatment.plazi.org/id/",""),d.innerHTML+=g.link,this.append(" ",d),this.append(s);let u=document. -createElement("div");u.classList.add("indent","details"),this.append(u),t.details.then(a=>{let m=document.createElement( -"span"),T=document.createElement("i");if(c.replaceWith(m," ",T),a.creators?m.innerText=a.creators:(m.classList.add("miss\ -ing"),m.innerText="No Authors"),a.title?T.innerText="\u201C"+a.title+"\u201D":(T.classList.add("missing"),T.innerText="N\ -o Title"),a.treats.def.size>0){let o=document.createElement("div");o.innerHTML=g.east,o.innerHTML+=g.def,(i==="def"||i=== -"cite")&&o.classList.add("hidden"),u.append(o),a.treats.def.forEach(p=>{let e=document.createElement("a");e.classList.add( -"taxon","uri");let n=p.replace("http://taxon-concept.plazi.org/id/","");e.innerText=n,e.href="#"+n,e.title="show name",o. -append(" ",e),I.findName(p).then(r=>{e.classList.remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText= -r.displayName},()=>{e.removeAttribute("href")})})}if(a.treats.aug.size>0||a.treats.treattn.size>0){let o=document.createElement( -"div");o.innerHTML=g.east,o.innerHTML+=g.aug,(i==="aug"||i==="cite")&&o.classList.add("hidden"),u.append(o),a.treats.aug. -forEach(p=>{let e=document.createElement("a");e.classList.add("taxon","uri");let n=p.replace("http://taxon-concept.plazi\ -.org/id/","");e.innerText=n,e.href="#"+n,e.title="show name",o.append(" ",e),I.findName(p).then(r=>{e.classList.remove("\ -uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})}), -a.treats.treattn.forEach(p=>{let e=document.createElement("a");e.classList.add("taxon","uri");let n=p.replace("http://ta\ -xon-name.plazi.org/id/","");e.innerText=n,e.href="#"+n,e.title="show name",o.append(" ",e),I.findName(p).then(r=>{e.classList. -remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("h\ -ref")})})}if(a.treats.dpr.size>0){let o=document.createElement("div");o.innerHTML=g.west,o.innerHTML+=g.dpr,(i==="dpr"|| -i==="cite")&&o.classList.add("hidden"),u.append(o),a.treats.dpr.forEach(p=>{let e=document.createElement("a");e.classList. -add("taxon","uri");let n=p.replace("http://taxon-concept.plazi.org/id/","");e.innerText=n,e.href="#"+n,e.title="show nam\ -e",o.append(" ",e),I.findName(p).then(r=>{e.classList.remove("uri"),r.authority?e.innerText=r.displayName+" "+r.authority: -e.innerText=r.displayName},()=>{e.removeAttribute("href")})})}if(a.treats.citetc.size>0||a.treats.citetn.size>0){let o=document. -createElement("div");o.innerHTML=g.empty+g.cite,o.classList.add("hidden"),u.append(o),a.treats.citetc.forEach(p=>{let e=document. -createElement("a");e.classList.add("taxon","uri");let n=p.replace("http://taxon-concept.plazi.org/id/","");e.innerText=n, -e.href="#"+n,e.title="show name",o.append(" ",e),I.findName(p).then(r=>{e.classList.remove("uri"),r.authority?e.innerText= -r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})}),a.treats.citetn.forEach(p=>{ -let e=document.createElement("a");e.classList.add("taxon","uri");let n=p.replace("http://taxon-name.plazi.org/id/","");e. -innerText=n,e.href="#"+n,e.title="show name",o.append(" ",e),I.findName(p).then(r=>{e.classList.remove("uri"),r.authority? -e.innerText=r.displayName+" "+r.authority:e.innerText=r.displayName},()=>{e.removeAttribute("href")})})}if(a.figureCitations. -length>0){let o=document.createElement("div");o.classList.add("figures","hidden"),u.append(o);for(let p of a.figureCitations){ -let e=document.createElement("figure");o.append(e);let n=document.createElement("img");n.src=p.url,n.loading="lazy",n.alt= -p.description??"Cited Figure without caption",e.append(n);let r=document.createElement("figcaption");r.innerText=p.description?? -"",e.append(r)}}if(a.materialCitations.length>0){let o=document.createElement("div");o.innerHTML=g.empty+g.cite+" Materi\ -al Citations:
-",o.classList.add("hidden"),u.append(o),o.innerText+=a.materialCitations.map(p=>JSON.stringify(p).replaceAll( +toggle("expanded")?s.innerHTML=g.collapse:s.innerHTML=g.expand});let u=document.createElement("span");t.date?u.innerText= +""+t.date:(u.classList.add("missing"),u.innerText="No Date"),this.append(u);let o=document.createElement("progress");this. +append(": ",o);let l=document.createElement("a");l.classList.add("treatment","uri"),l.href=t.url,l.target="_blank",l.innerText= +t.url.replace("http://treatment.plazi.org/id/",""),l.innerHTML+=g.link,this.append(" ",l),this.append(s);let m=document. +createElement("div");m.classList.add("indent","details"),this.append(m),t.details.then(i=>{let c=document.createElement( +"span"),f=document.createElement("i");if(o.replaceWith(c," ",f),i.creators?c.innerText=i.creators:(c.classList.add("miss\ +ing"),c.innerText="No Authors"),i.title?f.innerText="\u201C"+i.title+"\u201D":(f.classList.add("missing"),f.innerText="N\ +o Title"),i.treats.def.size>0){let d=document.createElement("div");d.innerHTML=g.east,d.innerHTML+=g.def,(r==="def"||r=== +"cite")&&d.classList.add("hidden"),m.append(d),i.treats.def.forEach(p=>{let a=document.createElement("a");a.classList.add( +"taxon","uri");let e=p.replace("http://taxon-concept.plazi.org/id/","");a.innerText=e,a.href="#"+e,a.title="show name",d. +append(" ",a),I.findName(p).then(n=>{a.classList.remove("uri"),n.authority?a.innerText=n.displayName+" "+n.authority:a.innerText= +n.displayName},()=>{a.removeAttribute("href")})})}if(i.treats.aug.size>0||i.treats.treattn.size>0){let d=document.createElement( +"div");d.innerHTML=g.east,d.innerHTML+=g.aug,(r==="aug"||r==="cite")&&d.classList.add("hidden"),m.append(d),i.treats.aug. +forEach(p=>{let a=document.createElement("a");a.classList.add("taxon","uri");let e=p.replace("http://taxon-concept.plazi\ +.org/id/","");a.innerText=e,a.href="#"+e,a.title="show name",d.append(" ",a),I.findName(p).then(n=>{a.classList.remove("\ +uri"),n.authority?a.innerText=n.displayName+" "+n.authority:a.innerText=n.displayName},()=>{a.removeAttribute("href")})}), +i.treats.treattn.forEach(p=>{let a=document.createElement("a");a.classList.add("taxon","uri");let e=p.replace("http://ta\ +xon-name.plazi.org/id/","");a.innerText=e,a.href="#"+e,a.title="show name",d.append(" ",a),I.findName(p).then(n=>{a.classList. +remove("uri"),n.authority?a.innerText=n.displayName+" "+n.authority:a.innerText=n.displayName},()=>{a.removeAttribute("h\ +ref")})})}if(i.treats.dpr.size>0){let d=document.createElement("div");d.innerHTML=g.west,d.innerHTML+=g.dpr,(r==="dpr"|| +r==="cite")&&d.classList.add("hidden"),m.append(d),i.treats.dpr.forEach(p=>{let a=document.createElement("a");a.classList. +add("taxon","uri");let e=p.replace("http://taxon-concept.plazi.org/id/","");a.innerText=e,a.href="#"+e,a.title="show nam\ +e",d.append(" ",a),I.findName(p).then(n=>{a.classList.remove("uri"),n.authority?a.innerText=n.displayName+" "+n.authority: +a.innerText=n.displayName},()=>{a.removeAttribute("href")})})}if(i.treats.citetc.size>0||i.treats.citetn.size>0){let d=document. +createElement("div");d.innerHTML=g.empty+g.cite,d.classList.add("hidden"),m.append(d),i.treats.citetc.forEach(p=>{let a=document. +createElement("a");a.classList.add("taxon","uri");let e=p.replace("http://taxon-concept.plazi.org/id/","");a.innerText=e, +a.href="#"+e,a.title="show name",d.append(" ",a),I.findName(p).then(n=>{a.classList.remove("uri"),n.authority?a.innerText= +n.displayName+" "+n.authority:a.innerText=n.displayName},()=>{a.removeAttribute("href")})}),i.treats.citetn.forEach(p=>{ +let a=document.createElement("a");a.classList.add("taxon","uri");let e=p.replace("http://taxon-name.plazi.org/id/","");a. +innerText=e,a.href="#"+e,a.title="show name",d.append(" ",a),I.findName(p).then(n=>{a.classList.remove("uri"),n.authority? +a.innerText=n.displayName+" "+n.authority:a.innerText=n.displayName},()=>{a.removeAttribute("href")})})}if(i.figureCitations. +length>0){let d=document.createElement("div");d.classList.add("figures","hidden"),m.append(d);for(let p of i.figureCitations){ +let a=document.createElement("figure");d.append(a);let e=document.createElement("img");e.src=p.url,e.loading="lazy",e.alt= +p.description??"Cited Figure without caption",a.append(e);let n=document.createElement("figcaption");n.innerText=p.description?? +"",a.append(n)}}if(i.materialCitations.length>0){let d=document.createElement("div");d.innerHTML=g.empty+g.cite+" Materi\ +al Citations:
-",d.classList.add("hidden"),m.append(d),d.innerText+=i.materialCitations.map(p=>JSON.stringify(p).replaceAll( "{","").replaceAll("}","").replaceAll('":',": ").replaceAll(",",", ").replaceAll('"',"")).join(` - -`)}})}};customElements.define("syno-treatment",C);var b=class extends HTMLElement{constructor(t){super();let i=document. -createElement("h2"),s=document.createElement("i");s.innerText=t.displayName,i.append(s),this.append(i);let l=document.createElement( -"span");if(l.classList.add("rank"),l.innerText=t.rank,i.append(" ",l),t.taxonNameURI){let a=document.createElement("a"); -a.classList.add("taxon","uri");let m=t.taxonNameURI.replace("http://taxon-name.plazi.org/id/","");a.innerText=m,a.id=m,a. -href=t.taxonNameURI,a.target="_blank",a.innerHTML+=g.link,i.append(" ",a)}let c=document.createElement("div");c.classList. -add("vernacular"),t.vernacularNames.then(a=>{a.size>0&&(c.innerText="\u201C"+F([...a.values()].flat()).join("\u201D, \u201C")+ -"\u201D")}),this.append(c);let d=document.createElement("ul");if(this.append(d),t.colURI){let a=document.createElement("\ -a");a.classList.add("col","uri");let m=t.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");a.innerText=m, -a.id=m,a.href=t.colURI,a.target="_blank",a.innerHTML+=g.link,i.append(" ",a);let T=document.createElement("div");T.classList. -add("treatmentline"),T.innerHTML=t.acceptedColURI!==t.colURI?g.col_dpr:g.col_aug,d.append(T);let o=document.createElement( -"span");o.innerText="Catalogue of Life",T.append(o);let p=document.createElement("div");if(p.classList.add("indent"),T.append( -p),t.acceptedColURI!==t.colURI){let e=document.createElement("div");e.innerHTML=g.east+g.col_aug,p.append(e);let n=document. -createElement("a");n.classList.add("col","uri");let r=t.acceptedColURI.replace("https://www.catalogueoflife.org/data/tax\ -on/","");n.innerText=r,n.href=`#${r}`,n.title="show name",e.append(n),I.findName(t.acceptedColURI).then(f=>{f.authority? -n.innerText=f.displayName+" "+f.authority:n.innerText=f.displayName},()=>{n.removeAttribute("href")})}}if(t.treatments.treats. -size>0||t.treatments.cite.size>0){for(let a of t.treatments.treats){let m=new C(a,"aug");d.append(m)}for(let a of t.treatments. -cite){let m=new C(a,"cite");d.append(m)}}let u=document.createElement("abbr");u.classList.add("justification"),u.innerText= -"...?",R(t).then(a=>u.title=`This ${a}`),i.append(" ",u);for(let a of t.authorizedNames){let m=document.createElement("h\ -3"),T=document.createElement("i");T.innerText=a.displayName,T.classList.add("gray"),m.append(T),m.append(" ",a.authority), -this.append(m);let o=document.createElement("ul");if(this.append(o),a.taxonConceptURI){let e=document.createElement("a"); -e.classList.add("taxon","uri");let n=a.taxonConceptURI.replace("http://taxon-concept.plazi.org/id/","");e.innerText=n,e. -id=n,e.href=a.taxonConceptURI,e.target="_blank",e.innerHTML+=g.link,m.append(" ",e)}if(a.colURI){let e=document.createElement( -"a");e.classList.add("col","uri");let n=a.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");e.innerText=n, -e.id=n,e.href=a.colURI,e.target="_blank",e.innerHTML+=g.link,m.append(" ",e);let r=document.createElement("div");r.classList. -add("treatmentline"),r.innerHTML=a.acceptedColURI!==a.colURI?g.col_dpr:g.col_aug,o.append(r);let f=document.createElement( -"span");f.innerText="Catalogue of Life",r.append(f);let S=document.createElement("div");if(S.classList.add("indent"),r.append( -S),a.acceptedColURI!==a.colURI){let w=document.createElement("div");w.innerHTML=g.east+g.col_aug,S.append(w);let N=document. -createElement("a");N.classList.add("col","uri");let v=a.acceptedColURI.replace("https://www.catalogueoflife.org/data/tax\ -on/","");N.innerText=v,N.href=`#${v}`,N.title="show name",w.append(" ",N),I.findName(a.acceptedColURI).then(y=>{N.classList. -remove("uri"),y.authority?N.innerText=y.displayName+" "+y.authority:N.innerText=y.displayName},()=>{N.removeAttribute("h\ -ref")})}}let p=[];for(let e of a.treatments.def)p.push({trt:e,status:"def"});for(let e of a.treatments.aug)p.push({trt:e, -status:"aug"});for(let e of a.treatments.dpr)p.push({trt:e,status:"dpr"});for(let e of a.treatments.cite)p.push({trt:e,status:"\ -cite"});H||p.sort((e,n)=>e.trt.date&&n.trt.date?e.trt.date-n.trt.date:e.trt.date?1:n.trt.date?-1:0);for(let{trt:e,status:n}of p){ -let r=new C(e,n);o.append(r)}}}};customElements.define("syno-name",b);async function R(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,i=await R(h.justification.parent);return`is, according to ${t.creators} ${h. -justification.treatment.date}, - a synonym of ${h.justification.parent.displayName} which ${i}`}else{let t=await R(h.justification.parent);return`is\ + -`)}})}};customElements.define("syno-treatment",C);var y=class extends HTMLElement{constructor(t){super();let r=document. +createElement("h2"),s=document.createElement("i");s.innerText=t.displayName,r.append(s),this.append(r);let u=document.createElement( +"span");u.classList.add("rank"),u.innerText=t.rank;let o=document.createElement("span");if(o.classList.add("rank"),o.innerText= +t.kingdom||"Missing Kingdom",r.append(" ",o," ",u),t.taxonNameURI){let c=document.createElement("a");c.classList.add("ta\ +xon","uri");let f=t.taxonNameURI.replace("http://taxon-name.plazi.org/id/","");c.innerText=f,c.id=f,c.href=t.taxonNameURI, +c.target="_blank",c.innerHTML+=g.link,r.append(" ",c)}let l=document.createElement("div");l.classList.add("vernacular"), +t.vernacularNames.then(c=>{c.size>0&&(l.innerText="\u201C"+z([...c.values()].flat()).join("\u201D, \u201C")+"\u201D")}), +this.append(l);let m=document.createElement("ul");if(this.append(m),t.colURI){let c=document.createElement("a");c.classList. +add("col","uri");let f=t.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");c.innerText=f,c.id=f,c.href=t. +colURI,c.target="_blank",c.innerHTML+=g.link,r.append(" ",c);let d=document.createElement("div");d.classList.add("treatm\ +entline"),d.innerHTML=t.acceptedColURI!==t.colURI?g.col_dpr:g.col_aug,m.append(d);let p=document.createElement("span");p. +innerText="Catalogue of Life",d.append(p);let a=document.createElement("div");if(a.classList.add("indent"),d.append(a),t. +acceptedColURI!==t.colURI){let e=document.createElement("div");e.innerHTML=g.east+g.col_aug,a.append(e);let n=document.createElement( +"a");n.classList.add("col","uri");let h=t.acceptedColURI.replace("https://www.catalogueoflife.org/data/taxon/","");n.innerText= +h,n.href=`#${h}`,n.title="show name",e.append(n),I.findName(t.acceptedColURI).then(v=>{v.authority?n.innerText=v.displayName+ +" "+v.authority:n.innerText=v.displayName},()=>{n.removeAttribute("href")})}}if(t.treatments.treats.size>0||t.treatments. +cite.size>0){for(let c of t.treatments.treats){let f=new C(c,"aug");m.append(f)}for(let c of t.treatments.cite){let f=new C( +c,"cite");m.append(f)}}let i=document.createElement("abbr");i.classList.add("justification"),i.innerText="...?",R(t).then( +c=>i.title=`This ${c}`),r.append(" ",i);for(let c of t.authorizedNames){let f=document.createElement("h3"),d=document.createElement( +"i");d.innerText=c.displayName,d.classList.add("gray"),f.append(d),f.append(" ",c.authority),this.append(f);let p=document. +createElement("ul");if(this.append(p),c.taxonConceptURI){let e=document.createElement("a");e.classList.add("taxon","uri"); +let n=c.taxonConceptURI.replace("http://taxon-concept.plazi.org/id/","");e.innerText=n,e.id=n,e.href=c.taxonConceptURI,e. +target="_blank",e.innerHTML+=g.link,f.append(" ",e)}if(c.colURI){let e=document.createElement("a");e.classList.add("col", +"uri");let n=c.colURI.replace("https://www.catalogueoflife.org/data/taxon/","");e.innerText=n,e.id=n,e.href=c.colURI,e.target= +"_blank",e.innerHTML+=g.link,f.append(" ",e);let h=document.createElement("div");h.classList.add("treatmentline"),h.innerHTML= +c.acceptedColURI!==c.colURI?g.col_dpr:g.col_aug,p.append(h);let v=document.createElement("span");v.innerText="Catalogue \ +of Life",h.append(v);let w=document.createElement("div");if(w.classList.add("indent"),h.append(w),c.acceptedColURI!==c.colURI){ +let S=document.createElement("div");S.innerHTML=g.east+g.col_aug,w.append(S);let N=document.createElement("a");N.classList. +add("col","uri");let q=c.acceptedColURI.replace("https://www.catalogueoflife.org/data/taxon/","");N.innerText=q,N.href=`\ +#${q}`,N.title="show name",S.append(" ",N),I.findName(c.acceptedColURI).then(A=>{N.classList.remove("uri"),A.authority?N. +innerText=A.displayName+" "+A.authority:N.innerText=A.displayName},()=>{N.removeAttribute("href")})}}let a=[];for(let e of c. +treatments.def)a.push({trt:e,status:"def"});for(let e of c.treatments.aug)a.push({trt:e,status:"aug"});for(let e of c.treatments. +dpr)a.push({trt:e,status:"dpr"});for(let e of c.treatments.cite)a.push({trt:e,status:"cite"});Q||a.sort((e,n)=>e.trt.date&& +n.trt.date?e.trt.date-n.trt.date:e.trt.date?1:n.trt.date?-1:0);for(let{trt:e,status:n}of a){let h=new C(e,n);p.append(h)}}}}; +customElements.define("syno-name",y);async function R(T){if(T.justification.searchTerm)return T.justification.subTaxon?"\ +is a sub-taxon of the search term.":"is the search term.";if(T.justification.treatment){let t=await T.justification.treatment. +details,r=await R(T.justification.parent);return`is, according to ${t.creators} ${T.justification.treatment.date}, + a synonym of ${T.justification.parent.displayName} which ${r}`}else{let t=await R(T.justification.parent);return`is\ , according to the Catalogue of Life, - a synonym of ${h.justification.parent.displayName} which ${t}`}}for await(let h of I){let t=new b(h);D.append(t)}var J=performance. -now();L.innerHTML="";L.innerText=`Found ${I.names.length} names with ${I.treatments.size} treatments. This took ${(J-Z)/ + a synonym of ${T.justification.parent.displayName} which ${t}`}}for await(let T of I){let t=new y(T);D.append(t)}var G=performance. +now();L.innerHTML="";L.innerText=`Found ${I.names.length} names with ${I.treatments.size} treatments. This took ${(G-W)/ 1e3} seconds.`;I.names.length===0&&D.append(":["); //# sourceMappingURL=index.js.map diff --git a/index.js.map b/index.js.map index da8fa8a..6273e29 100644 --- a/index.js.map +++ b/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../SparqlEndpoint.ts", "../Queries.ts", "../SynonymGroup.ts", "https://jsr.io/@std/collections/1.0.9/distinct.ts", "index.ts"], - "sourcesContent": ["// deno-lint-ignore-file no-unused-labels\nasync 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.warn(`!! 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 ?tn ?tc ?col ?rank ?genus ?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 ?tn ?tc ?col ?rank ?genus ?subgenus ?species ?infrasp ?name ?authority`;\n\n// For unclear reasons, the queries breaks if the limit is removed.\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 # TODO # ?col dwc:parent* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?kingdom .\n OPTIONAL {\n ?col dwc:specificEpithet ?species .\n OPTIONAL { ?col dwc:infraspecificEpithet ?infrasp . }\n }\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\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 .\n {\n ?col dwc:specificEpithet ?species .\n ?tn dwc:species ?species .\n {\n ?col dwc:infraspecificEpithet ?infrasp .\n ?tn dwc:subSpecies|dwc:variety|dwc:form ?infrasp .\n } UNION {\n FILTER NOT EXISTS { ?col dwc:infraspecificEpithet ?infrasp . }\n FILTER NOT EXISTS { ?tn dwc:subSpecies|dwc:variety|dwc:form ?infrasp . }\n }\n } UNION {\n FILTER NOT EXISTS { ?col dwc:specificEpithet ?species . }\n FILTER NOT EXISTS { ?tn dwc:species ?species . }\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}\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 .\n ?tn dwc:genus ?genus .\n OPTIONAL { ?tn dwc:subGenus ?subgenus . }\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(?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 # TODO # ?col dwc:parent* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?kingdom .\n\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 .\n OPTIONAL { ?tn dwc:subGenus ?subgenus . }\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(?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 # TODO # ?col dwc:parent* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?kingdom .\n\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", "import type { SparqlEndpoint, SparqlJson } from \"./mod.ts\";\nimport * as Queries from \"./Queries.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 * Not that \"weird\" ranks like subGenus 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.colURI === uri) {\n name = n;\n break;\n }\n const an = n.authorizedNames.find((an) =>\n an.taxonConceptURI === uri || an.colURI === 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.colURI === uri) {\n resolve(n);\n return;\n }\n const an = n.authorizedNames.find((an) =>\n an.taxonConceptURI === uri || an.colURI === 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].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: string | undefined;\n\n // there can be multiple CoL-taxa with same latin name, e.g. Leontopodium alpinum has 3T6ZY and 3T6ZX.\n const authorizedCoLNames: AuthorizedName[] = [];\n const authorizedTCNames: 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 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) {\n console.log(\"Duplicate unathorized COL:\", unathorizedCol, colURI);\n }\n unathorizedCol = colURI;\n } else if (!authorizedCoLNames.find((e) => e.colURI === colURI)) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n authorizedCoLNames.push({\n displayName,\n authority: t.authority!.value,\n colURI: t.col.value,\n treatments: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n cite: new Set(),\n },\n });\n }\n }\n\n if (t.tc && t.tcAuth && t.tcAuth.value) {\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 const colName = authorizedCoLNames.find((e) =>\n t.tcAuth!.value.split(\" / \").includes(e.authority)\n );\n if (colName) {\n colName.authority = t.tcAuth?.value;\n colName.taxonConceptURI = t.tc.value;\n colName.treatments = {\n def,\n aug,\n dpr,\n cite,\n };\n } else if (this.expanded.has(t.tc.value)) {\n // console.log(\"Skipping known\", t.tc.value);\n return;\n } else {\n authorizedTCNames.push({\n displayName,\n authority: t.tcAuth.value,\n taxonConceptURI: t.tc.value,\n treatments: {\n def,\n aug,\n dpr,\n cite,\n },\n });\n }\n\n def.forEach((t) => treatmentPromises.push(t));\n aug.forEach((t) => treatmentPromises.push(t));\n dpr.forEach((t) => treatmentPromises.push(t));\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 displayName,\n rank: json.results.bindings[0].rank!.value,\n taxonNameURI,\n authorizedNames: [...authorizedCoLNames, ...authorizedTCNames],\n colURI: 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.colURI) this.expanded.add(authName.colURI);\n if (authName.taxonConceptURI) this.expanded.add(authName.taxonConceptURI);\n }\n\n const colPromises: Promise[] = [];\n\n if (unathorizedCol) {\n const [acceptedColURI, promises] = await this.getAcceptedCol(\n unathorizedCol,\n name,\n );\n name.acceptedColURI = acceptedColURI;\n colPromises.push(...promises);\n }\n\n await Promise.all(\n authorizedCoLNames.map(async (n) => {\n const [acceptedColURI, promises] = await this.getAcceptedCol(\n n.colURI!,\n name,\n );\n n.acceptedColURI = acceptedColURI;\n colPromises.push(...promises);\n }),\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 await Promise.allSettled(\n [\n ...colPromises,\n ...[...newSynonyms].map(([n, treatment]) =>\n this.getName(n, { searchTerm: false, parent: name, treatment })\n ),\n ],\n );\n }\n\n /** @internal */\n private async getAcceptedCol(\n colUri: string,\n parent: Name,\n ): Promise<[string, 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 return [this.acceptedCol.get(colUri)!, []];\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 [this.acceptedCol.get(colUri)!, promises];\n }\n\n if (!this.acceptedCol.has(colUri)) this.acceptedCol.set(colUri, colUri);\n return [this.acceptedCol.get(colUri)!, 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 // 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 /**\n * The URI of the respective CoL-taxon if it exists\n *\n * Not 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 * Always present if colURI is present, they are the same if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedColURI?: string;\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 /** The URI of the respective `dwcFP:TaxonConcept` if it exists */\n taxonConceptURI?: string;\n\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 * Always present if colURI is present, they are the same if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedColURI?: string;\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 title.append(\" \", 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.colURI) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.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.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.acceptedColURI !== name.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.acceptedColURI !== name.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.acceptedColURI!.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.acceptedColURI!).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.taxonConceptURI) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n const short = authorizedName.taxonConceptURI.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.taxonConceptURI;\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n authName.append(\" \", name_uri);\n }\n if (authorizedName.colURI) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.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.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 = authorizedName.acceptedColURI !== authorizedName.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.acceptedColURI !== authorizedName.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.acceptedColURI!.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.acceptedColURI!).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", "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", "authorizedCoLNames", "authorizedTCNames", "taxonNameURI", "t", "colURI", "def", "aug", "dpr", "cite", "colName", "treats", "authName", "colPromises", "acceptedColURI", "promises", "newSynonyms", "treat", "d", "s", "treatment", "colUri", "parent", "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", "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"] + "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.warn(`!! 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 ?rank ?genus ?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 ?rank ?genus ?subgenus ?species ?infrasp ?name ?authority`;\n\n// For unclear reasons, the queries breaks if the limit is removed.\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 OPTIONAL { ?col (dwc:parent|dwc:acceptedName)* ?p . ?p dwc:rank \"kingdom\" ; dwc:taxonName ?colkingdom . }\n BIND(COALESCE(?colkingdom, \"\") AS ?kingdom)\n OPTIONAL { ?col dwc:infragenericEpithet ?colsubgenus . }\n BIND(COALESCE(?colsubgenus, \"\") AS ?subgenus)\n OPTIONAL {\n ?col dwc:specificEpithet ?species .\n OPTIONAL { ?col dwc:infraspecificEpithet ?infrasp . }\n }\n OPTIONAL { ?col dwc:scientificNameAuthorship ?authority . }\n\n OPTIONAL {\n ?tn dwc:rank ?trank ;\n a dwcFP:TaxonName .\n FILTER(LCASE(?rank) = LCASE(?trank))\n ?tn dwc:kingdom ?kingdom .\n ?tn dwc:genus ?genus .\n\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\n FILTER(?subgenus = COALESCE(?tnsubgenus, \"\"))\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 .\n ?tn dwc:genus ?genus .\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\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 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(?subgenus = 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 .\n OPTIONAL { ?tn dwc:subGenus ?tnsubgenus . }\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 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(?subgenus = 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", "import type { SparqlEndpoint, SparqlJson } from \"./mod.ts\";\nimport * as Queries from \"./Queries.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 * Not that \"weird\" ranks like subGenus 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.colURI === uri) {\n name = n;\n break;\n }\n const an = n.authorizedNames.find((an) =>\n an.taxonConceptURI === uri || an.colURI === 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.colURI === uri) {\n resolve(n);\n return;\n }\n const an = n.authorizedNames.find((an) =>\n an.taxonConceptURI === uri || an.colURI === 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].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: string | undefined;\n\n // there can be multiple CoL-taxa with same latin name, e.g. Leontopodium alpinum has 3T6ZY and 3T6ZX.\n const authorizedCoLNames: AuthorizedName[] = [];\n const authorizedTCNames: 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 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) {\n console.log(\"Duplicate unathorized COL:\", unathorizedCol, colURI);\n }\n unathorizedCol = colURI;\n } else if (!authorizedCoLNames.find((e) => e.colURI === colURI)) {\n if (this.expanded.has(colURI)) {\n console.log(\"Skipping known\", colURI);\n return;\n }\n authorizedCoLNames.push({\n displayName,\n authority: t.authority!.value,\n colURI: t.col.value,\n treatments: {\n def: new Set(),\n aug: new Set(),\n dpr: new Set(),\n cite: new Set(),\n },\n });\n }\n }\n\n if (t.tc && t.tcAuth && t.tcAuth.value) {\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 const colName = authorizedCoLNames.find((e) =>\n t.tcAuth!.value.split(\" / \").includes(e.authority)\n );\n if (colName) {\n colName.authority = t.tcAuth?.value;\n colName.taxonConceptURI = t.tc.value;\n colName.treatments = {\n def,\n aug,\n dpr,\n cite,\n };\n } else if (this.expanded.has(t.tc.value)) {\n // console.log(\"Skipping known\", t.tc.value);\n return;\n } else {\n authorizedTCNames.push({\n displayName,\n authority: t.tcAuth.value,\n taxonConceptURI: t.tc.value,\n treatments: {\n def,\n aug,\n dpr,\n cite,\n },\n });\n }\n\n def.forEach((t) => treatmentPromises.push(t));\n aug.forEach((t) => treatmentPromises.push(t));\n dpr.forEach((t) => treatmentPromises.push(t));\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: [...authorizedCoLNames, ...authorizedTCNames],\n colURI: 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.colURI) this.expanded.add(authName.colURI);\n if (authName.taxonConceptURI) this.expanded.add(authName.taxonConceptURI);\n }\n\n const colPromises: Promise[] = [];\n\n if (unathorizedCol) {\n const [acceptedColURI, promises] = await this.getAcceptedCol(\n unathorizedCol,\n name,\n );\n name.acceptedColURI = acceptedColURI;\n colPromises.push(...promises);\n }\n\n await Promise.all(\n authorizedCoLNames.map(async (n) => {\n const [acceptedColURI, promises] = await this.getAcceptedCol(\n n.colURI!,\n name,\n );\n n.acceptedColURI = acceptedColURI;\n colPromises.push(...promises);\n }),\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 await Promise.allSettled(\n [\n ...colPromises,\n ...[...newSynonyms].map(([n, treatment]) =>\n this.getName(n, { searchTerm: false, parent: name, treatment })\n ),\n ],\n );\n }\n\n /** @internal */\n private async getAcceptedCol(\n colUri: string,\n parent: Name,\n ): Promise<[string, 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 return [this.acceptedCol.get(colUri)!, []];\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 [this.acceptedCol.get(colUri)!, promises];\n }\n\n if (!this.acceptedCol.has(colUri)) this.acceptedCol.set(colUri, colUri);\n return [this.acceptedCol.get(colUri)!, 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 /**\n * The URI of the respective CoL-taxon if it exists\n *\n * Not 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 * Always present if colURI is present, they are the same if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedColURI?: string;\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 /** The URI of the respective `dwcFP:TaxonConcept` if it exists */\n taxonConceptURI?: string;\n\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 * Always present if colURI is present, they are the same if it is the accepted CoL-Taxon.\n *\n * May be the string \"INVALID COL\" if the colURI is not valid.\n */\n acceptedColURI?: string;\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.colURI) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = name.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.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.acceptedColURI !== name.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.acceptedColURI !== name.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.acceptedColURI!.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.acceptedColURI!).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.taxonConceptURI) {\n const name_uri = document.createElement(\"a\");\n name_uri.classList.add(\"taxon\", \"uri\");\n const short = authorizedName.taxonConceptURI.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.taxonConceptURI;\n name_uri.target = \"_blank\";\n name_uri.innerHTML += icons.link;\n authName.append(\" \", name_uri);\n }\n if (authorizedName.colURI) {\n const col_uri = document.createElement(\"a\");\n col_uri.classList.add(\"col\", \"uri\");\n const id = authorizedName.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.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 = authorizedName.acceptedColURI !== authorizedName.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.acceptedColURI !== authorizedName.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.acceptedColURI!.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.acceptedColURI!).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", "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", "authorizedCoLNames", "authorizedTCNames", "taxonNameURI", "t", "colURI", "def", "aug", "dpr", "cite", "colName", "treats", "authName", "colPromises", "acceptedColURI", "promises", "newSynonyms", "treat", "d", "s", "treatment", "colUri", "parent", "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"] } diff --git a/index.ts b/index.ts index ee1f6c3..4a5aee4 100644 --- a/index.ts +++ b/index.ts @@ -333,7 +333,10 @@ class SynoName extends HTMLElement { const rank_badge = document.createElement("span"); rank_badge.classList.add("rank"); rank_badge.innerText = name.rank; - title.append(" ", rank_badge); + const kingdom_badge = document.createElement("span"); + kingdom_badge.classList.add("rank"); + kingdom_badge.innerText = name.kingdom || "Missing Kingdom"; + title.append(" ", kingdom_badge, " ", rank_badge); if (name.taxonNameURI) { const name_uri = document.createElement("a");