-
Notifications
You must be signed in to change notification settings - Fork 1
/
tissueExpressionBAR.min.js
1 lines (1 loc) · 25.1 KB
/
tissueExpressionBAR.min.js
1
const existingStrokeData={};function addTissueMetadata(e){let t,s,a;e.includes("Half_Leaf_Pseudomonas_syringae")&&(e+="_outline"),document.getElementById(createSVGExpressionData.svgObjectName)&&(t=document.getElementById(createSVGExpressionData.svgObjectName),s=t.getElementById(e),a=s.childNodes);const i=2.25;let o,n;if(t&&s){if(s.getAttribute("stroke-width"))o=s.getAttribute("stroke-width"),s.getAttribute("stroke")&&(n=s.getAttribute("stroke"));else if(a.length>0)for(const e of a)"path"===e.nodeName&&(e.getAttribute("stroke-width")&&(o=e.getAttribute("stroke-width")),e.getAttribute("stroke")&&(n=e.getAttribute("stroke")));if(existingStrokeData[e]||(existingStrokeData[e]={},existingStrokeData[e].strokeWidth=o,existingStrokeData[e].strokeColour=n,existingStrokeData[e].addedMetadata=!1),t.getElementById(e)&&!existingStrokeData[e].addedMetadata){existingStrokeData[e].addedMetadata=!0;const n=t.getElementById(e);if(n.getBoundingClientRect()){const e=s.getElementsByTagName("title")?.[0]?.textContent,t=n.getBoundingClientRect().right,a=n.getBoundingClientRect().bottom;e&&t&&a?ePlantPlantEFPChangeTitlePosition(!0,t,a,e):ePlantPlantEFPChangeTitlePosition(!1)}else ePlantPlantEFPChangeTitlePosition(!1);o=Number(o);let l=o*i;const r=i,c=1.125;l>r&&r>o?l=r:l<c&&c>o?l=c:0===l?l=i:l||(l=c);let d=!1;if(n.getAttribute("stroke-width"))t.getElementById(e).setAttribute("stroke-width",l),t.getElementById(e).setAttribute("stroke","#000"),d=!0;else if(a&&a.length>0)for(const e of a)"path"===e.nodeName&&e.getAttribute("stroke-width")&&(e.setAttribute("stroke-width",l),e.getAttribute("stroke")&&e.setAttribute("stroke","#000"),d=!0);d||(t.getElementById(e).setAttribute("stroke-width",l),t.getElementById(e).setAttribute("stroke","#000"))}}}function removeTissueMetadata(e){e.includes("Half_Leaf_Pseudomonas_syringae")&&(e+="_outline");const t="#000";let s,a,i;if(document.getElementById(createSVGExpressionData.svgObjectName)&&(s=document.getElementById(createSVGExpressionData.svgObjectName),a=s.getElementById(e),i=a.childNodes),existingStrokeData[e]&&existingStrokeData[e].addedMetadata)if(existingStrokeData[e].addedMetadata=!1,a&&a.getAttribute("stroke-width"))Number(existingStrokeData[e].strokeWidth)>=0?s.getElementById(e).setAttribute("stroke-width",existingStrokeData[e].strokeWidth):existingStrokeData[e].strokeWidth?s.getElementById(e).setAttribute("stroke-width",1):s.getElementById(e).removeAttribute("stroke-width"),a.getAttribute("stroke")&&(existingStrokeData[e].strokeColour?s.getElementById(e).setAttribute("stroke",existingStrokeData[e].strokeColour):s.getElementById(e).setAttribute("stroke",t));else if(i.length>0)for(const o of i)"path"===o.nodeName&&(o.getAttribute("stroke-width")&&(Number(existingStrokeData[e].strokeWidth)>=0?o.setAttribute("stroke-width",existingStrokeData[e].strokeWidth):existingStrokeData[e].strokeWidth?o.setAttribute("stroke-width",1):s.getElementById(e).removeAttribute("stroke-width")),o.getAttribute("stroke")&&(existingStrokeData[e].strokeColour?o.setAttribute("stroke",existingStrokeData[e].strokeColour):o.setAttribute("stroke",t)));else a.setAttribute("stroke-width",1),a.setAttribute("stroke",t);ePlantPlantEFPChangeTitlePosition(!1)}function debounceTissueMetadata(e,t){let s;return function(...a){const i=this;clearTimeout(s),s=setTimeout((()=>e.apply(i,a)),t)}}function ePlantPlantEFPChangeTitlePosition(e=!1,t=0,s=0,a="",i="ePlant-hover-title-box"){const o=document.getElementById(i);o&&(e?(o.style.display="block",o.style.left=`${t}px`,o.style.top=`${s}px`,o.textContent=a):o.style.display="none")}window.existingStrokeData=existingStrokeData;const ePlantPlantEFPHandleMouseEventData={start:!1,cacheMousePos:{x:null,y:null},startHeight:null,zoomLevel:1};function ePlantPlantEFPHandleMouseEvent(e,t,s,a=1.5){const i=e.firstElementChild;if(i?.viewBox?.baseVal&&(ePlantPlantEFPHandleMouseEventData.startHeight||(ePlantPlantEFPHandleMouseEventData.startHeight=i.viewBox.baseVal.height),"down"===t&&!ePlantPlantEFPHandleMouseEventData.start&&window.getSelection()&&window.getSelection().isCollapsed&&(s.preventDefault(),ePlantPlantEFPHandleMouseEventData.start=!0,ePlantPlantEFPHandleMouseEventData.cacheMousePos={x:s.clientX,y:s.clientY}),"move"===t&&ePlantPlantEFPHandleMouseEventData.start)){s.preventDefault();const e=i.viewBox.baseVal.height?window.innerHeight/i.viewBox.baseVal.height/a:a,t=-(s.clientX-ePlantPlantEFPHandleMouseEventData.cacheMousePos.x)/e,o=-(s.clientY-ePlantPlantEFPHandleMouseEventData.cacheMousePos.y)/e,n=.95;let l=i.height.baseVal.value?(100*n-i.height.baseVal.value/i.viewBox.baseVal.height)/100:(100*n-window.innerHeight/i.viewBox.baseVal.height)/100;(l<=0||l>=1)&&(l=n);let r=i.width.baseVal.value?(100*n-i.width.baseVal.value/i.viewBox.baseVal.width)/100:(100*n-window.innerWidth/i.viewBox.baseVal.height)/100;(r<=0||r>=1)&&(r=n);const c=1/ePlantPlantEFPHandleMouseEventData.zoomLevel==1?n:1/ePlantPlantEFPHandleMouseEventData.zoomLevel,d=i.viewBox.baseVal.width*l*c,h=i.viewBox.baseVal.width*l,f=i.viewBox.baseVal.height*r,p=f*c;ePlantPlantEFPHandleMouseEventData.cacheMousePos={x:s.clientX,y:s.clientY},i.viewBox.baseVal.y+o<=p&&i.viewBox.baseVal.y+o>=-f?i.viewBox.baseVal.y+=o:i.viewBox.baseVal.y=i.viewBox.baseVal.y+o>0?p:-f,i.viewBox.baseVal.x+t<=d&&i.viewBox.baseVal.x+t>=-h?i.viewBox.baseVal.x+=t:i.viewBox.baseVal.x=i.viewBox.baseVal.x+t>0?d:-h}"up"===t&&(ePlantPlantEFPHandleMouseEventData.start=!1)}function ePlantPlantEFPHandleMouseWheel(e,t,s=3){const a=e.firstElementChild,i=a.viewBox.baseVal,o=t.deltaY>0,n=ePlantPlantEFPHandleMouseEventData.startHeight?window.innerHeight/ePlantPlantEFPHandleMouseEventData.startHeight/s:s;window.getSelection()&&window.getSelection().isCollapsed&&i&&t.deltaY&&ePlantPlantEFPHandleMouseEventData.start&&(t.preventDefault(),o?(a.viewBox.baseVal.width=i.width*n,a.viewBox.baseVal.height=i.height*n,ePlantPlantEFPHandleMouseEventData.zoomLevel*=n):(a.viewBox.baseVal.width=i.width/n,a.viewBox.baseVal.height=i.height/n,ePlantPlantEFPHandleMouseEventData.zoomLevel/=n))}class CreateSVGExpressionData{constructor(){this.eFPObjects={},this.sampleData={},this.sampleOptions=[],this.sampleReadableName={},this.topExpressionValues={},this.expressionValues={},this.topExpressionOptions=["Microarray","RNA-seq"],this.localStorageTop=!1,this.localStorageSample={},this.desiredDOMid="",this.appendSVG,this.clickList=[],this.svgValues={},this.svgMax=0,this.svgMin=0,this.svgMaxAverage=0,this.svgMaxAverageSample="",this.svgMinAverage=0,this.svgMinAverageSample="",this.svgObjectName="",this.svgContainerHeight="95vh"}verifyLoci(e){if("string"==typeof e){const t=new RegExp("^[A][T][MC0-9][G][0-9]{5}[.][0-9]{1,2}$|^[A][T][MC0-9][G][0-9]{5}$","i");return Boolean(e.trim().match(t))}return!1}generateSVG(e="AT3G24650",t,s="default",a=!0,i){this.verifyLoci(e.trim())?(this.svgValues={},this.svgMax=void 0,this.svgMin=void 0,this.svgMaxAverage=void 0,this.svgMaxAverageSample=void 0,this.svgMinAverage=void 0,this.svgMinAverageSample=void 0,this.includeDropdownAll=a,!1===this.clickList.includes(s)&&this.clickList.push(s),i&&"string"==typeof i?this.svgContainerHeight=i.toString():i&&"number"==typeof i&&(this.svgContainerHeight=`${i.toString()}px`),this.desiredDOMid=t,this.#e(s,e.trim().toUpperCase())):console.error(`Invalid locus: ${e.trim()}`)}async#e(e,t="AT3G24650"){let s=0,a=localStorage.getItem("bar_eplant-top-expression-values"),i=!0;if(this.localStorageTop||a&&(a=JSON.parse(a),(a.expiry&&(new Date).getTime()-a.expiry<=6048e5||a[t])&&(i=!1),this.topExpressionValues={...this.topExpressionValues,...a},this.localStorageTop=!0),this.topExpressionValues[t]&&(i=!1),i)for(const o of this.topExpressionOptions){const n=`https://bar.utoronto.ca/expression_max_api/max_average?method=${o}`,l="application/json";let r={loci:[t.toUpperCase()],method:o};r=JSON.stringify(r);const c={mode:"cors",method:"POST"};l&&(c.headers={},c.headers["Content-type"]=l),c.body=r,await fetch(n,c).then((async o=>{200===o.status?await o.text().then((async o=>{let l,r;l=o.length>0?JSON.parse(o):{};const c=n.split("=");if(c.length>1&&(r=c[1]),r&&l&&!0===l.wasSuccessful&&l.maxAverage){const e={};e[r]={},e[r].maxAverage=l.maxAverage[t.toUpperCase()],l.standardDeviation&&(e[r].standardDeviation=l.standardDeviation[t.toUpperCase()]),l.sample&&(e[r].sample=l.sample[t.toUpperCase()]),l.compendium&&(e[r].compendium=l.compendium[t.toUpperCase()]),this.topExpressionValues||(this.topExpressionValues={}),this.topExpressionValues[t]={...this.topExpressionValues[t],...e}}if(s+=1,s===this.topExpressionOptions.length){if(!a||i?(a={},a[t]={...this.topExpressionValues[t]},a.expiry=(new Date).getTime()):a[t]={...this.topExpressionValues[t]},a&&Object.keys(a).length>10)for(const e in a)if(e!==t&&"expiry"!==e){delete a[e];break}a&&(localStorage.setItem("bar_eplant-top-expression-values",JSON.stringify(a)),this.localStorageTop=!0),await this.#t(e,t)}})):200!==o.status&&(s+=1,s===this.topExpressionOptions.length&&await this.#t(e,t),console.error(`fetch error - Status Code: ${o.status}, fetch-url: ${o.url}, document-url: ${window.location.href}`))})).catch((async a=>{s+=1,s===this.topExpressionOptions.length&&await this.#t(e,t),console.error(a)}))}else Object.keys(this.topExpressionValues[t]).length>0?await this.#t(e,t):Object.keys(a[t]).length>0&&(this.topExpressionValues||(this.topExpressionValues={}),this.topExpressionValues[t]=a[t],await this.#t(e,t))}async#t(e,t){if(0===Object.keys(this.sampleData).length){let s=!0,a=localStorage?.getItem("bar_eplant-sample-data-storage");if(a&&(a=JSON.parse(a),a.expiry&&a.data&&(new Date).getTime()-a.expiry<=6048e5&&(s=!1,this.sampleData=a.data)),s){const e="https://raw.githubusercontent.com/BioAnalyticResource/ePlant_Plant_eFP/master/data/SampleData.min.json",t={mode:"cors"};await fetch(e,t).then((async e=>{200===e.status?await e.text().then((async e=>{const t=e.length>0?JSON.parse(e):{};this.sampleData=t;const s={data:t,expiry:(new Date).getTime()};localStorage.setItem("bar_eplant-sample-data-storage",JSON.stringify(s))})):200!==e.status&&console.error(`fetch error - Status Code: ${e.status}, fetch-url: ${e.url}, document-url: ${window.location.href}`)})).catch((async e=>{console.error(e)}))}await this.#s(e,t)}else Object.keys(this.sampleData).length>0&&await this.#s(e,t)}async#s(e,t){if(".svg"===e.substring(-4)&&(e=e.substring(0,e.length-4)),0===this.sampleOptions.length)for(const[r,c]of Object.entries(this.sampleData))this.sampleOptions.push(r),this.sampleReadableName[c.name]=r;const s=Object.keys(this.sampleData);let a="",i=[],o=[];if(await this.#a(),!s.includes(e)&&this.topExpressionValues[t]){let a,i=0;for(const[,e]of Object.entries(this.topExpressionValues[t]))e.compendium&&e.compendium[1]&&s.includes(e.compendium[1])&&e.maxAverage&&e.maxAverage[1]&&e.maxAverage[1]>i&&(i=e.maxAverage[1],a=e.compendium[1]);e=a||"AbioticStress"}"default"===e&&(e="AbioticStress");const n=this.sampleData[e];let l;if(n&&n.sample&&(l=n.sample),n&&n.db&&(a=n.db),void 0!==a){o=Object.keys(n.sample),i=[];for(const e of o)i=i.concat(l[e])}this.eFPObjects[e]&&this.eFPObjects[e].locusCalled.includes(t)?this.eFPObjects[e]&&await this.#i(e,t,this.includeDropdownAll):await this.#o(a,t,i,e,l)}async#a(){if(0===Object.keys(this.localStorageSample).length){let e=localStorage.getItem("bar_eplant-efp-data");if(e&&(e=JSON.parse(e),this.localStorageSample=e,await this.#n(),!(e.expiry&&(new Date).getTime()-e.expiry<=6048e5)))if(0===Object.keys(this.eFPObjects).length)this.eFPObjects=e;else for(const[t,s]of Object.entries(e))if("expiry"!==t)if(this.eFPObjects[t]){const e=[];for(const a of s.locusCalled)this.eFPObjects[t].locusCalled.includes(a)||e.push(a);if(e.length>0)for(const[a,i]of Object.entries(s.sample))if(this.eFPObjects[t].sample[a])for(const s of e)this.eFPObjects[t].sample[a][s]||(this.eFPObjects[t].sample[a][s]=i[s]);else this.eFPObjects[t].sample[a]=i}else this.eFPObjects[t]=s}}async#n(e){if(2*JSON.stringify(this.localStorageSample).length>1e6)for(const[t,s]of Object.entries(this.eFPObjects))if(t!==e&&"expiry"!==t){delete this.eFPObjects[t];break}}async#o(e,t,s,a,i){let o="https://bar.utoronto.ca/~asullivan/webservices/plantefp.cgi?";o+=`datasource=${e}&`,o+=`id=${t}&`,o+="samples=[";for(let r=0;r<s.length;r+=1){let e=s[r].trim();e=e.replace(/\+/g,"%2B"),e=e.replace(/ /g,"%20"),o+=`"${e}"`,r!==s.length-1&&(o+=",")}o+="]";const n={mode:"cors"};let l=!1;this.eFPObjects?.[a]?.[t]?.includes("locus")&&(l=!0),i&&!l?await fetch(o,n).then((async s=>{200===s.status?await s.text().then((async s=>{let o;o=s.length>0?JSON.parse(s):{};const n=Object.keys(i);void 0===this.eFPObjects&&(this.eFPObjects={}),void 0===this.eFPObjects[a]&&(this.eFPObjects[a]={}),void 0===this.eFPObjects[a].sample&&(this.eFPObjects[a].sample={}),void 0===this.eFPObjects[a].sample&&(this.eFPObjects[a].sample={});for(const e of o){const s=e.name.trim(),o=e.value;let l="",r=s;r=s.replace(/%2B/g,"+"),r=r.replace(/%20/g," "),r=r.trim();for(const e of n)i[e].includes(r)&&(l=e,void 0===this.eFPObjects[a].sample[l]&&(this.eFPObjects[a].sample[l]={}),void 0===this.eFPObjects[a].sample[l][r]&&(this.eFPObjects[a].sample[l][r]={}),this.eFPObjects[a].sample[l][r][t]=o,this.eFPObjects[a].locusCalled||(this.eFPObjects[a].locusCalled=[]),this.eFPObjects[a].locusCalled.includes(t)||this.eFPObjects[a].locusCalled.push(t))}this.eFPObjects[a].db=e,this.localStorageSample&&0!==Object.keys(this.localStorageSample)?.length?this.localStorageSample[a]=this.eFPObjects[a]:(this.localStorageSample=this.eFPObjects,this.localStorageSample.expiry=(new Date).getTime()),await this.#n(a),localStorage.setItem("bar_eplant-efp-data",JSON.stringify(this.localStorageSample)),await this.#i(a,t,this.includeDropdownAll)})):200!==s.status&&(await this.#i(a,t,this.includeDropdownAll),console.error(`fetch error - Status Code: ${s.status}, fetch-url: ${s.url}, document-url: ${window.location.href}`))})).catch((async e=>{await this.#i(a,t,this.includeDropdownAll),console.error(e)})):(await this.#i(a,t,this.includeDropdownAll),console.error(`sampleSubunits is ${i}`))}async#i(e,t,s=!1){let a="Klepikova",i=(new DOMParser).parseFromString('<div class="expressionContainer"></div>',"text/html");if(i=i.querySelector(".expressionContainer"),""!==e&&(a=e),s&&this.sampleOptions){let a=0,o=0,n="";if(this.topExpressionValues[t]&&Object.keys(this.topExpressionValues[t]).length>0){n+='<option\n value="hiddenOption"\n id="hiddenExpressionOption"\n disabled="true"\n >\n Compendiums with maximum average expression:\n </option>',o+=1;const e=Object.keys(this.topExpressionValues[t]);for(const s of e)if(this.topExpressionValues[t][s]){const e=this.topExpressionValues[t][s],a=e.compendium;for(let t=0;t<Object.keys(a).length;t+=1){const a=t+1;if(e.compendium[a]){const t=e.compendium[a],i=e.sample[a];if(i&&this.sampleData[t]&&this.sampleData[t]&&this.sampleData[t].description){const l=this.sampleData[t].description[i],r=e.maxAverage[a];n+=`<option\n value="${t}"\n >\n ${this.sampleData[t].name}: ${l} at ${r} (${s})\n </option>`,o+=1;break}}}}}n+='<option\n value="hiddenOption"\n id="allCompendiumOptions"\n disabled="true"\n >\n All compendiums:\n </option>',o+=1;const l=Object.keys(this.sampleReadableName);l.sort();for(const t in l)l[t]&&(n+=`<option\n value="${this.sampleReadableName[l[t]]}"\n >\n ${l[t]}\n </option>`,this.sampleReadableName[l[t]]===e&&(a=parseInt(o,10)+parseInt(t,10)));const r=(new DOMParser).parseFromString(`<div class="selectSVGContainer">\n <span>Select SVG to display:</span>\n <select\n onchange="window.createSVGExpressionData.generateSVG('${t}', '${this.desiredDOMid}', this?.value?.toString()?.length > 0 ? this.value.toString() : 'default', ${s})"\n id="sampleOptions"\n value="${e}"\n style="width: 100%; max-width: 40em;"\n class="selectCompendiumOptions"\n\t\t\t\t\t\taria-label="Select SVG to display"\n >\n ${n}\n </select>\n </div>`,"text/html").body.childNodes[0];r.getElementsByTagName("select")[0].selectedIndex=a,i.appendChild(r)}const o=(new DOMParser).parseFromString('<div\n id="ePlant-hover-title-box"\n style="\n position: fixed;\n z-index: 100;\n color: #fff;\n background-color: #000;\n border: 1px solid #000;\n border-radius: 3px;\n padding: 5px;\n opacity: 0.85;\n white-space: pre-line;\n display: none;\n "\n >Test</div>',"text/html").body.childNodes[0];i.appendChild(o);const n=`https://bar.utoronto.ca/~asullivan/ePlant_Plant_eFP/compendiums/${a}.svg`;if(await fetch(n,{mode:"cors"}).then((async e=>{200===e.status?await e.text().then((async e=>{const s=(new DOMParser).parseFromString(e,"text/html").body.childNodes[0];s.id&&(this.svgObjectName=s.id,s.style="width: 100% !important; height: 100% !important;");const o=(new DOMParser).parseFromString(`<div id="${a}_object" style="height:${this.svgContainerHeight};"\n onMouseDown="ePlantPlantEFPHandleMouseEvent(${a}_object, 'down', event)"\n onMouseMove="ePlantPlantEFPHandleMouseEvent(${a}_object, 'move', event)"\n onMouseUp="ePlantPlantEFPHandleMouseEvent(${a}_object, 'up', event)"\n onMouseLeave="ePlantPlantEFPHandleMouseEvent(${a}_object, 'up', event)"\n onWheel="ePlantPlantEFPHandleMouseWheel(${a}_object, event)"\n ></div>`,"text/html").body.childNodes[0];o.appendChild(s),i.appendChild(o),this.appendSVG=i,await this.#l(a,t)})):200!==e.status&&console.error(`fetch error - Status Code: ${e.status}, fetch-url: ${e.url}, document-url: ${window.location.href}`)})).catch((async e=>{console.error(e)})),this.desiredDOMid&&this.desiredDOMid.length>0){const e=document.getElementById(this.desiredDOMid);if(e){if(e.childNodes&&e.childNodes.length>0){const t=e.childNodes;for(const s in t)t[s].className&&t[s].className.includes("expressionContainer")&&e.removeChild(t[s])}e.appendChild(this.appendSVG)}}}async#l(e,t){const s=t;let a="";for(let i=0;i<s.length;i+=1)a+=1===i||3===i?s[i].toLowerCase():s[i];await this.#r(e,t)}async#r(e,t){const s=this.eFPObjects[e].sample,a=Object.keys(s);for(const i of a){const e=Object.keys(s[i]);void 0===this.svgValues[i]&&(this.svgValues[i]={});for(const a of e)void 0===this.svgValues[i].rawValues&&(this.svgValues[i].rawValues=[]),this.svgValues[i].rawValues.push(s[i][a][t])}await this.#c(e,a)}async#c(e,t){this.svgMax=void 0,this.svgMin=void 0;for(const s of t){const t=this.svgValues[s].rawValues.sort(),a=[];for(const e of t)!1===Number.isNaN(e)&&a.push(parseFloat(e));let i=0;for(const e of a)i+=e;const o=i/a.length,n=a[a.length-1],l=a[1];(!this.svgMax||n>this.svgMax)&&(this.svgMax=n),(!this.svgMin||l<this.svgMin)&&(this.svgMin=l),(!this.svgMaxAverage||o>this.svgMaxAverage)&&(this.svgMaxAverage=o,this.svgMaxAverageSample=s),(!this.svgMinAverage||o<this.svgMinAverage)&&(this.svgMinAverage=o,this.svgMinAverageSample=s),this.svgValues[s]||(this.svgValues[s]={}),this.svgValues[s].average=o,this.svgValues[s].sd=this.#d(a);const r=this.sampleData[e],c=Object.keys(r.controlComparison);if(!1===c.includes(s)){let e="";for(const t of c)r.controlComparison[t].includes(s)&&(e=t);if(this.svgValues[e]&&this.svgValues[e].rawValues){const t=this.svgValues[e].rawValues;let a=0;for(const e of t)a+=parseFloat(e);const i=a/t.length;let n=0,l=0;if(null!==i&&i>0&&o>0){o>i?(n=o-i,this.svgValues[s].inductionValue=n):i>o&&(l=i-o,this.svgValues[s].reductionValue=l);const t=o/i;this.svgValues[s].expressionRatio=t,this.svgValues[s].controlSampleName=e,this.svgValues[s].controlAverage=i}}}}await this.#h(e,t)}#d(e){let t=0;const s=e.length;if(s>=1){let a=0,i=0;for(let t=0;t<s;t+=1)i+=e[t];const o=i/s;for(let t=0;t<s;t+=1)a+=(e[t]-o)**2;t=Math.sqrt(a/s)}return t}async#h(e,t){for(const s of t){const t=this.svgMaxAverage;let a=this.svgValues[s].average;a<0&&(a=0);let i=null;t&&t>=0&&(i=a/t*100),i>100?i=100:i<0&&(i=0);const o=this.percentageToColour(i),n=parseFloat(a).toFixed(3),l=this.svgValues[s].rawValues.length;this.svgValues[s].expressionLevel=n,this.svgValues[s].sampleSize=l,await this.#f(e,s,o,n,l)}}percentageToColour(e){const t=parseInt(e,10);if(t>=0){return["#ffff00","#fffc00","#fff900","#fff700","#fef400","#fff200","#ffef00","#feed00","#ffea00","#ffe800","#ffe500","#ffe200","#ffe000","#ffdd00","#ffdb00","#ffd800","#ffd600","#fed300","#ffd100","#ffce00","#ffcc00","#ffc900","#ffc600","#ffc400","#ffc100","#ffbf00","#ffbc00","#ffba00","#ffb700","#feb500","#ffb200","#ffaf00","#ffad00","#ffaa00","#ffa800","#ffa500","#ffa300","#ffa000","#ff9e00","#ff9b00","#ff9900","#ff9600","#ff9300","#ff9100","#ff8e00","#ff8c00","#ff8900","#ff8700","#ff8400","#ff8200","#ff7f00","#ff7c00","#ff7a00","#ff7700","#ff7500","#ff7200","#ff7000","#ff6d00","#ff6b00","#ff6800","#ff6600","#ff6300","#ff6000","#ff5e00","#ff5b00","#ff5900","#ff5600","#ff5400","#ff5100","#ff4f00","#ff4c00","#ff4900","#ff4700","#ff4400","#ff4200","#ff3f00","#ff3d00","#ff3a00","#ff3800","#ff3500","#ff3200","#ff3000","#ff2d00","#ff2b00","#ff2800","#ff2600","#ff2300","#ff2100","#ff1e00","#ff1c00","#ff1900","#ff1600","#ff1400","#ff1100","#ff0f00","#ff0c00","#ff0a00","#ff0700","#ff0500","#ff0200","#ff0000"][t]}return"#808080"}async#f(e,t,s,a,i=1){const o=this.appendSVG.lastElementChild.getElementsByTagName("svg")[0],n=[...o.getElementsByTagName("path"),...o.getElementsByTagName("g")];if(o&&n.length>0){const o=createSVGExpressionData.svgValues[t];let l;this.sampleData[e].description&&(l=this.sampleData[e].description[t]),void 0!==l&&""!==l||(l=t);const r=["Control_Shoot_0_Hour","Cold_Shoot_0_Hour","Osmotic_Shoot_0_Hour","Salt_Shoot_0_Hour","Drought_Shoot_0_Hour","Genotoxic_Shoot_0_Hour","Oxidative_Shoot_0_Hour","UV-B_Shoot_0_Hour","Wounding_Shoot_0_Hour","Heat_Shoot_0_Hour"],c=["Control_Root_0_Hour","Cold_Root_0_Hour","Osmotic_Root_0_Hour","Salt_Root_0_Hour","Drought_Root_0_Hour","Genotoxic_Root_0_Hour","Oxidative_Root_0_Hour","UV-B_Root_0_Hour","Wounding_Root_0_Hour","Heat_Root_0_Hour"];let d,h=!1,f=!1;r.includes(t)?h=!0:c.includes(t)&&(f=!0);for(const e in n)n[e].id===t&&(d=n[e]);if(d&&d.childNodes.length>0){const e=d.childNodes;let t=!1;for(const a in e)"path"!==e[a].tagName&&"g"!==e[a].tagName||(e[a].setAttribute("fill",s),t=!0);t||d.setAttribute("fill",s)}else d&&d.setAttribute("fill",s);if(d){d.setAttribute("class","hoverDetails"),d.addEventListener("mouseenter",(e=>{window.requestAnimationFrame((()=>{debounceTissueMetadata(addTissueMetadata(e.target.id),250)}))})),d.addEventListener("mouseleave",(e=>{window.requestAnimationFrame((()=>{debounceTissueMetadata(removeTissueMetadata(e.target.id),250)}))})),d.setAttribute("data-expressionValue",a),d.setAttribute("data-sampleSize",i),d.setAttribute("data-standardDeviation",o.sd),d.setAttribute("data-sampleSize",i);const t=document.createElementNS("https://www.w3.org/2000/svg","title");t&&(t.textContent=`${l}\r\nExpression level: ${a}\r\nSample size: ${i}\r\nStandard Deviation: ${parseFloat(o.sd).toFixed(3)}`);if(!0===!1){let s;d.setAttribute("data-expressionRatio",o.expressionRatio),t.textContent+=`\r\nExpression Ratio: ${parseFloat(o.expressionRatio).toFixed(3)}`,d.setAttribute("data-controlSampleName",o.controlSampleName),this.sampleData[e].description&&(s=this.sampleData[e].description[o.controlSampleName]),void 0!==s&&""!==s||(s=o.controlSampleName),t.textContent+=`\r\nControl Sample Name: ${s}`,d.setAttribute("data-controlAverage",o.controlAverage),t.textContent+=`\r\nControl Expression: ${parseFloat(o.controlAverage).toFixed(3)}`}d.appendChild(t)}if(h){for(const e in r)if(r[e]){let t;for(const s in n)n[s].id===r[e]&&(t=n[s]);if(t){t.setAttribute("class","hoverDetails"),t.addEventListener("mouseenter",(function(e){addTissueMetadata(this.id)}),{passive:!0}),t.addEventListener("mouseleave",(function(e){removeTissueMetadata(this.id)}),{passive:!0});const o=t.childNodes;if(o.length>0){let e=!1;for(const t of o)"path"===t.tagName&&(t.setAttribute("fill",s),e=!0);e||t.setAttribute("fill",s)}else t.setAttribute("fill",s);const n=document.createElementNS("https://www.w3.org/2000/svg","title");n&&(n.textContent=`${r[e]}\r\nExpression level: ${a}\r\nSample size: ${i}`,t.appendChild(n))}}}else if(f)for(const e in c)if(c[e]){let t;for(const s in n)n[s].id===c[e]&&(t=n[s]);if(t){t.setAttribute("class","hoverDetails"),t.addEventListener("mouseenter",(function(e){addTissueMetadata(this.id)}),{passive:!0}),t.addEventListener("mouseleave",(function(e){removeTissueMetadata(this.id)}),{passive:!0});const o=t.childNodes;if(o.length>0){let e=!1;for(const t of o)"path"===t.tagName&&(t.setAttribute("fill",s),e=!0);e||t.setAttribute("fill",s)}else t.setAttribute("fill",s);const n=document.createElementNS("https://www.w3.org/2000/svg","title");n&&(n.textContent=`${c[e]}\r\nExpression level: ${a}\r\nSample size: ${i}`,t.appendChild(n))}}}}}const createSVGExpressionData=new CreateSVGExpressionData;window.createSVGExpressionData=createSVGExpressionData;