@sjcrh/proteinpaint-client 2.185.0 → 2.186.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/2dmaf-F5QNP7AQ.js +1371 -0
- package/dist/AIProjectAdmin-ROSQHK6Q.js +827 -0
- package/dist/AIProjectAdmin-ROSQHK6Q.js.map +7 -0
- package/dist/AppHeader-STVCDLET.js +833 -0
- package/dist/BoxPlot-CU7MEBH7.js +1217 -0
- package/dist/CorrelationVolcano-OE4R2GS3.js +617 -0
- package/dist/DE-SR7PJPKI.js +93 -0
- package/dist/DEinput-PRIAIBFH.js +299 -0
- package/dist/DEinput-PRIAIBFH.js.map +7 -0
- package/dist/DifferentialAnalysis-UWTYK7NU.js +241 -0
- package/dist/Disco-IL6REGSA.js +3235 -0
- package/dist/Disco.UI-JHHLS5BA.js +242 -0
- package/dist/DmrPlot-DDP53T3F.js +640 -0
- package/dist/GB-F4LMYMHF.js +1127 -0
- package/dist/GB-F4LMYMHF.js.map +7 -0
- package/dist/GeneExpInput-ZWBC226P.js +363 -0
- package/dist/GeneExpInput-ZWBC226P.js.map +7 -0
- package/dist/HicApp-RVFHTYED.js +2248 -0
- package/dist/NumBinaryEditor-B3FXQAOH.js +268 -0
- package/dist/NumBinaryEditor.unit.spec-75YQJ2U6.js +284 -0
- package/dist/NumContEditor-5PYW3OLY.js +105 -0
- package/dist/NumContEditor.unit.spec-F7ZRDGBN.js +167 -0
- package/dist/NumCustomBinEditor-TBT6GLYQ.js +36 -0
- package/dist/NumCustomBinEditor.unit.spec-6YHU45XV.js +282 -0
- package/dist/NumDiscreteEditor-N6OJYSJA.js +177 -0
- package/dist/NumDiscreteEditor.unit.spec-HQS5RZ6R.js +200 -0
- package/dist/NumRegularBinEditor-HSDDKVNG.js +36 -0
- package/dist/NumRegularBinEditor.unit.spec-33KN2MVM.js +225 -0
- package/dist/NumSplineEditor-XERKOACS.js +190 -0
- package/dist/NumSplineEditor.unit.spec-MPVM6KSC.js +197 -0
- package/dist/NumericDensity-35EKYW3V.js +36 -0
- package/dist/NumericDensity.unit.spec-OR24PPRJ.js +219 -0
- package/dist/NumericHandler-D6ZNGRE3.js +37 -0
- package/dist/NumericHandler.unit.spec-EKPGVSXI.js +217 -0
- package/dist/RunChart2-7DOXOFXV.js +756 -0
- package/dist/SC-APZRV4H6.js +826 -0
- package/dist/SC-APZRV4H6.js.map +7 -0
- package/dist/Volcano-X4ZWK644.js +1344 -0
- package/dist/Volcano-X4ZWK644.js.map +7 -0
- package/dist/WSIViewer-E247ELKN.js +47971 -0
- package/dist/WsiSamplesPlot-3522VRB5.js +163 -0
- package/dist/adSandbox-IDFY5P2P.js +36 -0
- package/dist/alphaGenome-F3W7GJQ5.js +173 -0
- package/dist/app-2HDSFMRM.js +47 -0
- package/dist/app-LIWPFL7C.js +35 -0
- package/dist/app.js +10 -10
- package/dist/bam-TBHHSATL.js +857 -0
- package/dist/barchart-HHFCBOZE.js +45 -0
- package/dist/barchart.events-UQUSSRXB.js +45 -0
- package/dist/barchart.integration.spec-OF3MWFQ5.js +1675 -0
- package/dist/barchart2-XRMPCBBU.js +309 -0
- package/dist/block-5UEORHFB.js +6200 -0
- package/dist/block.init-QSSFUVIT.js +36 -0
- package/dist/block.mds.expressionrank-VBIIJHQF.js +357 -0
- package/dist/block.mds.geneboxplot-KSBHXBNX.js +826 -0
- package/dist/block.mds.junction-FWZWMZJ2.js +1543 -0
- package/dist/block.mds.svcnv-UXORVLH2.js +6799 -0
- package/dist/block.svg-6KIGW4QH.js +162 -0
- package/dist/block.tk.aicheck-DK566Q4C.js +281 -0
- package/dist/block.tk.ase-2GB2VJJ6.js +363 -0
- package/dist/block.tk.bam-RQNOLY52.js +1904 -0
- package/dist/block.tk.bedgraphdot-N4YMZFO4.js +382 -0
- package/dist/block.tk.bigwig.ui-4S7L7D7D.js +209 -0
- package/dist/block.tk.hicstraw-AHFNQKCS.js +821 -0
- package/dist/block.tk.junction-7E6SNQMQ.js +2362 -0
- package/dist/block.tk.junction.textmatrixui-3C5JVYX5.js +197 -0
- package/dist/block.tk.ld-TOUCLT3W.js +97 -0
- package/dist/block.tk.menu-JCV5ORD6.js +1027 -0
- package/dist/block.tk.pgv-CUU22U6M.js +942 -0
- package/dist/brainImaging-MTQTXNNL.js +421 -0
- package/dist/chunk-2UYBBUXK.js +293 -0
- package/dist/chunk-2VPEFXEJ.js +4207 -0
- package/dist/chunk-2YC6ZVE4.js +20377 -0
- package/dist/chunk-2YC6ZVE4.js.map +7 -0
- package/dist/chunk-37MD3Y5G.js +1230 -0
- package/dist/chunk-37MD3Y5G.js.map +7 -0
- package/dist/chunk-3QHIL3V3.js +55 -0
- package/dist/chunk-44VXWKYJ.js +129 -0
- package/dist/chunk-52D6EGUS.js +95 -0
- package/dist/chunk-5FHM3L4I.js +102 -0
- package/dist/chunk-62TF2MCH.js +142 -0
- package/dist/chunk-67QM2NUK.js +6364 -0
- package/dist/chunk-6AAPHEWK.js +676 -0
- package/dist/chunk-6KPGMUHS.js +153 -0
- package/dist/chunk-6WBIZXNI.js +455 -0
- package/dist/chunk-7AAJVXEG.js +302 -0
- package/dist/chunk-AFJRAR4N.js +1271 -0
- package/dist/chunk-BBNO6JLO.js +200 -0
- package/dist/chunk-BBNO6JLO.js.map +7 -0
- package/dist/chunk-CVRYZMDE.js +148 -0
- package/dist/chunk-DGUTCYH2.js +276 -0
- package/dist/chunk-DHNXATHC.js +158 -0
- package/dist/chunk-DXHATYHE.js +180 -0
- package/dist/chunk-DXHATYHE.js.map +7 -0
- package/dist/chunk-E3BI23UK.js +229 -0
- package/dist/chunk-E4JDHA3C.js +621 -0
- package/dist/chunk-FOJWYEGV.js +228 -0
- package/dist/chunk-FTN7Y34O.js +158 -0
- package/dist/chunk-GAOUV4ID.js +1943 -0
- package/dist/chunk-GAOUV4ID.js.map +7 -0
- package/dist/chunk-GRG5MMPN.js +2815 -0
- package/dist/chunk-GSU4PZN3.js +482 -0
- package/dist/chunk-I55NLUCQ.js +1823 -0
- package/dist/chunk-I55NLUCQ.js.map +7 -0
- package/dist/chunk-IIRU2JLK.js +217 -0
- package/dist/chunk-JCB74ZSK.js +272 -0
- package/dist/chunk-JUDWPYMA.js +824 -0
- package/dist/chunk-KT6VZBC7.js +1087 -0
- package/dist/chunk-L2HBHFTK.js +2370 -0
- package/dist/chunk-LKADRF3Q.js +368 -0
- package/dist/chunk-MAXFRUGM.js +407 -0
- package/dist/chunk-MQN7RYCK.js +37 -0
- package/dist/chunk-OEUI4CYZ.js +470 -0
- package/dist/chunk-OM36XUQL.js +34 -0
- package/dist/chunk-P5LNIH5X.js +54 -0
- package/dist/chunk-PG62PRMF.js +102 -0
- package/dist/chunk-Q3J3F2NU.js +205 -0
- package/dist/chunk-RYCOJY7M.js +188 -0
- package/dist/chunk-RYCOJY7M.js.map +7 -0
- package/dist/chunk-RZBV6474.js +117 -0
- package/dist/chunk-T5V4OC27.js +442 -0
- package/dist/chunk-TXJG4N6S.js +4992 -0
- package/dist/chunk-TXJG4N6S.js.map +7 -0
- package/dist/chunk-UCKSUNSJ.js +335 -0
- package/dist/chunk-W4TLYHZO.js +514 -0
- package/dist/chunk-WPZUXKIB.js +56 -0
- package/dist/chunk-XM47XD6G.js +215 -0
- package/dist/chunk-XVA3UOWD.js +263 -0
- package/dist/chunk-XVA3UOWD.js.map +7 -0
- package/dist/chunk-YIMRBXQK.js +1210 -0
- package/dist/chunk-YIMRBXQK.js.map +7 -0
- package/dist/chunk-YL7VT4QT.js +1159 -0
- package/dist/chunk-YL7VT4QT.js.map +7 -0
- package/dist/chunk-YWBUK4B7.js +291 -0
- package/dist/chunk-YWBUK4B7.js.map +7 -0
- package/dist/chunk-YZHGLSKQ.js +50 -0
- package/dist/chunk-ZGOOZK3I.js +203 -0
- package/dist/chunk-ZH2VP6Q6.js +95 -0
- package/dist/chunk-ZLOQXO5K.js +14 -0
- package/dist/chunk-ZMNDBPJU.js +100 -0
- package/dist/chunk-ZRTW6X3F.js +2784 -0
- package/dist/chunk-ZTT52MBP.js +2681 -0
- package/dist/condition-VUACUQYF.js +330 -0
- package/dist/controls-N4MPSNO4.js +39 -0
- package/dist/controls.config-PRXVODCM.js +37 -0
- package/dist/correlation-QJZUYDFH.js +96 -0
- package/dist/cuminc-JJHXW55V.js +1147 -0
- package/dist/cuminc.integration.spec-IXS2UO2O.js +676 -0
- package/dist/customdata.inputui-DUHO6M6I.js +287 -0
- package/dist/dataDownload-OFB7TYDB.js +328 -0
- package/dist/dataDownload.integration.spec-4HWDQO4C.js +191 -0
- package/dist/databrowser.ui-FGZ5SWG3.js +430 -0
- package/dist/databrowser.ui-FGZ5SWG3.js.map +7 -0
- package/dist/dictionary-BSKN37CP.js +109 -0
- package/dist/dnaMethylation-5QNEEGC6.js +36 -0
- package/dist/dnaMethylation.integration.spec-YIX3JSA7.js +201 -0
- package/dist/dofetch-KFMGQY7G.js +50 -0
- package/dist/e2pca-VX42HDYZ.js +348 -0
- package/dist/ep-B6ZNETLI.js +1254 -0
- package/dist/expclust.gdc.spec-SGECIILQ.js +305 -0
- package/dist/facet-2W5SBPGP.js +519 -0
- package/dist/gb-67KTSE2W.js +86 -0
- package/dist/gb-67KTSE2W.js.map +7 -0
- package/dist/geneExpClustering-6A7364T5.js +247 -0
- package/dist/geneExpression-NAM2UEYN.js +36 -0
- package/dist/geneExpression-WF56ODMZ.js +312 -0
- package/dist/geneExpression.unit.spec-DNE2T3WI.js +100 -0
- package/dist/geneORA-33FK2YOS.js +276 -0
- package/dist/geneVariant-C7PCNBOQ.js +37 -0
- package/dist/geneVariant-REELFRRA.js +39 -0
- package/dist/geneVariant.integration.spec-GNXUGDKL.js +196 -0
- package/dist/genefusion.ui-WO5EPJDS.js +306 -0
- package/dist/geneset-4C6ZLVMN.js +201 -0
- package/dist/geneset-4C6ZLVMN.js.map +7 -0
- package/dist/genomeBrowser.spec-VPAKTUJF.js +279 -0
- package/dist/grin2-AJFEBD43.js +852 -0
- package/dist/grin2-AJFEBD43.js.map +7 -0
- package/dist/grin2-GYHUYNEF.js +1554 -0
- package/dist/gsea-PE5WZ5ZI.js +45 -0
- package/dist/hierCluster-FH6YJHRT.js +61 -0
- package/dist/hierCluster-IFM5I5QN.js +57 -0
- package/dist/hierCluster.config-M57ZIWMB.js +38 -0
- package/dist/hierCluster.integration.spec-Z64RL7MC.js +393 -0
- package/dist/hierCluster.interactivity-CDBAJXOY.js +52 -0
- package/dist/imagePlot-NFEE6IGV.js +161 -0
- package/dist/imagePlot-NFEE6IGV.js.map +7 -0
- package/dist/importPlot-OWKXSK77.js +8 -0
- package/dist/isoformExpression-66XLJG73.js +38 -0
- package/dist/isoformExpression.unit.spec-QJX2IRHL.js +206 -0
- package/dist/launch.adhoc-JCWID253.js +40 -0
- package/dist/leftlabel.sample-5NZ6VQDN.js +257 -0
- package/dist/lollipop-BPFDEM2R.js +169 -0
- package/dist/lollipop-BPFDEM2R.js.map +7 -0
- package/dist/maf-HIS2FQXK.js +450 -0
- package/dist/maftimeline-UPJJQE23.js +591 -0
- package/dist/matrix-62CN2KXR.js +56 -0
- package/dist/matrix-SPEDEB3J.js +61 -0
- package/dist/matrix.config-XB6WFXUY.js +39 -0
- package/dist/matrix.integration.spec-NN7OR5XM.js +3070 -0
- package/dist/matrix.interactivity-OWMHUJCX.js +40 -0
- package/dist/matrix.layout-27QB6MWK.js +42 -0
- package/dist/matrix.renderers-EPXES5E4.js +36 -0
- package/dist/matrix.sort.unit.spec-NBT5FSZ6.js +470 -0
- package/dist/matrix.sorterUi.unit.spec-QKGUE4RR.js +340 -0
- package/dist/mavb-M7Y74OWQ.js +730 -0
- package/dist/mds.fimo-WCDFA7HG.js +516 -0
- package/dist/mds.samplescatterplot-ZDHQ3MKJ.js +1548 -0
- package/dist/mds.survivalplot-R74DL2RA.js +481 -0
- package/dist/oncomatrix-MOITJBII.js +293 -0
- package/dist/oncomatrix.spec-NALJBPYS.js +446 -0
- package/dist/plot.2dvaf-IE2EZEFA.js +375 -0
- package/dist/plot.app-HTW6TZEH.js +39 -0
- package/dist/plot.barplot-NCQEPEOY.js +100 -0
- package/dist/plot.boxplot-WNKVBVJJ.js +150 -0
- package/dist/plot.brainImaging-2Z3TOO6J.js +51 -0
- package/dist/plot.disco-4JAEIAYK.js +101 -0
- package/dist/plot.dzi-ZGLOVJJN.js +33 -0
- package/dist/plot.ssgq-IHUILM43.js +137 -0
- package/dist/plot.vaf2cov-ZYCQMD27.js +257 -0
- package/dist/plot.wsi-3GISVBDH.js +36 -0
- package/dist/polar-4AUAZHBV.js +184 -0
- package/dist/polar2-SRD4WWXU.js +226 -0
- package/dist/profile.spec-TOITKBBZ.js +78 -0
- package/dist/profileBarchart-Z4SYIYBE.js +265 -0
- package/dist/profileForms-RA7XQ2QT.js +438 -0
- package/dist/profilePlot-4BM3XZVK.js +52 -0
- package/dist/profileRadar-EYBESEPI.js +261 -0
- package/dist/profileRadarFacility-FZYTFM26.js +261 -0
- package/dist/proteinView-F6XKT2A5.js +1122 -0
- package/dist/proteinView-F6XKT2A5.js.map +7 -0
- package/dist/proteomeAbundance-3RJMRXYI.js +68 -0
- package/dist/proteomeAbundance-3RJMRXYI.js.map +7 -0
- package/dist/proteomeAbundance-65R6M4YQ.js +21 -0
- package/dist/qualitative-E7WL6DN4.js +41 -0
- package/dist/radar2-I6FN5SUX.js +314 -0
- package/dist/radarFacility2-GVK7PT3V.js +323 -0
- package/dist/regression-TIR5D354.js +54 -0
- package/dist/regression.inputs-2AMJCJ3L.js +46 -0
- package/dist/regression.inputs.term-D6D2QEUB.js +46 -0
- package/dist/regression.inputs.values.table-M3IPLGDJ.js +43 -0
- package/dist/regression.integration.spec-ROUSXLMH.js +782 -0
- package/dist/regression.results-YD5S74YS.js +38 -0
- package/dist/regression.spec-4OXBBTNO.js +706 -0
- package/dist/report-ETNALKTY.js +220 -0
- package/dist/sampleScatter.spec-LECMFMI2.js +200 -0
- package/dist/sampleView-B5TM7JOW.js +46 -0
- package/dist/samplelst-GFQCG4SS.js +109 -0
- package/dist/samplematrix-OMTNWCJK.js +2196 -0
- package/dist/sc-MIEEZBWG.js +84 -0
- package/dist/scatter-ETOZ722F.js +800 -0
- package/dist/scatter.integration.spec-TS4PNRLX.js +1194 -0
- package/dist/selectGenomeWithTklst-Y5QIM2JB.js +132 -0
- package/dist/singleCellCellType-HOJHZF5W.js +36 -0
- package/dist/singleCellCellType.unit.spec-MH5V3RPX.js +158 -0
- package/dist/singleCellGeneExpression-YVQ5TIKN.js +36 -0
- package/dist/singleCellGeneExpression.unit.spec-BMFFT5HO.js +151 -0
- package/dist/singleCellPlot-3YFUYA2Y.js +51 -0
- package/dist/singlecell-FK5JETW5.js +1570 -0
- package/dist/singlecell-RL7V7DIC.js +84 -0
- package/dist/snp-FT7HB3XN.js +36 -0
- package/dist/snp.unit.spec-CLYVYPPG.js +174 -0
- package/dist/snplocus-M5SEQGAC.js +206 -0
- package/dist/spliceevent.a53ss.diagram-EJ5CTRCZ.js +149 -0
- package/dist/spliceevent.exonskip.diagram-ETXMOHZ3.js +275 -0
- package/dist/spliceevent.noeventdiagram-S2O4ZM2Z.js +458 -0
- package/dist/ssGSEA-6PMDQDTJ.js +36 -0
- package/dist/ssGSEA.unit.spec-JD5T4R2N.js +86 -0
- package/dist/summarizeCnvGeneexp-GCHNKTIU.js +161 -0
- package/dist/summarizeGeneexpSurvival-R2RYQZ3M.js +106 -0
- package/dist/summarizeMutationCnv-LB2BIYRL.js +162 -0
- package/dist/summarizeMutationDiagnosis-3JUY75LM.js +38 -0
- package/dist/summarizeMutationSurvival-VYLRWTCF.js +97 -0
- package/dist/summary-2QQ72IEQ.js +47 -0
- package/dist/summary.integration.spec-XXU362UQ.js +412 -0
- package/dist/summaryInput-OZHZG3PV.js +233 -0
- package/dist/sunburst-CMCJCANX.js +282 -0
- package/dist/survival-EBD4DHO7.js +44 -0
- package/dist/survival-ISLRRPKU.js +56 -0
- package/dist/survival.integration.spec-FS7V4OXK.js +800 -0
- package/dist/svgraph-KGLNUM7W.js +1385 -0
- package/dist/svmr-NXZ5VLKH.js +3840 -0
- package/dist/table-ISOQOI6C.js +198 -0
- package/dist/termCollection-7ZSU3I45.js +36 -0
- package/dist/termCollection-V2A5BDQB.js +177 -0
- package/dist/termCollection.unit.spec-6VLCJGOU.js +206 -0
- package/dist/tk-6AB6XYIE.js +44 -0
- package/dist/tp.ui-2O4UW5N7.js +1457 -0
- package/dist/tvs.dt-CY6TOQVB.js +37 -0
- package/dist/tvs.dtcnv.categorical-AYQ432TW.js +38 -0
- package/dist/tvs.dtcnv.continuous-XVDL6SG3.js +70 -0
- package/dist/tvs.dtfusion-V3AV7A6Q.js +38 -0
- package/dist/tvs.dtsnvindel-XM3NXIT7.js +38 -0
- package/dist/tvs.dtsv-Z2GYRINW.js +38 -0
- package/dist/tvs.samplelst-C4FB63G7.js +102 -0
- package/dist/tvs.termCollection-VHTSC2ST.js +157 -0
- package/dist/violin-KGGTUQFF.js +44 -0
- package/dist/violin.integration.spec-5EW6PLJX.js +1423 -0
- package/dist/violin.interactivity-RI4RURGO.js +36 -0
- package/dist/violin.renderer-EWU2IFZE.js +38 -0
- package/dist/vocabulary-VLIGC7OP.js +39 -0
- package/package.json +3 -3
- package/src/databrowser/dictionary.parse.js +14 -2
- package/dist/2dmaf-X7LATQT7.js +0 -1371
- package/dist/AIProjectAdmin-GUBKURGO.js +0 -830
- package/dist/AIProjectAdmin-GUBKURGO.js.map +0 -7
- package/dist/AppHeader-RDOFP322.js +0 -833
- package/dist/BoxPlot-AZF2EMGQ.js +0 -1217
- package/dist/CorrelationVolcano-VXW35SXU.js +0 -617
- package/dist/DE-NLGMZ44O.js +0 -93
- package/dist/DEinput-OJ7P4UMP.js +0 -297
- package/dist/DEinput-OJ7P4UMP.js.map +0 -7
- package/dist/DifferentialAnalysis-G75VUHDI.js +0 -241
- package/dist/Disco-DX4S44SI.js +0 -3235
- package/dist/Disco.UI-5FYIACCU.js +0 -242
- package/dist/DmrPlot-HWYITHK2.js +0 -640
- package/dist/GB-DBTMRVYH.js +0 -1125
- package/dist/GB-DBTMRVYH.js.map +0 -7
- package/dist/GeneExpInput-DWB7OYT2.js +0 -335
- package/dist/GeneExpInput-DWB7OYT2.js.map +0 -7
- package/dist/HicApp-XPZVZXB7.js +0 -2248
- package/dist/NumBinaryEditor-M6MJYIHK.js +0 -268
- package/dist/NumBinaryEditor.unit.spec-W6MMYDAW.js +0 -284
- package/dist/NumContEditor-YRVENTS5.js +0 -105
- package/dist/NumContEditor.unit.spec-A6OH4TI7.js +0 -167
- package/dist/NumCustomBinEditor-BLBOYSCQ.js +0 -36
- package/dist/NumCustomBinEditor.unit.spec-55V5CKLB.js +0 -282
- package/dist/NumDiscreteEditor-DTRM6VL2.js +0 -177
- package/dist/NumDiscreteEditor.unit.spec-YMB6QRER.js +0 -200
- package/dist/NumRegularBinEditor-XW4SVA7S.js +0 -36
- package/dist/NumRegularBinEditor.unit.spec-VAHC3VOD.js +0 -225
- package/dist/NumSplineEditor-H22HTRFR.js +0 -190
- package/dist/NumSplineEditor.unit.spec-4JUADXZR.js +0 -197
- package/dist/NumericDensity-ECSZCQRX.js +0 -36
- package/dist/NumericDensity.unit.spec-SXXCXM4X.js +0 -219
- package/dist/NumericHandler-CMBN3FZX.js +0 -37
- package/dist/NumericHandler.unit.spec-UYTJG2Z2.js +0 -217
- package/dist/RunChart2-MVFWLXZX.js +0 -756
- package/dist/SC-BRC3J2O4.js +0 -797
- package/dist/SC-BRC3J2O4.js.map +0 -7
- package/dist/Volcano-WMNFZSX2.js +0 -1234
- package/dist/Volcano-WMNFZSX2.js.map +0 -7
- package/dist/WSIViewer-2Z636FMA.js +0 -47971
- package/dist/WsiSamplesPlot-LN75PND3.js +0 -163
- package/dist/adSandbox-AJ7QUDOI.js +0 -36
- package/dist/alphaGenome-PVCRXAQK.js +0 -173
- package/dist/app-DWYCAFRP.js +0 -47
- package/dist/app-RENXV7VR.js +0 -35
- package/dist/bam-5G6IT6OX.js +0 -857
- package/dist/barchart-MLCCU6SU.js +0 -45
- package/dist/barchart.events-B6HQTLK2.js +0 -45
- package/dist/barchart.integration.spec-S43A7C7N.js +0 -1675
- package/dist/barchart2-QMKEN6MN.js +0 -309
- package/dist/block-IGBB4BJH.js +0 -6200
- package/dist/block.init-NLCYAKV4.js +0 -36
- package/dist/block.mds.expressionrank-TZWGRDY7.js +0 -357
- package/dist/block.mds.geneboxplot-OAFROYDL.js +0 -826
- package/dist/block.mds.junction-NSLXTW3D.js +0 -1543
- package/dist/block.mds.svcnv-ICPG4BW6.js +0 -6799
- package/dist/block.svg-DTFVIAAC.js +0 -162
- package/dist/block.tk.aicheck-ZIMIBWHA.js +0 -281
- package/dist/block.tk.ase-I7UNK5BK.js +0 -363
- package/dist/block.tk.bam-W7JG46RS.js +0 -1904
- package/dist/block.tk.bedgraphdot-XAQJPKGJ.js +0 -382
- package/dist/block.tk.bigwig.ui-YQOJPJSG.js +0 -209
- package/dist/block.tk.hicstraw-OWWGGCHU.js +0 -821
- package/dist/block.tk.junction-V63ZQQX6.js +0 -2362
- package/dist/block.tk.junction.textmatrixui-B7KXX7WN.js +0 -197
- package/dist/block.tk.ld-2J6CT74S.js +0 -97
- package/dist/block.tk.menu-6AQLG7PW.js +0 -1027
- package/dist/block.tk.pgv-4V6PKVCQ.js +0 -942
- package/dist/brainImaging-WRBGYLHK.js +0 -421
- package/dist/chat-X2BCTEDF.js +0 -148
- package/dist/chat-X2BCTEDF.js.map +0 -7
- package/dist/chunk-23VG37CB.js +0 -1939
- package/dist/chunk-23VG37CB.js.map +0 -7
- package/dist/chunk-2VOHINOC.js +0 -262
- package/dist/chunk-2VOHINOC.js.map +0 -7
- package/dist/chunk-3AK6GP4M.js +0 -215
- package/dist/chunk-3B7EWIVB.js +0 -153
- package/dist/chunk-3JAC5CHL.js +0 -407
- package/dist/chunk-3QBZ2Y77.js +0 -188
- package/dist/chunk-3QBZ2Y77.js.map +0 -7
- package/dist/chunk-3T2PCWII.js +0 -442
- package/dist/chunk-4BTAI6HQ.js +0 -100
- package/dist/chunk-4JVNATQR.js +0 -621
- package/dist/chunk-4ZCR6CPK.js +0 -4964
- package/dist/chunk-4ZCR6CPK.js.map +0 -7
- package/dist/chunk-5MW5VMWD.js +0 -2784
- package/dist/chunk-5ZBEDKBD.js +0 -158
- package/dist/chunk-65YTZS3R.js +0 -203
- package/dist/chunk-6ZCHECOT.js +0 -1816
- package/dist/chunk-6ZCHECOT.js.map +0 -7
- package/dist/chunk-73ZT6NAT.js +0 -34
- package/dist/chunk-7HJ6H7AZ.js +0 -2681
- package/dist/chunk-AFXYPMFZ.js +0 -117
- package/dist/chunk-BL4ALBZ7.js +0 -37
- package/dist/chunk-BRCDZJBQ.js +0 -824
- package/dist/chunk-EBGX226R.js +0 -205
- package/dist/chunk-EHXI36HJ.js +0 -2815
- package/dist/chunk-ENP4FLOX.js +0 -293
- package/dist/chunk-FDOSJKDA.js +0 -1209
- package/dist/chunk-FDOSJKDA.js.map +0 -7
- package/dist/chunk-HP2BASCY.js +0 -1159
- package/dist/chunk-HP2BASCY.js.map +0 -7
- package/dist/chunk-HROKXT4K.js +0 -14
- package/dist/chunk-HTMXVOTH.js +0 -482
- package/dist/chunk-IA7S4UL5.js +0 -302
- package/dist/chunk-JFIOYO3M.js +0 -272
- package/dist/chunk-JMJW3ERE.js +0 -470
- package/dist/chunk-K7XWZSQA.js +0 -148
- package/dist/chunk-KSN3EVKI.js +0 -102
- package/dist/chunk-L5SOHZ5V.js +0 -229
- package/dist/chunk-LMGE54CQ.js +0 -54
- package/dist/chunk-LOMVTHAM.js +0 -95
- package/dist/chunk-MSW7OS2O.js +0 -276
- package/dist/chunk-MVCGSYS2.js +0 -50
- package/dist/chunk-N2HBIQKU.js +0 -102
- package/dist/chunk-NL3DVEVX.js +0 -158
- package/dist/chunk-O4WJSZC3.js +0 -1087
- package/dist/chunk-OLUDD6EC.js +0 -2370
- package/dist/chunk-OVPVPPRG.js +0 -55
- package/dist/chunk-OYEISJSJ.js +0 -289
- package/dist/chunk-OYEISJSJ.js.map +0 -7
- package/dist/chunk-P2JDCMXW.js +0 -4207
- package/dist/chunk-PMDXCESS.js +0 -514
- package/dist/chunk-PXYYICV7.js +0 -1271
- package/dist/chunk-PZ3KIUWJ.js +0 -56
- package/dist/chunk-QEWMCAJW.js +0 -335
- package/dist/chunk-QLWDUZ5K.js +0 -129
- package/dist/chunk-QRSIID3T.js +0 -95
- package/dist/chunk-ST644IDH.js +0 -217
- package/dist/chunk-UOOMFM7K.js +0 -6364
- package/dist/chunk-VGHSLILD.js +0 -368
- package/dist/chunk-W35IOI74.js +0 -228
- package/dist/chunk-XKF4KMCB.js +0 -146
- package/dist/chunk-XKF4KMCB.js.map +0 -7
- package/dist/chunk-XVDWYTJ6.js +0 -676
- package/dist/chunk-YQVEBFGT.js +0 -455
- package/dist/chunk-YWUVCXFS.js +0 -20271
- package/dist/chunk-YWUVCXFS.js.map +0 -7
- package/dist/chunk-ZT3PB4XX.js +0 -1150
- package/dist/chunk-ZT3PB4XX.js.map +0 -7
- package/dist/chunk-ZVSXHCGP.js +0 -142
- package/dist/condition-CZX2GSN4.js +0 -330
- package/dist/controls-BQR3WY5W.js +0 -39
- package/dist/controls.config-TAVZDHFZ.js +0 -37
- package/dist/correlation-BIWVZNC6.js +0 -96
- package/dist/cuminc-EDXOOI5R.js +0 -1147
- package/dist/cuminc.integration.spec-UZA7BDTB.js +0 -676
- package/dist/customdata.inputui-PEB4CE7J.js +0 -287
- package/dist/dataDownload-KANEHJXJ.js +0 -328
- package/dist/dataDownload.integration.spec-23WLHSWJ.js +0 -191
- package/dist/databrowser.ui-B2TNECC4.js +0 -419
- package/dist/databrowser.ui-B2TNECC4.js.map +0 -7
- package/dist/dictionary-YOTUFVES.js +0 -109
- package/dist/dnaMethylation-TRFAZWRJ.js +0 -36
- package/dist/dnaMethylation.integration.spec-SPFZO76D.js +0 -201
- package/dist/dofetch-MH4MRMGY.js +0 -50
- package/dist/e2pca-AFVAFUJ2.js +0 -348
- package/dist/ep-4FXTLWB4.js +0 -1254
- package/dist/expclust.gdc.spec-SFOCKBLR.js +0 -305
- package/dist/facet-SY6PYSTN.js +0 -519
- package/dist/gb-JUV63QCN.js +0 -93
- package/dist/gb-JUV63QCN.js.map +0 -7
- package/dist/geneExpClustering-FOY77R7P.js +0 -247
- package/dist/geneExpression-AHKX57BT.js +0 -312
- package/dist/geneExpression-D2F2KVGY.js +0 -36
- package/dist/geneExpression.unit.spec-SR2BGZQL.js +0 -100
- package/dist/geneORA-VJMYI4BT.js +0 -276
- package/dist/geneVariant-LFM5SO2P.js +0 -37
- package/dist/geneVariant-OIKEV4JM.js +0 -39
- package/dist/geneVariant.integration.spec-T6BINPIN.js +0 -196
- package/dist/genefusion.ui-NLMW5XMI.js +0 -306
- package/dist/geneset-HKXFHM5K.js +0 -197
- package/dist/geneset-HKXFHM5K.js.map +0 -7
- package/dist/genomeBrowser.spec-DRYIFJLY.js +0 -279
- package/dist/grin2-GJKLNT4J.js +0 -1031
- package/dist/grin2-GJKLNT4J.js.map +0 -7
- package/dist/grin2-LGI535FF.js +0 -1554
- package/dist/gsea-Z7DSDFOA.js +0 -45
- package/dist/hierCluster-HC2B5XRR.js +0 -61
- package/dist/hierCluster-PLHVN5S3.js +0 -57
- package/dist/hierCluster.config-E3DIJWL5.js +0 -38
- package/dist/hierCluster.integration.spec-OQLPUQG4.js +0 -393
- package/dist/hierCluster.interactivity-LRNPDTEH.js +0 -52
- package/dist/imagePlot-GUXRGYQA.js +0 -139
- package/dist/imagePlot-GUXRGYQA.js.map +0 -7
- package/dist/importPlot-M5HGLHRO.js +0 -8
- package/dist/isoformExpression-PADLHHR5.js +0 -38
- package/dist/isoformExpression.unit.spec-5BPAL4OS.js +0 -206
- package/dist/launch.adhoc-JH6ZZFDB.js +0 -40
- package/dist/leftlabel.sample-NS2TBANH.js +0 -257
- package/dist/lollipop-W6NOHHCP.js +0 -166
- package/dist/lollipop-W6NOHHCP.js.map +0 -7
- package/dist/maf-NOHIKTUP.js +0 -450
- package/dist/maftimeline-WGWE52EF.js +0 -591
- package/dist/matrix-B6NPQFFF.js +0 -61
- package/dist/matrix-UAKRJL5A.js +0 -56
- package/dist/matrix.config-KJNJXPJJ.js +0 -39
- package/dist/matrix.integration.spec-VAXIR3E6.js +0 -3070
- package/dist/matrix.interactivity-H4MCMJXU.js +0 -40
- package/dist/matrix.layout-RFKQJM5D.js +0 -42
- package/dist/matrix.renderers-7JJIC6VC.js +0 -36
- package/dist/matrix.sort.unit.spec-MQQVWWNT.js +0 -470
- package/dist/matrix.sorterUi.unit.spec-LG4TI7VF.js +0 -340
- package/dist/mavb-EIZHS6F4.js +0 -730
- package/dist/mds.fimo-XVC6MI7W.js +0 -516
- package/dist/mds.samplescatterplot-PRR4TKYI.js +0 -1548
- package/dist/mds.survivalplot-3OG4Y2B6.js +0 -481
- package/dist/oncomatrix-SO6S6IIB.js +0 -293
- package/dist/oncomatrix.spec-VXTF44K5.js +0 -446
- package/dist/plot.2dvaf-JW5OJJXV.js +0 -375
- package/dist/plot.app-T3GVCFQ3.js +0 -39
- package/dist/plot.barplot-2TYP6DPI.js +0 -100
- package/dist/plot.boxplot-HOQHM7JF.js +0 -150
- package/dist/plot.brainImaging-5AI7BSD4.js +0 -51
- package/dist/plot.disco-HNNZHK5Z.js +0 -101
- package/dist/plot.dzi-4OQSO7SY.js +0 -33
- package/dist/plot.ssgq-VZTTGECT.js +0 -137
- package/dist/plot.vaf2cov-ASEELRDV.js +0 -257
- package/dist/plot.wsi-MDWYLU4R.js +0 -36
- package/dist/polar-QSY6JG4P.js +0 -184
- package/dist/polar2-FD6656VD.js +0 -226
- package/dist/profile.spec-V7EQBXT2.js +0 -78
- package/dist/profileBarchart-EIKHZAPD.js +0 -265
- package/dist/profileForms-NGFRXPFF.js +0 -438
- package/dist/profilePlot-2UFKJ2OC.js +0 -52
- package/dist/profileRadar-B2R7OV5F.js +0 -261
- package/dist/profileRadarFacility-ILC7POCI.js +0 -261
- package/dist/proteinView-AS6ZV2JT.js +0 -758
- package/dist/proteinView-AS6ZV2JT.js.map +0 -7
- package/dist/proteomeAbundance-6J5YF4V2.js +0 -63
- package/dist/proteomeAbundance-6J5YF4V2.js.map +0 -7
- package/dist/proteomeAbundance-OF27N347.js +0 -21
- package/dist/qualitative-CSUO2WG5.js +0 -41
- package/dist/radar2-L2HGCUYR.js +0 -314
- package/dist/radarFacility2-HXUUTRYO.js +0 -323
- package/dist/regression-Y4NYGZSA.js +0 -54
- package/dist/regression.inputs-RWFIJLNF.js +0 -46
- package/dist/regression.inputs.term-QIU5SHTN.js +0 -46
- package/dist/regression.inputs.values.table-FM6QTSEV.js +0 -43
- package/dist/regression.integration.spec-YRKKU7HL.js +0 -782
- package/dist/regression.results-YUDCHUZJ.js +0 -38
- package/dist/regression.spec-G4GIIV32.js +0 -706
- package/dist/report-2N4FBR4Q.js +0 -220
- package/dist/sampleScatter.spec-UIUYO4WR.js +0 -200
- package/dist/sampleView-TOK5Y5KU.js +0 -46
- package/dist/samplelst-YW5ZS3GJ.js +0 -109
- package/dist/samplematrix-447BHSO7.js +0 -2196
- package/dist/sc-O2PL3FL2.js +0 -84
- package/dist/scatter-4DXHOWVY.js +0 -800
- package/dist/scatter.integration.spec-ZPTM3AGQ.js +0 -1194
- package/dist/selectGenomeWithTklst-3RLZFW62.js +0 -132
- package/dist/singleCellCellType-3LQJXS7H.js +0 -36
- package/dist/singleCellCellType.unit.spec-UJM72SP4.js +0 -158
- package/dist/singleCellGeneExpression-JOWJWPIQ.js +0 -36
- package/dist/singleCellGeneExpression.unit.spec-VY5CGRZH.js +0 -151
- package/dist/singleCellPlot-IVLVKOO6.js +0 -51
- package/dist/singlecell-VJJZJZF7.js +0 -1570
- package/dist/singlecell-VQJ2252L.js +0 -84
- package/dist/snp-ALMKZKL2.js +0 -36
- package/dist/snp.unit.spec-GJQBAHGQ.js +0 -174
- package/dist/snplocus-WCNCMFWZ.js +0 -206
- package/dist/spliceevent.a53ss.diagram-4Q4JF4RX.js +0 -149
- package/dist/spliceevent.exonskip.diagram-IOYOKELT.js +0 -275
- package/dist/spliceevent.noeventdiagram-77ZCOHSF.js +0 -458
- package/dist/ssGSEA-QTXXIN4K.js +0 -36
- package/dist/ssGSEA.unit.spec-LQESATT3.js +0 -86
- package/dist/summarizeCnvGeneexp-YKUQGDQF.js +0 -161
- package/dist/summarizeGeneexpSurvival-ARGG5VDC.js +0 -106
- package/dist/summarizeMutationCnv-FMZYT3EC.js +0 -162
- package/dist/summarizeMutationDiagnosis-ZX7I46SC.js +0 -38
- package/dist/summarizeMutationSurvival-RCFMTT43.js +0 -97
- package/dist/summary-QLL5YVI2.js +0 -47
- package/dist/summary.integration.spec-DHY6XCEJ.js +0 -412
- package/dist/summaryInput-ANCUQGIB.js +0 -233
- package/dist/sunburst-RDNFBOCK.js +0 -282
- package/dist/survival-BG7QV52L.js +0 -44
- package/dist/survival-WSN36OQE.js +0 -56
- package/dist/survival.integration.spec-37KAJ5IK.js +0 -800
- package/dist/svgraph-A5WGHW4S.js +0 -1385
- package/dist/svmr-CYRHHWZF.js +0 -3840
- package/dist/table-VHO7E5PI.js +0 -198
- package/dist/termCollection-E4Q6GLXN.js +0 -177
- package/dist/termCollection-HSVSH7TJ.js +0 -36
- package/dist/termCollection.unit.spec-ZCE3TUMS.js +0 -206
- package/dist/tk-GPRHDN4K.js +0 -44
- package/dist/tp.ui-LTUA3FSL.js +0 -1457
- package/dist/tvs.dt-G43PAAKD.js +0 -37
- package/dist/tvs.dtcnv.categorical-UHDS2TGZ.js +0 -38
- package/dist/tvs.dtcnv.continuous-ZNGYQKTD.js +0 -70
- package/dist/tvs.dtfusion-JBEEUDUS.js +0 -38
- package/dist/tvs.dtsnvindel-XXN5Q7RN.js +0 -38
- package/dist/tvs.dtsv-MO6L7HHV.js +0 -38
- package/dist/tvs.samplelst-HKY6UUJM.js +0 -102
- package/dist/tvs.termCollection-TY6FPL25.js +0 -157
- package/dist/violin-YHE3WSGR.js +0 -44
- package/dist/violin.integration.spec-F2UD7BHC.js +0 -1423
- package/dist/violin.interactivity-LVDTDEPQ.js +0 -36
- package/dist/violin.renderer-IIEIUGRI.js +0 -38
- package/dist/vocabulary-WQRYXBRO.js +0 -39
- /package/dist/{2dmaf-X7LATQT7.js.map → 2dmaf-F5QNP7AQ.js.map} +0 -0
- /package/dist/{AppHeader-RDOFP322.js.map → AppHeader-STVCDLET.js.map} +0 -0
- /package/dist/{BoxPlot-AZF2EMGQ.js.map → BoxPlot-CU7MEBH7.js.map} +0 -0
- /package/dist/{CorrelationVolcano-VXW35SXU.js.map → CorrelationVolcano-OE4R2GS3.js.map} +0 -0
- /package/dist/{DE-NLGMZ44O.js.map → DE-SR7PJPKI.js.map} +0 -0
- /package/dist/{DifferentialAnalysis-G75VUHDI.js.map → DifferentialAnalysis-UWTYK7NU.js.map} +0 -0
- /package/dist/{Disco-DX4S44SI.js.map → Disco-IL6REGSA.js.map} +0 -0
- /package/dist/{Disco.UI-5FYIACCU.js.map → Disco.UI-JHHLS5BA.js.map} +0 -0
- /package/dist/{DmrPlot-HWYITHK2.js.map → DmrPlot-DDP53T3F.js.map} +0 -0
- /package/dist/{HicApp-XPZVZXB7.js.map → HicApp-RVFHTYED.js.map} +0 -0
- /package/dist/{NumBinaryEditor-M6MJYIHK.js.map → NumBinaryEditor-B3FXQAOH.js.map} +0 -0
- /package/dist/{NumBinaryEditor.unit.spec-W6MMYDAW.js.map → NumBinaryEditor.unit.spec-75YQJ2U6.js.map} +0 -0
- /package/dist/{NumContEditor-YRVENTS5.js.map → NumContEditor-5PYW3OLY.js.map} +0 -0
- /package/dist/{NumContEditor.unit.spec-A6OH4TI7.js.map → NumContEditor.unit.spec-F7ZRDGBN.js.map} +0 -0
- /package/dist/{NumCustomBinEditor-BLBOYSCQ.js.map → NumCustomBinEditor-TBT6GLYQ.js.map} +0 -0
- /package/dist/{NumCustomBinEditor.unit.spec-55V5CKLB.js.map → NumCustomBinEditor.unit.spec-6YHU45XV.js.map} +0 -0
- /package/dist/{NumDiscreteEditor-DTRM6VL2.js.map → NumDiscreteEditor-N6OJYSJA.js.map} +0 -0
- /package/dist/{NumDiscreteEditor.unit.spec-YMB6QRER.js.map → NumDiscreteEditor.unit.spec-HQS5RZ6R.js.map} +0 -0
- /package/dist/{NumRegularBinEditor-XW4SVA7S.js.map → NumRegularBinEditor-HSDDKVNG.js.map} +0 -0
- /package/dist/{NumRegularBinEditor.unit.spec-VAHC3VOD.js.map → NumRegularBinEditor.unit.spec-33KN2MVM.js.map} +0 -0
- /package/dist/{NumSplineEditor-H22HTRFR.js.map → NumSplineEditor-XERKOACS.js.map} +0 -0
- /package/dist/{NumSplineEditor.unit.spec-4JUADXZR.js.map → NumSplineEditor.unit.spec-MPVM6KSC.js.map} +0 -0
- /package/dist/{NumericDensity-ECSZCQRX.js.map → NumericDensity-35EKYW3V.js.map} +0 -0
- /package/dist/{NumericDensity.unit.spec-SXXCXM4X.js.map → NumericDensity.unit.spec-OR24PPRJ.js.map} +0 -0
- /package/dist/{NumericHandler-CMBN3FZX.js.map → NumericHandler-D6ZNGRE3.js.map} +0 -0
- /package/dist/{NumericHandler.unit.spec-UYTJG2Z2.js.map → NumericHandler.unit.spec-EKPGVSXI.js.map} +0 -0
- /package/dist/{RunChart2-MVFWLXZX.js.map → RunChart2-7DOXOFXV.js.map} +0 -0
- /package/dist/{WSIViewer-2Z636FMA.js.map → WSIViewer-E247ELKN.js.map} +0 -0
- /package/dist/{WsiSamplesPlot-LN75PND3.js.map → WsiSamplesPlot-3522VRB5.js.map} +0 -0
- /package/dist/{adSandbox-AJ7QUDOI.js.map → adSandbox-IDFY5P2P.js.map} +0 -0
- /package/dist/{alphaGenome-PVCRXAQK.js.map → alphaGenome-F3W7GJQ5.js.map} +0 -0
- /package/dist/{app-DWYCAFRP.js.map → app-2HDSFMRM.js.map} +0 -0
- /package/dist/{app-RENXV7VR.js.map → app-LIWPFL7C.js.map} +0 -0
- /package/dist/{bam-5G6IT6OX.js.map → bam-TBHHSATL.js.map} +0 -0
- /package/dist/{barchart-MLCCU6SU.js.map → barchart-HHFCBOZE.js.map} +0 -0
- /package/dist/{barchart.events-B6HQTLK2.js.map → barchart.events-UQUSSRXB.js.map} +0 -0
- /package/dist/{barchart.integration.spec-S43A7C7N.js.map → barchart.integration.spec-OF3MWFQ5.js.map} +0 -0
- /package/dist/{barchart2-QMKEN6MN.js.map → barchart2-XRMPCBBU.js.map} +0 -0
- /package/dist/{block-IGBB4BJH.js.map → block-5UEORHFB.js.map} +0 -0
- /package/dist/{block.init-NLCYAKV4.js.map → block.init-QSSFUVIT.js.map} +0 -0
- /package/dist/{block.mds.expressionrank-TZWGRDY7.js.map → block.mds.expressionrank-VBIIJHQF.js.map} +0 -0
- /package/dist/{block.mds.geneboxplot-OAFROYDL.js.map → block.mds.geneboxplot-KSBHXBNX.js.map} +0 -0
- /package/dist/{block.mds.junction-NSLXTW3D.js.map → block.mds.junction-FWZWMZJ2.js.map} +0 -0
- /package/dist/{block.mds.svcnv-ICPG4BW6.js.map → block.mds.svcnv-UXORVLH2.js.map} +0 -0
- /package/dist/{block.svg-DTFVIAAC.js.map → block.svg-6KIGW4QH.js.map} +0 -0
- /package/dist/{block.tk.aicheck-ZIMIBWHA.js.map → block.tk.aicheck-DK566Q4C.js.map} +0 -0
- /package/dist/{block.tk.ase-I7UNK5BK.js.map → block.tk.ase-2GB2VJJ6.js.map} +0 -0
- /package/dist/{block.tk.bam-W7JG46RS.js.map → block.tk.bam-RQNOLY52.js.map} +0 -0
- /package/dist/{block.tk.bedgraphdot-XAQJPKGJ.js.map → block.tk.bedgraphdot-N4YMZFO4.js.map} +0 -0
- /package/dist/{block.tk.bigwig.ui-YQOJPJSG.js.map → block.tk.bigwig.ui-4S7L7D7D.js.map} +0 -0
- /package/dist/{block.tk.hicstraw-OWWGGCHU.js.map → block.tk.hicstraw-AHFNQKCS.js.map} +0 -0
- /package/dist/{block.tk.junction-V63ZQQX6.js.map → block.tk.junction-7E6SNQMQ.js.map} +0 -0
- /package/dist/{block.tk.junction.textmatrixui-B7KXX7WN.js.map → block.tk.junction.textmatrixui-3C5JVYX5.js.map} +0 -0
- /package/dist/{block.tk.ld-2J6CT74S.js.map → block.tk.ld-TOUCLT3W.js.map} +0 -0
- /package/dist/{block.tk.menu-6AQLG7PW.js.map → block.tk.menu-JCV5ORD6.js.map} +0 -0
- /package/dist/{block.tk.pgv-4V6PKVCQ.js.map → block.tk.pgv-CUU22U6M.js.map} +0 -0
- /package/dist/{brainImaging-WRBGYLHK.js.map → brainImaging-MTQTXNNL.js.map} +0 -0
- /package/dist/{chunk-ENP4FLOX.js.map → chunk-2UYBBUXK.js.map} +0 -0
- /package/dist/{chunk-P2JDCMXW.js.map → chunk-2VPEFXEJ.js.map} +0 -0
- /package/dist/{chunk-OVPVPPRG.js.map → chunk-3QHIL3V3.js.map} +0 -0
- /package/dist/{chunk-QLWDUZ5K.js.map → chunk-44VXWKYJ.js.map} +0 -0
- /package/dist/{chunk-QRSIID3T.js.map → chunk-52D6EGUS.js.map} +0 -0
- /package/dist/{chunk-N2HBIQKU.js.map → chunk-5FHM3L4I.js.map} +0 -0
- /package/dist/{chunk-ZVSXHCGP.js.map → chunk-62TF2MCH.js.map} +0 -0
- /package/dist/{chunk-UOOMFM7K.js.map → chunk-67QM2NUK.js.map} +0 -0
- /package/dist/{chunk-XVDWYTJ6.js.map → chunk-6AAPHEWK.js.map} +0 -0
- /package/dist/{chunk-3B7EWIVB.js.map → chunk-6KPGMUHS.js.map} +0 -0
- /package/dist/{chunk-YQVEBFGT.js.map → chunk-6WBIZXNI.js.map} +0 -0
- /package/dist/{chunk-IA7S4UL5.js.map → chunk-7AAJVXEG.js.map} +0 -0
- /package/dist/{chunk-PXYYICV7.js.map → chunk-AFJRAR4N.js.map} +0 -0
- /package/dist/{chunk-K7XWZSQA.js.map → chunk-CVRYZMDE.js.map} +0 -0
- /package/dist/{chunk-MSW7OS2O.js.map → chunk-DGUTCYH2.js.map} +0 -0
- /package/dist/{chunk-5ZBEDKBD.js.map → chunk-DHNXATHC.js.map} +0 -0
- /package/dist/{chunk-L5SOHZ5V.js.map → chunk-E3BI23UK.js.map} +0 -0
- /package/dist/{chunk-4JVNATQR.js.map → chunk-E4JDHA3C.js.map} +0 -0
- /package/dist/{chunk-W35IOI74.js.map → chunk-FOJWYEGV.js.map} +0 -0
- /package/dist/{chunk-NL3DVEVX.js.map → chunk-FTN7Y34O.js.map} +0 -0
- /package/dist/{chunk-EHXI36HJ.js.map → chunk-GRG5MMPN.js.map} +0 -0
- /package/dist/{chunk-HTMXVOTH.js.map → chunk-GSU4PZN3.js.map} +0 -0
- /package/dist/{chunk-ST644IDH.js.map → chunk-IIRU2JLK.js.map} +0 -0
- /package/dist/{chunk-JFIOYO3M.js.map → chunk-JCB74ZSK.js.map} +0 -0
- /package/dist/{chunk-BRCDZJBQ.js.map → chunk-JUDWPYMA.js.map} +0 -0
- /package/dist/{chunk-O4WJSZC3.js.map → chunk-KT6VZBC7.js.map} +0 -0
- /package/dist/{chunk-OLUDD6EC.js.map → chunk-L2HBHFTK.js.map} +0 -0
- /package/dist/{chunk-VGHSLILD.js.map → chunk-LKADRF3Q.js.map} +0 -0
- /package/dist/{chunk-3JAC5CHL.js.map → chunk-MAXFRUGM.js.map} +0 -0
- /package/dist/{chunk-BL4ALBZ7.js.map → chunk-MQN7RYCK.js.map} +0 -0
- /package/dist/{chunk-JMJW3ERE.js.map → chunk-OEUI4CYZ.js.map} +0 -0
- /package/dist/{chunk-73ZT6NAT.js.map → chunk-OM36XUQL.js.map} +0 -0
- /package/dist/{chunk-LMGE54CQ.js.map → chunk-P5LNIH5X.js.map} +0 -0
- /package/dist/{chunk-KSN3EVKI.js.map → chunk-PG62PRMF.js.map} +0 -0
- /package/dist/{chunk-EBGX226R.js.map → chunk-Q3J3F2NU.js.map} +0 -0
- /package/dist/{chunk-AFXYPMFZ.js.map → chunk-RZBV6474.js.map} +0 -0
- /package/dist/{chunk-3T2PCWII.js.map → chunk-T5V4OC27.js.map} +0 -0
- /package/dist/{chunk-QEWMCAJW.js.map → chunk-UCKSUNSJ.js.map} +0 -0
- /package/dist/{chunk-PMDXCESS.js.map → chunk-W4TLYHZO.js.map} +0 -0
- /package/dist/{chunk-PZ3KIUWJ.js.map → chunk-WPZUXKIB.js.map} +0 -0
- /package/dist/{chunk-3AK6GP4M.js.map → chunk-XM47XD6G.js.map} +0 -0
- /package/dist/{chunk-MVCGSYS2.js.map → chunk-YZHGLSKQ.js.map} +0 -0
- /package/dist/{chunk-65YTZS3R.js.map → chunk-ZGOOZK3I.js.map} +0 -0
- /package/dist/{chunk-LOMVTHAM.js.map → chunk-ZH2VP6Q6.js.map} +0 -0
- /package/dist/{chunk-HROKXT4K.js.map → chunk-ZLOQXO5K.js.map} +0 -0
- /package/dist/{chunk-4BTAI6HQ.js.map → chunk-ZMNDBPJU.js.map} +0 -0
- /package/dist/{chunk-5MW5VMWD.js.map → chunk-ZRTW6X3F.js.map} +0 -0
- /package/dist/{chunk-7HJ6H7AZ.js.map → chunk-ZTT52MBP.js.map} +0 -0
- /package/dist/{condition-CZX2GSN4.js.map → condition-VUACUQYF.js.map} +0 -0
- /package/dist/{controls-BQR3WY5W.js.map → controls-N4MPSNO4.js.map} +0 -0
- /package/dist/{controls.config-TAVZDHFZ.js.map → controls.config-PRXVODCM.js.map} +0 -0
- /package/dist/{correlation-BIWVZNC6.js.map → correlation-QJZUYDFH.js.map} +0 -0
- /package/dist/{cuminc-EDXOOI5R.js.map → cuminc-JJHXW55V.js.map} +0 -0
- /package/dist/{cuminc.integration.spec-UZA7BDTB.js.map → cuminc.integration.spec-IXS2UO2O.js.map} +0 -0
- /package/dist/{customdata.inputui-PEB4CE7J.js.map → customdata.inputui-DUHO6M6I.js.map} +0 -0
- /package/dist/{dataDownload-KANEHJXJ.js.map → dataDownload-OFB7TYDB.js.map} +0 -0
- /package/dist/{dataDownload.integration.spec-23WLHSWJ.js.map → dataDownload.integration.spec-4HWDQO4C.js.map} +0 -0
- /package/dist/{dictionary-YOTUFVES.js.map → dictionary-BSKN37CP.js.map} +0 -0
- /package/dist/{dnaMethylation-TRFAZWRJ.js.map → dnaMethylation-5QNEEGC6.js.map} +0 -0
- /package/dist/{dnaMethylation.integration.spec-SPFZO76D.js.map → dnaMethylation.integration.spec-YIX3JSA7.js.map} +0 -0
- /package/dist/{dofetch-MH4MRMGY.js.map → dofetch-KFMGQY7G.js.map} +0 -0
- /package/dist/{e2pca-AFVAFUJ2.js.map → e2pca-VX42HDYZ.js.map} +0 -0
- /package/dist/{ep-4FXTLWB4.js.map → ep-B6ZNETLI.js.map} +0 -0
- /package/dist/{expclust.gdc.spec-SFOCKBLR.js.map → expclust.gdc.spec-SGECIILQ.js.map} +0 -0
- /package/dist/{facet-SY6PYSTN.js.map → facet-2W5SBPGP.js.map} +0 -0
- /package/dist/{geneExpClustering-FOY77R7P.js.map → geneExpClustering-6A7364T5.js.map} +0 -0
- /package/dist/{geneExpression-D2F2KVGY.js.map → geneExpression-NAM2UEYN.js.map} +0 -0
- /package/dist/{geneExpression-AHKX57BT.js.map → geneExpression-WF56ODMZ.js.map} +0 -0
- /package/dist/{geneExpression.unit.spec-SR2BGZQL.js.map → geneExpression.unit.spec-DNE2T3WI.js.map} +0 -0
- /package/dist/{geneORA-VJMYI4BT.js.map → geneORA-33FK2YOS.js.map} +0 -0
- /package/dist/{geneVariant-LFM5SO2P.js.map → geneVariant-C7PCNBOQ.js.map} +0 -0
- /package/dist/{geneVariant-OIKEV4JM.js.map → geneVariant-REELFRRA.js.map} +0 -0
- /package/dist/{geneVariant.integration.spec-T6BINPIN.js.map → geneVariant.integration.spec-GNXUGDKL.js.map} +0 -0
- /package/dist/{genefusion.ui-NLMW5XMI.js.map → genefusion.ui-WO5EPJDS.js.map} +0 -0
- /package/dist/{genomeBrowser.spec-DRYIFJLY.js.map → genomeBrowser.spec-VPAKTUJF.js.map} +0 -0
- /package/dist/{grin2-LGI535FF.js.map → grin2-GYHUYNEF.js.map} +0 -0
- /package/dist/{gsea-Z7DSDFOA.js.map → gsea-PE5WZ5ZI.js.map} +0 -0
- /package/dist/{hierCluster-HC2B5XRR.js.map → hierCluster-FH6YJHRT.js.map} +0 -0
- /package/dist/{hierCluster-PLHVN5S3.js.map → hierCluster-IFM5I5QN.js.map} +0 -0
- /package/dist/{hierCluster.config-E3DIJWL5.js.map → hierCluster.config-M57ZIWMB.js.map} +0 -0
- /package/dist/{hierCluster.integration.spec-OQLPUQG4.js.map → hierCluster.integration.spec-Z64RL7MC.js.map} +0 -0
- /package/dist/{hierCluster.interactivity-LRNPDTEH.js.map → hierCluster.interactivity-CDBAJXOY.js.map} +0 -0
- /package/dist/{importPlot-M5HGLHRO.js.map → importPlot-OWKXSK77.js.map} +0 -0
- /package/dist/{isoformExpression-PADLHHR5.js.map → isoformExpression-66XLJG73.js.map} +0 -0
- /package/dist/{isoformExpression.unit.spec-5BPAL4OS.js.map → isoformExpression.unit.spec-QJX2IRHL.js.map} +0 -0
- /package/dist/{launch.adhoc-JH6ZZFDB.js.map → launch.adhoc-JCWID253.js.map} +0 -0
- /package/dist/{leftlabel.sample-NS2TBANH.js.map → leftlabel.sample-5NZ6VQDN.js.map} +0 -0
- /package/dist/{maf-NOHIKTUP.js.map → maf-HIS2FQXK.js.map} +0 -0
- /package/dist/{maftimeline-WGWE52EF.js.map → maftimeline-UPJJQE23.js.map} +0 -0
- /package/dist/{matrix-B6NPQFFF.js.map → matrix-62CN2KXR.js.map} +0 -0
- /package/dist/{matrix-UAKRJL5A.js.map → matrix-SPEDEB3J.js.map} +0 -0
- /package/dist/{matrix.config-KJNJXPJJ.js.map → matrix.config-XB6WFXUY.js.map} +0 -0
- /package/dist/{matrix.integration.spec-VAXIR3E6.js.map → matrix.integration.spec-NN7OR5XM.js.map} +0 -0
- /package/dist/{matrix.interactivity-H4MCMJXU.js.map → matrix.interactivity-OWMHUJCX.js.map} +0 -0
- /package/dist/{matrix.layout-RFKQJM5D.js.map → matrix.layout-27QB6MWK.js.map} +0 -0
- /package/dist/{matrix.renderers-7JJIC6VC.js.map → matrix.renderers-EPXES5E4.js.map} +0 -0
- /package/dist/{matrix.sort.unit.spec-MQQVWWNT.js.map → matrix.sort.unit.spec-NBT5FSZ6.js.map} +0 -0
- /package/dist/{matrix.sorterUi.unit.spec-LG4TI7VF.js.map → matrix.sorterUi.unit.spec-QKGUE4RR.js.map} +0 -0
- /package/dist/{mavb-EIZHS6F4.js.map → mavb-M7Y74OWQ.js.map} +0 -0
- /package/dist/{mds.fimo-XVC6MI7W.js.map → mds.fimo-WCDFA7HG.js.map} +0 -0
- /package/dist/{mds.samplescatterplot-PRR4TKYI.js.map → mds.samplescatterplot-ZDHQ3MKJ.js.map} +0 -0
- /package/dist/{mds.survivalplot-3OG4Y2B6.js.map → mds.survivalplot-R74DL2RA.js.map} +0 -0
- /package/dist/{oncomatrix-SO6S6IIB.js.map → oncomatrix-MOITJBII.js.map} +0 -0
- /package/dist/{oncomatrix.spec-VXTF44K5.js.map → oncomatrix.spec-NALJBPYS.js.map} +0 -0
- /package/dist/{plot.2dvaf-JW5OJJXV.js.map → plot.2dvaf-IE2EZEFA.js.map} +0 -0
- /package/dist/{plot.app-T3GVCFQ3.js.map → plot.app-HTW6TZEH.js.map} +0 -0
- /package/dist/{plot.barplot-2TYP6DPI.js.map → plot.barplot-NCQEPEOY.js.map} +0 -0
- /package/dist/{plot.boxplot-HOQHM7JF.js.map → plot.boxplot-WNKVBVJJ.js.map} +0 -0
- /package/dist/{plot.brainImaging-5AI7BSD4.js.map → plot.brainImaging-2Z3TOO6J.js.map} +0 -0
- /package/dist/{plot.disco-HNNZHK5Z.js.map → plot.disco-4JAEIAYK.js.map} +0 -0
- /package/dist/{plot.dzi-4OQSO7SY.js.map → plot.dzi-ZGLOVJJN.js.map} +0 -0
- /package/dist/{plot.ssgq-VZTTGECT.js.map → plot.ssgq-IHUILM43.js.map} +0 -0
- /package/dist/{plot.vaf2cov-ASEELRDV.js.map → plot.vaf2cov-ZYCQMD27.js.map} +0 -0
- /package/dist/{plot.wsi-MDWYLU4R.js.map → plot.wsi-3GISVBDH.js.map} +0 -0
- /package/dist/{polar-QSY6JG4P.js.map → polar-4AUAZHBV.js.map} +0 -0
- /package/dist/{polar2-FD6656VD.js.map → polar2-SRD4WWXU.js.map} +0 -0
- /package/dist/{profile.spec-V7EQBXT2.js.map → profile.spec-TOITKBBZ.js.map} +0 -0
- /package/dist/{profileBarchart-EIKHZAPD.js.map → profileBarchart-Z4SYIYBE.js.map} +0 -0
- /package/dist/{profileForms-NGFRXPFF.js.map → profileForms-RA7XQ2QT.js.map} +0 -0
- /package/dist/{profilePlot-2UFKJ2OC.js.map → profilePlot-4BM3XZVK.js.map} +0 -0
- /package/dist/{profileRadar-B2R7OV5F.js.map → profileRadar-EYBESEPI.js.map} +0 -0
- /package/dist/{profileRadarFacility-ILC7POCI.js.map → profileRadarFacility-FZYTFM26.js.map} +0 -0
- /package/dist/{proteomeAbundance-OF27N347.js.map → proteomeAbundance-65R6M4YQ.js.map} +0 -0
- /package/dist/{qualitative-CSUO2WG5.js.map → qualitative-E7WL6DN4.js.map} +0 -0
- /package/dist/{radar2-L2HGCUYR.js.map → radar2-I6FN5SUX.js.map} +0 -0
- /package/dist/{radarFacility2-HXUUTRYO.js.map → radarFacility2-GVK7PT3V.js.map} +0 -0
- /package/dist/{regression-Y4NYGZSA.js.map → regression-TIR5D354.js.map} +0 -0
- /package/dist/{regression.inputs-RWFIJLNF.js.map → regression.inputs-2AMJCJ3L.js.map} +0 -0
- /package/dist/{regression.inputs.term-QIU5SHTN.js.map → regression.inputs.term-D6D2QEUB.js.map} +0 -0
- /package/dist/{regression.inputs.values.table-FM6QTSEV.js.map → regression.inputs.values.table-M3IPLGDJ.js.map} +0 -0
- /package/dist/{regression.integration.spec-YRKKU7HL.js.map → regression.integration.spec-ROUSXLMH.js.map} +0 -0
- /package/dist/{regression.results-YUDCHUZJ.js.map → regression.results-YD5S74YS.js.map} +0 -0
- /package/dist/{regression.spec-G4GIIV32.js.map → regression.spec-4OXBBTNO.js.map} +0 -0
- /package/dist/{report-2N4FBR4Q.js.map → report-ETNALKTY.js.map} +0 -0
- /package/dist/{sampleScatter.spec-UIUYO4WR.js.map → sampleScatter.spec-LECMFMI2.js.map} +0 -0
- /package/dist/{sampleView-TOK5Y5KU.js.map → sampleView-B5TM7JOW.js.map} +0 -0
- /package/dist/{samplelst-YW5ZS3GJ.js.map → samplelst-GFQCG4SS.js.map} +0 -0
- /package/dist/{samplematrix-447BHSO7.js.map → samplematrix-OMTNWCJK.js.map} +0 -0
- /package/dist/{sc-O2PL3FL2.js.map → sc-MIEEZBWG.js.map} +0 -0
- /package/dist/{scatter-4DXHOWVY.js.map → scatter-ETOZ722F.js.map} +0 -0
- /package/dist/{scatter.integration.spec-ZPTM3AGQ.js.map → scatter.integration.spec-TS4PNRLX.js.map} +0 -0
- /package/dist/{selectGenomeWithTklst-3RLZFW62.js.map → selectGenomeWithTklst-Y5QIM2JB.js.map} +0 -0
- /package/dist/{singleCellCellType-3LQJXS7H.js.map → singleCellCellType-HOJHZF5W.js.map} +0 -0
- /package/dist/{singleCellCellType.unit.spec-UJM72SP4.js.map → singleCellCellType.unit.spec-MH5V3RPX.js.map} +0 -0
- /package/dist/{singleCellGeneExpression-JOWJWPIQ.js.map → singleCellGeneExpression-YVQ5TIKN.js.map} +0 -0
- /package/dist/{singleCellGeneExpression.unit.spec-VY5CGRZH.js.map → singleCellGeneExpression.unit.spec-BMFFT5HO.js.map} +0 -0
- /package/dist/{singleCellPlot-IVLVKOO6.js.map → singleCellPlot-3YFUYA2Y.js.map} +0 -0
- /package/dist/{singlecell-VJJZJZF7.js.map → singlecell-FK5JETW5.js.map} +0 -0
- /package/dist/{singlecell-VQJ2252L.js.map → singlecell-RL7V7DIC.js.map} +0 -0
- /package/dist/{snp-ALMKZKL2.js.map → snp-FT7HB3XN.js.map} +0 -0
- /package/dist/{snp.unit.spec-GJQBAHGQ.js.map → snp.unit.spec-CLYVYPPG.js.map} +0 -0
- /package/dist/{snplocus-WCNCMFWZ.js.map → snplocus-M5SEQGAC.js.map} +0 -0
- /package/dist/{spliceevent.a53ss.diagram-4Q4JF4RX.js.map → spliceevent.a53ss.diagram-EJ5CTRCZ.js.map} +0 -0
- /package/dist/{spliceevent.exonskip.diagram-IOYOKELT.js.map → spliceevent.exonskip.diagram-ETXMOHZ3.js.map} +0 -0
- /package/dist/{spliceevent.noeventdiagram-77ZCOHSF.js.map → spliceevent.noeventdiagram-S2O4ZM2Z.js.map} +0 -0
- /package/dist/{ssGSEA-QTXXIN4K.js.map → ssGSEA-6PMDQDTJ.js.map} +0 -0
- /package/dist/{ssGSEA.unit.spec-LQESATT3.js.map → ssGSEA.unit.spec-JD5T4R2N.js.map} +0 -0
- /package/dist/{summarizeCnvGeneexp-YKUQGDQF.js.map → summarizeCnvGeneexp-GCHNKTIU.js.map} +0 -0
- /package/dist/{summarizeGeneexpSurvival-ARGG5VDC.js.map → summarizeGeneexpSurvival-R2RYQZ3M.js.map} +0 -0
- /package/dist/{summarizeMutationCnv-FMZYT3EC.js.map → summarizeMutationCnv-LB2BIYRL.js.map} +0 -0
- /package/dist/{summarizeMutationDiagnosis-ZX7I46SC.js.map → summarizeMutationDiagnosis-3JUY75LM.js.map} +0 -0
- /package/dist/{summarizeMutationSurvival-RCFMTT43.js.map → summarizeMutationSurvival-VYLRWTCF.js.map} +0 -0
- /package/dist/{summary-QLL5YVI2.js.map → summary-2QQ72IEQ.js.map} +0 -0
- /package/dist/{summary.integration.spec-DHY6XCEJ.js.map → summary.integration.spec-XXU362UQ.js.map} +0 -0
- /package/dist/{summaryInput-ANCUQGIB.js.map → summaryInput-OZHZG3PV.js.map} +0 -0
- /package/dist/{sunburst-RDNFBOCK.js.map → sunburst-CMCJCANX.js.map} +0 -0
- /package/dist/{survival-BG7QV52L.js.map → survival-EBD4DHO7.js.map} +0 -0
- /package/dist/{survival-WSN36OQE.js.map → survival-ISLRRPKU.js.map} +0 -0
- /package/dist/{survival.integration.spec-37KAJ5IK.js.map → survival.integration.spec-FS7V4OXK.js.map} +0 -0
- /package/dist/{svgraph-A5WGHW4S.js.map → svgraph-KGLNUM7W.js.map} +0 -0
- /package/dist/{svmr-CYRHHWZF.js.map → svmr-NXZ5VLKH.js.map} +0 -0
- /package/dist/{table-VHO7E5PI.js.map → table-ISOQOI6C.js.map} +0 -0
- /package/dist/{termCollection-HSVSH7TJ.js.map → termCollection-7ZSU3I45.js.map} +0 -0
- /package/dist/{termCollection-E4Q6GLXN.js.map → termCollection-V2A5BDQB.js.map} +0 -0
- /package/dist/{termCollection.unit.spec-ZCE3TUMS.js.map → termCollection.unit.spec-6VLCJGOU.js.map} +0 -0
- /package/dist/{tk-GPRHDN4K.js.map → tk-6AB6XYIE.js.map} +0 -0
- /package/dist/{tp.ui-LTUA3FSL.js.map → tp.ui-2O4UW5N7.js.map} +0 -0
- /package/dist/{tvs.dt-G43PAAKD.js.map → tvs.dt-CY6TOQVB.js.map} +0 -0
- /package/dist/{tvs.dtcnv.categorical-UHDS2TGZ.js.map → tvs.dtcnv.categorical-AYQ432TW.js.map} +0 -0
- /package/dist/{tvs.dtcnv.continuous-ZNGYQKTD.js.map → tvs.dtcnv.continuous-XVDL6SG3.js.map} +0 -0
- /package/dist/{tvs.dtfusion-JBEEUDUS.js.map → tvs.dtfusion-V3AV7A6Q.js.map} +0 -0
- /package/dist/{tvs.dtsnvindel-XXN5Q7RN.js.map → tvs.dtsnvindel-XM3NXIT7.js.map} +0 -0
- /package/dist/{tvs.dtsv-MO6L7HHV.js.map → tvs.dtsv-Z2GYRINW.js.map} +0 -0
- /package/dist/{tvs.samplelst-HKY6UUJM.js.map → tvs.samplelst-C4FB63G7.js.map} +0 -0
- /package/dist/{tvs.termCollection-TY6FPL25.js.map → tvs.termCollection-VHTSC2ST.js.map} +0 -0
- /package/dist/{violin-YHE3WSGR.js.map → violin-KGGTUQFF.js.map} +0 -0
- /package/dist/{violin.integration.spec-F2UD7BHC.js.map → violin.integration.spec-5EW6PLJX.js.map} +0 -0
- /package/dist/{violin.interactivity-LVDTDEPQ.js.map → violin.interactivity-RI4RURGO.js.map} +0 -0
- /package/dist/{violin.renderer-IIEIUGRI.js.map → violin.renderer-EWU2IFZE.js.map} +0 -0
- /package/dist/{vocabulary-WQRYXBRO.js.map → vocabulary-VLIGC7OP.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../dom/animation.js", "../dom/axisstyle.js", "../dom/boxplot.js", "../dom/checkbox.js", "../src/client.js", "../common/1stGenetk.js", "../dom/ColorScale/ColorScaleMenu.ts", "../dom/ColorScale/ColorScale.ts", "../dom/ColorScale/colorScale.helpers.ts", "../dom/cnvConfig.ts", "../dom/table.ts", "../filter/tvs.js", "../filter/filter.utils.js", "../filter/filter.renderer.js", "../filter/filter.interactivity.js", "../termdb/Vocab.js", "../dom/sayerror.ts", "../termdb/TermdbVocab.js", "../termdb/FrontendVocab.js", "../termdb/vocabulary.js", "../filter/FilterClass.js", "../filter/FilterStateless.js", "../../node_modules/html-to-image/src/util.ts", "../../node_modules/html-to-image/src/clone-pseudos.ts", "../../node_modules/html-to-image/src/mimes.ts", "../../node_modules/html-to-image/src/dataurl.ts", "../../node_modules/html-to-image/src/clone-node.ts", "../../node_modules/html-to-image/src/embed-resources.ts", "../../node_modules/html-to-image/src/embed-images.ts", "../../node_modules/html-to-image/src/apply-style.ts", "../../node_modules/html-to-image/src/embed-webfonts.ts", "../../node_modules/html-to-image/src/index.ts", "../filter/FilterRxComp.js", "../filter/FilterPrompt.js", "../dom/variantConfig.ts", "../common/svg.download.js", "../dom/downloadMenu.ts", "../dom/downloadTextfile.js", "../dom/fillbar.js", "../tw/geneExpression.ts", "../tw/singleCellGeneExpression.ts", "../dom/genesearch.ts", "../dom/GeneSetEdit/addButton.ts", "../dom/GeneSetEdit/radioWithContent.ts", "../dom/GeneSetEdit/GenesMenu.ts", "../dom/GeneSetEdit/GeneSetEditUI.ts", "../dom/html.legend.js", "../dom/InvalidDataUI.ts", "../dom/sketchGm.ts", "../dom/isoformSelect.ts", "../dom/LegendCircleReference.ts", "../dom/maxLabelWidth.ts", "../tw/categorical.ts", "../tw/TwBase.ts", "../tw/isoformExpression.ts", "../tw/metaboliteIntensity.ts", "../tw/proteomeAbundance.ts", "../tw/date.ts", "../tw/ssGSEA.ts", "../tw/dnaMethylation.ts", "../tw/numeric.ts", "../tw/snp.ts", "../tw/singleCellCellType.ts", "../tw/qualitative.ts", "../tw/collection/NumericTermCollection.ts", "../tw/collection/QualTermCollection.ts", "../tw/collection/CollectionCont.ts", "../tw/collection/CollectionQual.ts", "../tw/collection/CollectionBase.ts", "../termdb/handlers/geneVariant.ts", "../termsetting/handlers/geneVariant.ts", "../tw/geneVariant.ts", "../tw/TwRouter.ts", "../termsetting/utils.ts", "../node_modules/balanced-match/src/index.ts", "../node_modules/brace-expansion/src/index.ts", "../node_modules/minimatch/src/assert-valid-pattern.ts", "../node_modules/minimatch/src/brace-expressions.ts", "../node_modules/minimatch/src/unescape.ts", "../node_modules/minimatch/src/ast.ts", "../node_modules/minimatch/src/escape.ts", "../node_modules/minimatch/src/index.ts", "../termsetting/TermSettingView.ts", "../termsetting/TermSettingActions.ts", "../termsetting/TermSetting.ts", "../termsetting/TermSettingApi.ts", "../dom/MultiTermWrapperEditUI.ts", "../dom/numericAxis.js", "../dom/radiobutton.ts", "../dom/sandbox.ts", "../dom/search.ts", "../plots/AppBase.ts", "../termdb/tree.js", "../termdb/TermTypeSearch.ts", "../termdb/store.ts", "../termdb/submenu.js", "../termdb/search.js", "../termdb/app.ts", "../dom/select2Terms.js", "../dom/shapes.js", "../dom/ssmLink.ts", "../dom/svg.legend.js", "../dom/svg.scroll.js", "../dom/table2col.js", "../dom/toggleButtons.ts", "../dom/zoom.js", "../mass/charts.js", "../plots/volcano/settings/defaults.ts", "../mass/groups.js", "../plots/controls.config.js", "../plots/controls.js", "../plots/PlotBase.ts", "../plots/barchart.js", "../plots/barchart.events.js", "../dom/summary/ListSamples.ts", "../filter/tvs.dt.js"],
|
|
4
|
-
"sourcesContent": ["export function appear(d, display) {\n\td.style('opacity', 0)\n\t\t.style('display', display || 'block')\n\t\t.transition()\n\t\t.style('opacity', 1)\n}\n\nexport function disappear(d, remove) {\n\td.style('opacity', 1)\n\t\t.transition()\n\t\t.style('opacity', 0)\n\t\t.call(() => {\n\t\t\tif (remove) {\n\t\t\t\td.remove()\n\t\t\t} else {\n\t\t\t\td.style('display', 'none').style('opacity', 1)\n\t\t\t}\n\t\t})\n}\n", "export function axisstyle(p) {\n\tif (!p || !p.axis) return\n\tif (!p.color) {\n\t\tp.color = '#545454'\n\t}\n\tp.axis.selectAll('line').attr('stroke', p.color).attr('shape-rendering', 'crispEdges')\n\tp.axis\n\t\t.selectAll('path')\n\t\t.attr('fill', 'none')\n\t\t.attr('stroke', p.showline ? p.color : 'none')\n\t\t.attr('stroke-width', p.showline ? 1 : 0)\n\t\t.attr('shape-rendering', 'crispEdges')\n\tp.axis\n\t\t.selectAll('text')\n\t\t.style('cursor', 'default')\n\t\t.attr('font-size', p.fontsize ? p.fontsize + 'px' : '12px')\n\t\t.attr('fill', p.color)\n}\n", "/*\nadapted from block.mds.geneboxplot.js, but can be hard to reuse over there\n\narguments:\n\nbp: {}\n\tgenerated by server side boxplot_getvalue()\n\tbp.label:str\n\t------- Options not returned in server response ------- \n\toptional; if present, prints the label to the left of the row\n\toptional: if present, set the radius of the outlier circles\ng:\n\tsvg <g> in which a horizontal boxplot is rendered from left to right\ncolor:\n\tline/text color\nscale:\n\tcallback, v=>{return fxn(v)}\nrowheight:\n\tint\nlabpad:\n\tint, horizontal space between label <text> and boxplot <g>\nlabColor: \n\tstr, label text color. Default is color arg\nrectFill:\n\tstr, fill color of the box. Default is white\n*/\nexport function drawBoxplot({ bp, g, color, scale, rowheight, labpad, labColor = color }) {\n\tif (bp.label) {\n\t\tbp.labelG = g\n\t\t\t.append('text')\n\t\t\t.attr('font-family', 'Arial')\n\t\t\t.attr('text-anchor', 'end')\n\t\t\t.attr('dominant-baseline', 'central')\n\t\t\t.attr('fill', labColor)\n\t\t\t.attr('x', -labpad)\n\t\t\t.attr('y', rowheight / 2)\n\t\t\t.attr('font-size', Math.min(15, rowheight))\n\t\t\t.text(bp.label)\n\t}\n\n\tif (bp.w1 != undefined || bp.w2 != undefined) {\n\t\t// Undefined when there is no distribution\n\t\t// has valid values for boxplot, could be missing\n\t\tconst w1 = scale(bp.w1)\n\t\tconst w2 = scale(bp.w2)\n\t\tconst p25 = scale(bp.p25)\n\t\tconst p50 = scale(bp.p50)\n\t\tconst p75 = scale(bp.p75)\n\t\tbp.hline = g\n\t\t\t.append('line')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('shape-rendering', 'crispEdges')\n\t\t\t.attr('x1', w1)\n\t\t\t.attr('x2', w2)\n\t\t\t.attr('y1', rowheight / 2)\n\t\t\t.attr('y2', rowheight / 2)\n\t\tbp.linew1 = g\n\t\t\t.append('line')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('shape-rendering', 'crispEdges')\n\t\t\t.attr('x1', w1)\n\t\t\t.attr('x2', w1)\n\t\t\t.attr('y1', 0)\n\t\t\t.attr('y2', rowheight)\n\t\tbp.linew2 = g\n\t\t\t.append('line')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('shape-rendering', 'crispEdges')\n\t\t\t.attr('x1', w2)\n\t\t\t.attr('x2', w2)\n\t\t\t.attr('y1', 0)\n\t\t\t.attr('y2', rowheight)\n\t\tbp.box = g\n\t\t\t.append('rect')\n\t\t\t.attr('fill', bp?.rectFill || 'white')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('shape-rendering', 'crispEdges')\n\t\t\t.attr('x', p25)\n\t\t\t.attr('y', 0)\n\t\t\t.attr('width', p75 - p25)\n\t\t\t.attr('height', rowheight)\n\t\tbp.linep50 = g\n\t\t\t.append('line')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('shape-rendering', 'crispEdges')\n\t\t\t.attr('x1', p50)\n\t\t\t.attr('x2', p50)\n\t\t\t.attr('y1', 0)\n\t\t\t.attr('y2', rowheight)\n\t}\n\t// outliers\n\tfor (const d of bp.out) {\n\t\tg.append('circle')\n\t\t\t.attr('stroke', color)\n\t\t\t.attr('fill', 'white')\n\t\t\t.attr('fill-opacity', 0)\n\t\t\t.attr('cx', scale(d.value))\n\t\t\t.attr('cy', rowheight / 2)\n\t\t\t.attr('r', bp?.radius || rowheight / 3)\n\t\t/*\n\t\t\t.on('mouseover', () => {\n\t\t\t})\n\t\t\t.on('mouseout', () => {\n\t\t\t})\n\t\t\t*/\n\n\t\t/*\n\t\tif (plot.clicksample) {\n\t\t\td.circle.on('click', () => {\n\t\t\t})\n\t\t}\n\t\t*/\n\t}\n}\n", "/* on/off switch\n\n******* required\n.holder\n.callback()\n\tasync\n\tone boolean argument corresponding to whether the box is checked or not\n******* optional\n.divstyle{}\n.labeltext\n.title\n.checked\n\tif set to true, box is checked by default\n.id\n.testid\n sets input data-testid=\"\", for testing\n*/\nexport function make_one_checkbox(arg) {\n\tconst { holder, labeltext, title, callback, checked, divstyle, id, testid } = arg\n\n\tconst div = holder.append('div')\n\tif (divstyle) {\n\t\tfor (const k in divstyle) div.style(k, divstyle[k])\n\t}\n\tconst label = div.append('label').on('mousedown', event => {\n\t\t// this fix allows clicking on a checkbox of a secondary menu not to hide the primary menu, e.g. in geneset edit ui \"top mutated\" submenu options\n\t\tevent.stopPropagation()\n\t})\n\tconst input = label\n\t\t.append('input')\n\t\t.attr('type', 'checkbox')\n\t\t.property('checked', checked)\n\t\t.on('input', async () => {\n\t\t\tinput.property('disabled', true)\n\t\t\tawait callback(input.property('checked'))\n\t\t\tinput.property('disabled', false)\n\t\t})\n\tif (title) input.attr('title', title)\n\tif (id) input.attr('id', id)\n\tif (testid) input.attr('data-testid', testid)\n\tif (labeltext) label.append('span').html(' ' + labeltext)\n\treturn input\n}\n", "///////////////////\n//\n// all client-side stuff, including DOM\n//\n///////////////////\n\nimport { scaleLinear } from 'd3-scale'\nimport { select as d3select, selectAll as d3selectAll } from 'd3-selection'\nimport { rgb as d3rgb } from 'd3-color'\nimport * as common from '#shared/common.js'\nimport { set_base_zindex } from '#common/globals'\nimport { dofetch, dofetch2, dofetch3 } from '../common/dofetch'\n// support client code that import dofetch* from client.js\n// TODO: update affected code to import dofetch* directly from common/dofetch.js\nexport { dofetch, dofetch2, dofetch3 }\nimport { Menu, make_table_2col, fillbar, axisstyle, sayerror } from '#dom'\nexport { Menu, axisstyle, fillbar, make_table_2col, sayerror }\nimport { first_genetrack_tolist } from '../common/1stGenetk'\nexport { first_genetrack_tolist }\n\nexport const font = 'Arial'\nexport const unspecified = 'Unspecified'\nexport const colorinframe = 'green'\nexport const coloroutframe = '#858585'\nexport const colorbgleft = '#FCE3B8'\nexport const colorbgright = '#D2E2FC'\nexport const colorantisense = 'red'\nexport const colorctx = '#DE3336'\nexport const textlensf = 0.6 // to replace n.getBBox().width for detecting filling font size which breaks in chrome\n\nexport let base_zindex = null\n\n// things that used to be in client.js but now have been moved to common\nexport const tkt = common.tkt\nexport const gmmode = common.gmmode\n\nexport function appear(d, display) {\n\td.style('opacity', 0)\n\t\t.style('display', display || 'block')\n\t\t.transition()\n\t\t.style('opacity', 1)\n}\n\nexport function disappear(d, remove) {\n\td.style('opacity', 1)\n\t\t.transition()\n\t\t.style('opacity', 0)\n\t\t.call(() => {\n\t\t\tif (remove) {\n\t\t\t\td.remove()\n\t\t\t} else {\n\t\t\t\td.style('display', 'none').style('opacity', 1)\n\t\t\t}\n\t\t})\n}\n\nexport function newpane(pm) {\n\t/*\n\tparameter\n\n\t.setzindex\n\t\tquick dirty way to set the global variable base_zindex\n\n\t.x\n\t.y\n\t.toshrink\n\t\tbool\n\t.close\n\t\tcallback\n\t.closekeep\n\t\tbool\n\t.headpad\n\t\theader label bar padding\n\n\t*/\n\n\tif (pm.setzindex) {\n\t\t/*\n\t\tdirty fix\n\t\t*/\n\t\tbase_zindex = pm.setzindex\n\t\tset_base_zindex(pm.setzindex)\n\t\treturn\n\t}\n\n\tconst dur = 300\n\tconst pp = {}\n\tconst body = d3select(document.body)\n\tpp.pane = body\n\t\t.append('div')\n\t\t.attr('class', 'sja_pane')\n\t\t.style('left', pm.x + window.pageXOffset + 'px')\n\t\t.style('top', pm.y + window.pageYOffset + 'px')\n\t\t.style('opacity', 0)\n\n\tif (pm.$id) {\n\t\tpp.pane.attr('id', pm.$id)\n\t}\n\n\tif (base_zindex) {\n\t\t// fixed, from embedding instructions\n\t\tpp.pane.style('z-index', base_zindex)\n\t}\n\n\tpp.pane.transition().duration(dur).style('opacity', 1)\n\n\tconst toprow = pp.pane.append('div').on('mousedown', event => {\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tconst oldx = Number.parseInt(pp.pane.style('left')),\n\t\t\toldy = Number.parseInt(pp.pane.style('top'))\n\t\tconst x0 = event.clientX,\n\t\t\ty0 = event.clientY\n\t\tbody.on('mousemove', event => {\n\t\t\tpp.pane.style('left', oldx + event.clientX - x0 + 'px').style('top', oldy + event.clientY - y0 + 'px')\n\t\t})\n\t\tbody.on('mouseup', function () {\n\t\t\tbody.on('mouseup', null).on('mousemove', null)\n\t\t})\n\t\t// order of precedence, among all panes\n\t\tdocument.body.appendChild(pp.pane.node())\n\t})\n\n\tconst butt = toprow\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption')\n\t\t.style('display', 'inline-block')\n\t\t.style('padding', '4px 10px')\n\t\t.style('margin', '0px')\n\t\t.style('border-right', 'solid 1px white')\n\t\t.style('cursor', 'default')\n\t\t.style('font-size', '1.5em')\n\t\t.on('mousedown', event => {\n\t\t\tdocument.body.dispatchEvent(new Event('mousedown'))\n\t\t\tevent.stopPropagation()\n\t\t})\n\n\tif (pm.toshrink) {\n\t\tpp.mini = false\n\t\tbutt.html('━').on('click', () => {\n\t\t\tbutt.html(pp.mini ? '━' : '◽')\n\t\t\tif (pp.mini) {\n\t\t\t\tappear(pp.body)\n\t\t\t} else {\n\t\t\t\tdisappear(pp.body)\n\t\t\t}\n\t\t\tpp.mini = !pp.mini\n\t\t})\n\t} else {\n\t\tbutt.html('×')\n\t\tif (pm.close) {\n\t\t\t// custom callback on close button\n\t\t\tbutt.on('click', pm.close)\n\t\t} else if (pm.closekeep) {\n\t\t\t// hide and keep to bring it on later\n\t\t\tbutt.on('click', () => {\n\t\t\t\tpp.pane\n\t\t\t\t\t.transition()\n\t\t\t\t\t.duration(dur)\n\t\t\t\t\t.style('opacity', 0)\n\t\t\t\t\t.call(() => pp.pane.style('display', 'none'))\n\t\t\t})\n\t\t} else {\n\t\t\t// close and remove pane from page\n\t\t\tbutt.on('click', () => {\n\t\t\t\tpp.pane\n\t\t\t\t\t.transition()\n\t\t\t\t\t.duration(dur)\n\t\t\t\t\t.style('opacity', 0)\n\t\t\t\t\t.call(() => pp.pane.remove())\n\t\t\t})\n\t\t}\n\t}\n\t// where you can write\n\tpp.header = toprow\n\t\t.append('div')\n\t\t.style('display', 'inline-block')\n\t\t.style('font-family', font)\n\t\t.style('padding', pm.headpad || '5px 10px')\n\tpp.body = pp.pane.append('div').style('font-family', font)\n\treturn pp\n}\n\nexport function getdomaintypes(gm) {\n\tif (!gm.pdomains) return []\n\n\tconst types = new Map()\n\t// k: domain.name+domain.description\n\t// v: {} attributes of this type of domain\n\n\tfor (const i of gm.pdomains) {\n\t\tconst key = i.name + i.description\n\t\tif (types.has(key)) {\n\t\t\ttypes.get(key).start = Math.min(types.get(key).start, i.start)\n\t\t} else {\n\t\t\ttypes.set(key, {\n\t\t\t\tname: i.name,\n\t\t\t\tdescription: i.description,\n\t\t\t\tcolor: i.color,\n\t\t\t\tstart: i.start,\n\t\t\t\tiscustom: i.iscustom,\n\t\t\t\turl: i.url,\n\t\t\t\tpmid: i.pmid,\n\t\t\t\tCDD: i.CDD,\n\t\t\t\tPfam: i.Pfam,\n\t\t\t\tSMART: i.SMART,\n\t\t\t\tCOG: i.COG,\n\t\t\t\tPRK: i.PRK,\n\t\t\t\tCurated_at_NCBI: i.Curated_at_NCBI\n\t\t\t})\n\t\t}\n\t}\n\tconst lst = []\n\tfor (const [key, domaintype] of types) {\n\t\tdomaintype.key = key\n\t\tdomaintype.fill = domaintype.color\n\t\tdomaintype.stroke = d3rgb(domaintype.color).darker(1).toString()\n\t\tdelete domaintype.color\n\t\tlst.push(domaintype)\n\t}\n\tlst.sort((a, b) => a.start - b.start)\n\treturn lst\n}\n\nexport function newpane3(x, y, genomes) {\n\tconst pane = newpane({ x: x, y: y })\n\tconst inputdiv = pane.body.append('div').style('margin', '40px 20px 20px 20px')\n\tconst p = inputdiv.append('p')\n\tp.append('span').html('Genome ')\n\tconst gselect = p.append('select')\n\tfor (const n in genomes) {\n\t\tgselect.append('option').text(n)\n\t}\n\tconst filediv = inputdiv.append('div').style('margin', '20px 0px')\n\tconst saydiv = pane.body.append('div').style('margin', '10px 20px')\n\tconst visualdiv = pane.body.append('div').style('margin', '20px')\n\treturn [pane, inputdiv, gselect.node(), filediv, saydiv, visualdiv]\n}\n\nexport function to_svg(svg, name, opts = {}) {\n\tif (opts.apply_dom_styles) {\n\t\topts.svgClone = svg.cloneNode(true)\n\t\tconst clone = d3select(opts.svgClone) // make it easier to apply style below\n\n\t\t// TODO: may use opts.excludeSelector instead of harcoded classname?\n\t\tfor (const elem of opts.svgClone.querySelectorAll('.sjpp-exclude-svg-download')) {\n\t\t\telem.remove()\n\t\t}\n\n\t\tconst styles = window.getComputedStyle(svg)\n\t\tfor (const s of styles) {\n\t\t\tclone.style(s, styles.getPropertyValue(s))\n\t\t}\n\t}\n\n\tconst a = document.createElement('a')\n\tdocument.body.appendChild(a)\n\n\ta.addEventListener(\n\t\t'click',\n\t\tfunction () {\n\t\t\tconst serializer = new XMLSerializer()\n\t\t\tconst svg_blob = new Blob([serializer.serializeToString(opts.svgClone ? opts.svgClone : svg)], {\n\t\t\t\ttype: 'image/svg+xml'\n\t\t\t})\n\t\t\ta.download = name + '.svg'\n\t\t\ta.href = URL.createObjectURL(svg_blob)\n\t\t\tdocument.body.removeChild(a)\n\t\t},\n\t\tfalse\n\t)\n\ta.click()\n}\n\nexport function filetypeselect(holder) {\n\tconst s = holder.append('select')\n\ts.append('option').text('SNV and indel') // 0\n\ts.append('option').text('SV (tabular format)') // 1\n\ts.append('option').text('Fusion gene (tabular format)') // 2\n\ts.append('option').text('ITD') // 3\n\ts.append('option').text('Deletion, intragenic') // 4\n\ts.append('option').text('Truncation') // 5\n\ts.append('option').text('CNV, gene-level')\n\t// TODO vcf, new tabular format for fusion\n\treturn s\n}\n\nexport function export_data(title, lst, posx = 1, posy = 1, rows = 10, cols = 100, div = null) {\n\t// lst: {label, text}\n\n\tlet body // holder of ui\n\tif (!div) {\n\t\tconst pane = newpane({\n\t\t\tx: (window.innerWidth / 2 - 200) * posx,\n\t\t\ty: (window.innerHeight / 2 - 150) * posy\n\t\t})\n\t\tpane.header.text(title)\n\t\tbody = pane.body\n\t} else {\n\t\tdiv.append('p').text(title)\n\t\tbody = div.append('div')\n\t}\n\n\tfor (const w of lst) {\n\t\tconst div = body.append('div').style('margin-top', '10px')\n\t\tif (w.label) {\n\t\t\tdiv.append('div').text(w.label).style('margin', '5px')\n\t\t}\n\t\tbody.append('textarea').text(w.text).attr('readonly', 1).attr('rows', rows).attr('cols', cols)\n\t}\n\tbody\n\t\t.append('p')\n\t\t.style('font-size', '.7em')\n\t\t.text('Click on the text box above and press Ctrl-A to select all text for copy-pasting.')\n}\n\nexport function flyindi(from, to) {\n\tconst p1 = from.node().getBoundingClientRect()\n\tconst p2 = to.node().getBoundingClientRect()\n\tconst d = d3select(document.body)\n\t\t.append('div')\n\t\t.style('position', 'absolute')\n\t\t.style('border', 'solid 1px black')\n\t\t.style('left', p1.left + window.pageXOffset + 'px')\n\t\t.style('top', p1.top + window.pageYOffset + 'px')\n\t\t.style('width', p1.width + 'px')\n\t\t.style('height', p1.height + 'px')\n\tif (base_zindex) {\n\t\td.style('z-index', base_zindex + 3)\n\t}\n\td.transition()\n\t\t.duration(500)\n\t\t.style('left', p2.left + window.pageXOffset + 'px')\n\t\t.style('top', p2.top + window.pageYOffset + 'px')\n\t\t.style('width', p2.width + 'px')\n\t\t.style('height', p2.height + 'px')\n\t\t.on('end', () => d.remove())\n}\n\nexport function labelbox(arg) {\n\t/* a box with label overlapping its border\n\t- holder\n\t- label\n\t- color\n\t*/\n\tconst fontsize = 16\n\tif (!arg.color) {\n\t\targ.color = '#ccc'\n\t}\n\tconst d0 = arg.holder\n\t\t.append('div')\n\t\t.style('position', 'relative')\n\t\t.style('padding-top', fontsize / 2 + 'px')\n\tif (arg.margin) {\n\t\td0.style('margin', arg.margin)\n\t}\n\tconst bin = d0\n\t\t.append('div')\n\t\t.style('border', 'solid 1px ' + arg.color)\n\t\t.style('padding', fontsize + 'px')\n\t\t.style('padding-bottom', fontsize / 2 + 'px')\n\td0.append('div')\n\t\t.text(arg.label)\n\t\t.style('position', 'absolute')\n\t\t.style('left', '15px')\n\t\t.style('top', '0px')\n\t\t.style('background-color', 'white')\n\t\t.style('color', arg.color)\n\t\t.style('font-family', font)\n\t\t.style('font-size', fontsize + 'px')\n\t\t.style('padding', '0px 10px')\n\treturn bin\n}\n\nexport function category2legend(categories, holder) {\n\t// bound to tk logic\n\tholder.selectAll('*').remove()\n\tfor (const key in categories) {\n\t\tconst c = categories[key]\n\t\tconst div = holder\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('white-space', 'nowrap')\n\t\t\t.style('padding', '5px 20px 5px 0px')\n\t\tdiv\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('background-color', c.color)\n\t\t\t.style('margin-right', '5px')\n\t\t\t.style('padding', '0px 4px')\n\t\t\t.html(' ')\n\t\tdiv.append('div').style('display', 'inline-block').style('color', c.color).text(c.label)\n\t}\n}\n\nexport function bulk_badline(header, lines) {\n\t// surpress warnings on selected sites\n\tif (window.location.hostname == 'viz.stjude.cloud' || window.location.hostname == 'pecan.stjude.cloud') return\n\tif (window.sessionStorage.getItem('suppressErrors')?.includes(`\"bulk-bad-lines\"`)) return\n\n\tconst np = newpane({ x: 400, y: 60 })\n\tnp.body.style('margin', '20px 10px 10px 10px')\n\tnp.header.text(lines.length + ' line' + (lines.length > 1 ? 's' : '') + ' rejected, click to check')\n\tif (lines.length <= 50) {\n\t\t// small # of lines, show link for each\n\t\tfor (const [number, err, line] of lines) {\n\t\t\tnp.body\n\t\t\t\t.append('div')\n\t\t\t\t.classed('sja_clbtext', true)\n\t\t\t\t.style('margin', '3px')\n\t\t\t\t.text('Line ' + number + ': ' + err)\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tconst n2 = newpane({ x: 500, y: 60 })\n\t\t\t\t\tn2.header.text('Line ' + number)\n\t\t\t\t\tn2.body.style('margin', '10px')\n\t\t\t\t\tconst t = n2.body.append('table').style('border-spacing', '1px').style('border-collapse', 'separate')\n\t\t\t\t\tlet fl = true\n\t\t\t\t\tfor (let i = 0; i < header.length; i++) {\n\t\t\t\t\t\tconst tr = t.append('tr')\n\t\t\t\t\t\tif (fl) {\n\t\t\t\t\t\t\ttr.style('background-color', '#ededed')\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfl = !fl\n\t\t\t\t\t\ttr.append('td').text(header[i])\n\t\t\t\t\t\ttr.append('td').text(line[i] == undefined ? '' : line[i])\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t\treturn\n\t}\n\t// group lines by reasons of reject\n\tconst reason = new Map()\n\tfor (const [number, err, line] of lines) {\n\t\tif (!reason.has(err)) {\n\t\t\treason.set(err, [])\n\t\t}\n\t\treason.get(err).push({ number: number, line: line })\n\t}\n\n\tconst lst = [...reason]\n\n\tlst.sort((a, b) => b[1].length - a[1].length)\n\n\tfor (const [thisreason, linelst] of lst) {\n\t\tconst line1 = linelst[0]\n\t\tnp.body\n\t\t\t.append('div')\n\t\t\t.classed('sja_menuoption', true)\n\t\t\t.style('margin', '5px')\n\t\t\t.text(\n\t\t\t\t'Line ' + line1.number + ': ' + thisreason + (linelst.length > 1 ? ' (total ' + linelst.length + ' lines)' : '')\n\t\t\t)\n\t\t\t.on('click', () => {\n\t\t\t\tconst n2 = newpane({ x: 500, y: 60 })\n\t\t\t\tn2.header.text('Line ' + line1.number)\n\t\t\t\tconst t = n2.body.style('margin', '10px').append('table')\n\t\t\t\tlet fl = true\n\t\t\t\tfor (let i = 0; i < header.length; i++) {\n\t\t\t\t\tconst tr = t.append('tr')\n\t\t\t\t\tif (fl) {\n\t\t\t\t\t\ttr.style('background-color', '#ededed')\n\t\t\t\t\t}\n\t\t\t\t\tfl = !fl\n\t\t\t\t\ttr.append('td').text(header[i])\n\t\t\t\t\ttr.append('td').text(line1.line[i] == undefined ? '' : line1.line[i])\n\t\t\t\t}\n\t\t\t})\n\t}\n}\n\nexport function ensureisblock(b) {\n\tif (!b) return 'No Block{} object given'\n\tif (typeof b != 'object') return 'Block is not an object'\n\tif (!b.error) return 'method block.error() missing'\n\tif (!b.genome) return 'block.genome missing'\n\treturn null\n}\n\nexport function mclasscolorchangeui(tip) {\n\ttip.d.append('p').html('<span style=\"color:#858585;font-size:.7em\">EXAMPLE</span> M ; red')\n\tconst input = tip.d\n\t\t.append('textarea')\n\t\t.attr('cols', 25)\n\t\t.attr('rows', 5)\n\t\t.attr('placeholder', 'One class per line, join color and class code by semicolon.')\n\tconst row = tip.d.append('div')\n\trow\n\t\t.append('button')\n\t\t.text('Submit')\n\t\t.on('click', () => {\n\t\t\tconst str = input.property('value').trim()\n\t\t\tif (!str) return\n\t\t\terrdiv.text('')\n\t\t\tconst good = []\n\t\t\tfor (const line of str.split('\\n')) {\n\t\t\t\tconst l = line.split(';')\n\t\t\t\tif (l.length != 2) return errdiv.text('no separator in line: ' + line)\n\t\t\t\tconst c = l[0].trim()\n\t\t\t\tconst color = l[1].trim()\n\t\t\t\tif (!c || !color) return errdiv.text('wrong line: ' + line)\n\t\t\t\tif (!common.mclass[c]) return errdiv.text('wrong class: ' + c)\n\t\t\t\tgood.push([c, color])\n\t\t\t}\n\t\t\tif (good.length) {\n\t\t\t\tfor (const [c, color] of good) {\n\t\t\t\t\tcommon.mclass[c].color = color\n\t\t\t\t}\n\t\t\t\tmclasscolor2table(table)\n\t\t\t\terrdiv.text('New color set!')\n\t\t\t}\n\t\t})\n\trow\n\t\t.append('button')\n\t\t.text('Clear')\n\t\t.on('click', () => {\n\t\t\tinput.property('value', '')\n\t\t\terrdiv.text('')\n\t\t})\n\tconst errdiv = row.append('span').style('margin-left', '10px')\n\n\tconst table = tip.d.append('div').style('margin-top', '5px')\n\tmclasscolor2table(table)\n\n\ttip.d\n\t\t.append('p')\n\t\t.style('font-size', '.8em')\n\t\t.html(\n\t\t\t'<a href=https://en.wikipedia.org/wiki/Web_colors target=_blank>Use color names</a>, or #ff0000 or rgb(255,0,0)'\n\t\t)\n}\n\nexport function mclasscolor2table(table, snvonly) {\n\ttable.style('border-spacing', '3px').selectAll('*').remove()\n\tconst tr = table.append('tr').style('color', '#858585').style('font-size', '.7em')\n\ttr.append('td').text('CLASS')\n\ttr.append('td').attr('colspan', 2).text('LABEL, COLOR')\n\tfor (const k in common.mclass) {\n\t\tconst c = common.mclass[k]\n\t\tif (snvonly && c.dt != common.dtsnvindel) continue\n\n\t\t// Blank class color is white\n\n\t\tconst tr = table.append('tr')\n\t\ttr.append('td').text(k)\n\t\t{\n\t\t\tconst dot = tr\n\t\t\t\t.append('td')\n\t\t\t\t.append('span')\n\t\t\t\t.attr('class', 'sja_mcdot')\n\t\t\t\t.style('background-color', c.color)\n\t\t\t\t.html(' ')\n\t\t\tif (k == 'Blank') dot.style('border', 'solid 1px #eee')\n\t\t}\n\t\ttr.append('td')\n\t\t\t.text(c.label)\n\t\t\t.style('color', k == 'Blank' ? '#ddd' : c.color)\n\t}\n}\n\n// bigwig track\nexport const bwSetting = {\n\theight: 1,\n\tpcolor: 2,\n\tncolor: 3,\n\tpcolor2: 4,\n\tncolor2: 5,\n\tautoscale: 6,\n\tfixedscale: 7,\n\tpercentilescale: 8,\n\tnodotplot: 9,\n\tusedotplot: 10,\n\tusedividefactor: 11,\n\tnodividefactor: 12\n}\n\nexport function tkexists(t, tklst) {\n\t// return the tkobj found in the list\n\tfor (const t0 of tklst) {\n\t\tif (t0.type != t.type) continue\n\t\tswitch (t.type) {\n\t\t\tcase tkt.bigwig:\n\t\t\tcase tkt.bedj:\n\t\t\tcase tkt.junction:\n\t\t\tcase tkt.mdsjunction:\n\t\t\tcase tkt.bampile:\n\t\t\tcase tkt.hicstraw:\n\t\t\tcase tkt.expressionrank:\n\t\t\t\t// single file\n\t\t\t\tif ((t.file && t.file == t0.file) || (t.url && t.url == t0.url)) {\n\t\t\t\t\treturn t0\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase tkt.bigwigstranded:\n\t\t\t\tif (t.strand1 && t0.strand1 && t.strand1.file == t0.strand1.file && t.strand1.url == t0.strand1.url) {\n\t\t\t\t\tif (t.strand2 && t0.strand2 && t.strand2.file == t0.strand2.file && t.strand2.url == t0.strand2.url) {\n\t\t\t\t\t\treturn t0\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t// TODO pgv ds-vcf\n\t\t}\n\t}\n\treturn null\n}\n\nexport function ranksays(v) {\n\tif (v >= 100) return 'HIGHEST'\n\tif (v >= 90) return 'HIGH ' + v + '%'\n\tif (v >= 70) return 'high ' + v + '%'\n\tif (v >= 30) return v + '%'\n\tif (v >= 10) return 'low ' + v + '%'\n\tif (v > 0) return 'LOW ' + v + '%'\n\treturn 'LOWEST'\n}\n\nexport function rgb2hex(rgb) {\n\t// should be replaced by d3-color.rgb(xx).hex()\n\tif (rgb[0] == '#') return rgb\n\tconst r = rgb.match(/^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i)\n\treturn r && r.length === 4\n\t\t? '#' +\n\t\t\t\t('0' + parseInt(r[1], 10).toString(16)).slice(-2) +\n\t\t\t\t('0' + parseInt(r[2], 10).toString(16)).slice(-2) +\n\t\t\t\t('0' + parseInt(r[3], 10).toString(16)).slice(-2)\n\t\t: ''\n}\n\nexport function keyupEnter(event) {\n\treturn event.code == 'Enter' || event.code == 'NumpadEnter'\n}\n\nexport function may_findmatchingsnp(chr, poslst, genome, alleleLst) {\n\t/*\nchr: string, required\nposlst[]\n\tint, or {start, stop}\n\trequired\ngenome{ name }, required\nalleleLst[], optional\n*/\n\tif (!genome || !genome.hasSNP) return\n\tconst p = {\n\t\tbyCoord: true,\n\t\tgenome: genome.name,\n\t\tchr: chr,\n\t\tranges: [],\n\t\talleleLst\n\t}\n\tfor (const i of poslst) {\n\t\tif (Number.isFinite(i)) {\n\t\t\tp.ranges.push({ start: i, stop: i + 1 })\n\t\t} else if (i.start && i.stop) {\n\t\t\tp.ranges.push(i)\n\t\t}\n\t}\n\treturn dofetch('snp', p).then(data => {\n\t\tif (data.error) throw data.error\n\t\treturn data.results\n\t})\n}\n\nexport function snp_printhtml(m, d) {\n\t/*\nm{}\n\t.name\n\t.observed\n*/\n\td.append('a')\n\t\t.text(m.name)\n\t\t.attr('href', 'https://www.ncbi.nlm.nih.gov/snp/' + m.name)\n\t\t.attr('target', '_blank')\n\td.append('div').attr('class', 'sja_tinylogo_body').text(m.observed)\n\td.append('div').attr('class', 'sja_tinylogo_head').text('ALLELE')\n}\n\nexport function clinvar_printhtml(m, d) {\n\t/*\nm{}\n\t.id\n\t.value\n\t.bg\n\t.textcolor\n*/\n\td.append('div')\n\t\t.style('display', 'inline-block')\n\t\t.style('background', m.bg)\n\t\t.style('padding', '3px')\n\t\t.append('a')\n\t\t.attr('href', 'https://www.ncbi.nlm.nih.gov/clinvar/variation/' + m.id)\n\t\t.attr('target', '_blank')\n\t\t.style('color', m.textcolor)\n\t\t.text(m.value)\n\t\t.style('font-size', '.9em')\n\t\t.style('text-decoration', 'none')\n}\n\nexport function gmlst2loci(gmlst) {\n\t// gmlst as is returned by genelookup:deep\n\tconst locs = []\n\tfor (const f of gmlst) {\n\t\tlet nooverlap = true\n\t\tfor (const r of locs) {\n\t\t\tif (f.chr == r.chr && Math.max(f.start, r.start) < Math.min(f.stop, r.stop)) {\n\t\t\t\tr.start = Math.min(r.start, f.start)\n\t\t\t\tr.stop = Math.max(r.stop, f.stop)\n\t\t\t\tnooverlap = false\n\t\t\t}\n\t\t}\n\t\tif (nooverlap) {\n\t\t\tlocs.push({\n\t\t\t\tname: f.isoform,\n\t\t\t\tchr: f.chr,\n\t\t\t\tstart: f.start,\n\t\t\t\tstop: f.stop\n\t\t\t})\n\t\t}\n\t}\n\treturn locs\n}\n\nexport function tab2box(holder, tabs, runall, tabheader) {\n\t/*\ntabs[ tab{} ]\n\t.label:\n\t\trequired\n\t.callback()\n\t\trequired\n\nthis function attaches .box (d3 dom) to each tab of tabs[]\n\n*/\n\tconst tr = holder.append('table').style('border-spacing', '0px').style('border-collapse', 'separate').append('tr')\n\tconst tdleft = tr.append('td').style('vertical-align', 'top').style('padding', '10px 0px 10px 10px')\n\tconst tdright = tr\n\t\t.append('td')\n\t\t.style('vertical-align', 'top')\n\t\t.style('border-left', 'solid 1px #aaa')\n\t\t.style('padding', '10px')\n\tconst has_acitve_tab = tabs.findIndex(t => t.active) == -1 ? false : true\n\n\tif (tabheader) {\n\t\tconst tHeader = tdleft\n\t\t\t.append('div')\n\t\t\t.style('padding', '5px 10px')\n\t\t\t.style('margin', '5px 5px 10px 5px')\n\t\t\t.style('font-weight', '550')\n\t\t\t.text(tabheader)\n\t}\n\n\tfor (let i = 0; i < tabs.length; i++) {\n\t\tconst tab = tabs[i]\n\n\t\ttab.tab = tdleft\n\t\t\t.append('div')\n\t\t\t.style('padding', '5px 10px')\n\t\t\t.style('margin', '0px')\n\t\t\t.style('border-top', 'solid 1px #ddd')\n\t\t\t.style('border-radius', '0px')\n\t\t\t.classed('sja_menuoption', !has_acitve_tab && i != 0)\n\t\t\t.html(tab.label)\n\n\t\ttab.box = tdright\n\t\t\t.append('div')\n\t\t\t.style('padding', '3px')\n\t\t\t.style('display', (!has_acitve_tab && i == 0) || tab.active ? 'block' : 'none')\n\n\t\tif ((runall && tab.callback) || (!has_acitve_tab && i == 0 && tab.callback) || tab.active) {\n\t\t\ttab.callback(tab.box)\n\t\t\tdelete tab.callback\n\t\t}\n\t\tif (has_acitve_tab) tab.tab.classed('sja_menuoption', !tab.active)\n\n\t\ttab.tab.on('click', () => {\n\t\t\tif (tab.box.style('display') != 'none') {\n\t\t\t\ttab.tab.classed('sja_menuoption', true)\n\t\t\t\ttab.box.style('display', 'none')\n\t\t\t} else {\n\t\t\t\ttab.tab.classed('sja_menuoption', false)\n\t\t\t\tappear(tab.box)\n\t\t\t\tfor (let j = 0; j < tabs.length; j++) {\n\t\t\t\t\tif (i != j) {\n\t\t\t\t\t\ttabs[j].tab.classed('sja_menuoption', true)\n\t\t\t\t\t\ttabs[j].box.style('display', 'none')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (tab.callback) {\n\t\t\t\ttab.callback(tab.box)\n\t\t\t\tdelete tab.callback\n\t\t\t}\n\t\t})\n\t}\n}\n\nexport function tab_wait(d) {\n\treturn d.append('div').style('margin', '30px').text('Loading...')\n}\n", "export function first_genetrack_tolist(genome, lst) {\n\tif (!genome.tracks) return\n\tfor (const t of genome.tracks) {\n\t\tif (t.__isgene) {\n\t\t\tlst.push(t)\n\t\t\treturn\n\t\t}\n\t}\n}\n", "import type { SvgG, SvgSvg, Td } from '../../types/d3'\nimport type { ColorScaleMenuOpts, CutoffMode } from './types'\nimport { Menu } from '#dom'\nimport { rgb } from 'd3-color'\n\nexport class ColorScaleMenu {\n\tdomain: number[]\n\tcolors: string[] = ['white', 'red']\n\tdefault?: { min: number; max: number; percentile?: number }\n\tcutoffMode?: CutoffMode\n\tpercentile?: number\n\tsetColorsCallback?: (val: string, idx: number) => void\n\tnumInputCallback?: (f?: { cutoffMode: CutoffMode; min?: number; max?: number; percentile?: number }) => void\n\tprivate tip = new Menu({ padding: '2px' })\n\tconstructor(opts: ColorScaleMenuOpts) {\n\t\tthis.domain = [...opts.domain] // Create a copy of the domain to prevent mutating the original array when changing values in fixed cutoff mode\n\t\tthis.colors = opts.colors\n\n\t\tif (opts.setNumbersCallback) {\n\t\t\tthis.numInputCallback = opts.setNumbersCallback\n\t\t\tthis.cutoffMode = opts.cutoffMode\n\t\t\tthis.default = {\n\t\t\t\tmin: this.domain[0],\n\t\t\t\tmax: this.domain[this.domain.length - 1]\n\t\t\t}\n\t\t\tif (opts.percentile) {\n\t\t\t\t/** Both opts are defined in ColorScale.ts even if\n\t\t\t\t * the caller only passes one. See note in ColorScale.ts. */\n\t\t\t\tthis.default.percentile = opts.defaultPercentile\n\t\t\t\tthis.percentile = opts.percentile\n\t\t\t}\n\t\t}\n\t\tif (opts.setColorsCallback) this.setColorsCallback = opts.setColorsCallback\n\n\t\tthis.renderMenu(opts.scaleSvg, opts.barG)\n\t}\n\n\trenderMenu(scaleSvg: SvgSvg, barG: SvgG) {\n\t\tlet showTooltip = true\n\t\tscaleSvg\n\t\t\t.on('click', event => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tthis.tip.clear().showunder(barG.node())\n\t\t\t\tconst selectDiv = this.tip.d.append('div').style('padding', '2px')\n\t\t\t\tconst table = this.tip.d.append('table').style('margin', 'auto')\n\n\t\t\t\tconst submitPromptCell = table\n\t\t\t\t\t.append('tr')\n\t\t\t\t\t.append('td')\n\t\t\t\t\t.attr('colspan', '2')\n\t\t\t\t\t.style('opacity', 0.65)\n\t\t\t\t\t.style('font-size', '0.7em')\n\t\t\t\t\t.text('Press ENTER to submit')\n\t\t\t\t\t.style('display', this.cutoffMode != 'auto' ? '' : 'none')\n\n\t\t\t\tconst percentRow = table\n\t\t\t\t\t.append('tr')\n\t\t\t\t\t.style('padding', '5px')\n\t\t\t\t\t.append('td')\n\t\t\t\t\t.attr('colspan', '2')\n\t\t\t\t\t.style('display', this.cutoffMode == 'percentile' ? '' : 'none')\n\n\t\t\t\tconst minMaxPromptRow = table\n\t\t\t\t\t.append('tr')\n\t\t\t\t\t.style('text-align', 'center')\n\t\t\t\t\t.style('display', this.setColorsCallback ? 'table-row' : 'none')\n\t\t\t\tminMaxPromptRow.append('td').text('Min').style('padding-left', '5px').style('text-align', 'left')\n\t\t\t\tminMaxPromptRow.append('td').style('padding-left', '5px').style('text-align', 'left').text('Max')\n\n\t\t\t\tif (this.numInputCallback) {\n\t\t\t\t\tconst options = [\n\t\t\t\t\t\t{ label: 'Automatic', value: 'auto', selected: this.cutoffMode == 'auto' },\n\t\t\t\t\t\t{ label: 'Fixed', value: 'fixed', selected: this.cutoffMode == 'fixed' }\n\t\t\t\t\t]\n\t\t\t\t\tif (this.default?.percentile) {\n\t\t\t\t\t\toptions.push({\n\t\t\t\t\t\t\tlabel: 'Percentile',\n\t\t\t\t\t\t\tvalue: 'percentile',\n\t\t\t\t\t\t\tselected: this.cutoffMode == 'percentile'\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tconst select = selectDiv.append('select')\n\n\t\t\t\t\tselect\n\t\t\t\t\t\t.selectAll('option')\n\t\t\t\t\t\t.data(options)\n\t\t\t\t\t\t.enter()\n\t\t\t\t\t\t.append('option')\n\t\t\t\t\t\t.text(d => d.label)\n\t\t\t\t\t\t.property('value', d => d.value)\n\t\t\t\t\t\t.property('selected', d => d.selected)\n\n\t\t\t\t\t//Do not allow users to put in negative or > 100 values\n\t\t\t\t\tconst percentInput = this.appendValueInput(percentRow, this.percentile ?? null, 0.1, 100)\n\n\t\t\t\t\tconst minMaxInputRow = table.append('tr').style('display', this.cutoffMode == 'fixed' ? 'table-row' : 'none')\n\t\t\t\t\tconst minInput = this.appendValueInput(minMaxInputRow.append('td'), this.domain[0])\n\t\t\t\t\tthis.appendValueInput(minMaxInputRow.append('td'), this.domain[this.domain.length - 1])\n\n\t\t\t\t\tselect.on('change', async () => {\n\t\t\t\t\t\tthis.cutoffMode = select.node()!.value as CutoffMode\n\t\t\t\t\t\tif (!this.default) throw new Error('Auto values not set for #dom/ColorScale.')\n\t\t\t\t\t\tif (this.cutoffMode == 'auto') {\n\t\t\t\t\t\t\tminMaxPromptRow.style('display', this.setColorsCallback ? 'table-row' : 'none')\n\t\t\t\t\t\t\tthis.domain[0] = this.default.min\n\t\t\t\t\t\t\tthis.domain[this.domain.length - 1] = this.default.max\n\t\t\t\t\t\t\tthis.percentile = this.default.percentile\n\t\t\t\t\t\t\tawait this.numInputCallback!({\n\t\t\t\t\t\t\t\tcutoffMode: this.cutoffMode,\n\t\t\t\t\t\t\t\tmin: this.default.min,\n\t\t\t\t\t\t\t\tmax: this.default.max\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.tip.hide()\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//Show min/max prompts for fixed mode and if user may change colors\n\t\t\t\t\t\tminMaxPromptRow.style(\n\t\t\t\t\t\t\t'display',\n\t\t\t\t\t\t\tthis.setColorsCallback || this.cutoffMode == 'fixed' ? 'table-row' : 'none'\n\t\t\t\t\t\t)\n\t\t\t\t\t\t//Show submit prompt for fixed and percentile mode\n\t\t\t\t\t\tsubmitPromptCell.style('display', this.cutoffMode != 'auto' ? '' : 'none')\n\t\t\t\t\t\t//Show min/max inputs for fixed mode and focus on the min input\n\t\t\t\t\t\tminMaxInputRow.style('display', this.cutoffMode == 'fixed' ? 'table-row' : 'none')\n\t\t\t\t\t\tif (this.cutoffMode == 'fixed') minInput.node().focus()\n\t\t\t\t\t\t//Show and focus on the percentile input when mode is percentile\n\t\t\t\t\t\tpercentRow.style('display', this.cutoffMode == 'percentile' ? '' : 'none')\n\t\t\t\t\t\tif (this.cutoffMode == 'percentile') percentInput.node().focus()\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (this.setColorsCallback) {\n\t\t\t\t\tconst colorRow = table.append('tr').style('text-align', 'center')\n\t\t\t\t\tthis.appendColorInput(colorRow.append('td').style('padding-right', '10px'), 0)\n\t\t\t\t\tthis.appendColorInput(colorRow.append('td'), this.colors.length - 1)\n\t\t\t\t}\n\t\t\t\tshowTooltip = false\n\t\t\t})\n\t\t\t.on('mouseenter', event => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\t//Prevent showing the tooltip after user interacts with the color picker\n\t\t\t\tif (showTooltip == false) return\n\t\t\t\tthis.tip.clear().showunder(barG.node())\n\t\t\t\tconst text = `Click to customize ${this.setColorsCallback ? 'colors' : ''} ${\n\t\t\t\t\tthis.numInputCallback && this.setColorsCallback ? ' and ' : ''\n\t\t\t\t}${this.numInputCallback ? 'values' : ''}`\n\t\t\t\tthis.tip.d.append('div').style('padding', '2px').text(text)\n\t\t\t})\n\t\t\t.on('mouseleave', () => {\n\t\t\t\tif (showTooltip) this.tip.hide()\n\t\t\t})\n\t}\n\n\tappendColorInput = (td: Td, idx: number) => {\n\t\tconst colorInput = td\n\t\t\t.append('input')\n\t\t\t.style('width', '60px')\n\t\t\t.attr('type', 'color')\n\t\t\t//Rm default color input styles\n\t\t\t.style('padding', '0px')\n\t\t\t.style('border', 'none')\n\t\t\t.style('margin', '0px')\n\t\t\t.attr('value', rgb(this.colors[idx]).formatHex())\n\t\t\t.on('change', async () => {\n\t\t\t\tconst color = colorInput.node()!.value\n\t\t\t\tthis.colors[idx] = color\n\t\t\t\tawait this.setColorsCallback!(color, idx)\n\t\t\t\tthis.tip.hide()\n\t\t\t})\n\t}\n\n\tappendValueInput = (elem: any, elemValue: number | null, min?: number, max?: number) => {\n\t\tif (elemValue == null) return\n\t\tconst valueInput = elem\n\t\t\t.append('input')\n\t\t\t.attr('type', 'number')\n\t\t\t.style('width', '60px')\n\t\t\t.attr('value', elemValue)\n\t\t\t.style('padding', '3px')\n\n\t\t//Limit input if necessary\n\t\tif (min) valueInput.attr('min', min)\n\t\tif (max) valueInput.attr('max', max)\n\n\t\tvalueInput.on('keyup', async (event: KeyboardEvent) => {\n\t\t\tif (event.code != 'Enter') return\n\t\t\tconst valueNode = valueInput.node()\n\t\t\tif (!valueNode) return\n\t\t\tconst value: number = parseFloat(valueNode.value)\n\t\t\tif (!Number.isFinite(value)) {\n\t\t\t\t/** Prevent the user from entering invalid numbers (e.g. --2, 1e, etc.) */\n\t\t\t\talert('Please enter a valid number')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst opts: any = {\n\t\t\t\tcutoffMode: this.cutoffMode\n\t\t\t}\n\t\t\tif (this.cutoffMode == 'fixed') {\n\t\t\t\tconst idx = elemValue == this.domain[0] ? 0 : this.domain.length - 1\n\t\t\t\tthis.domain[idx] = value\n\t\t\t\topts.min = this.domain[0]\n\t\t\t\topts.max = this.domain[this.domain.length - 1]\n\t\t\t} else if (this.cutoffMode == 'percentile') {\n\t\t\t\tif (value <= 0 || value >= 100) {\n\t\t\t\t\talert('Please enter a value between 0 and 100')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.percentile = value\n\t\t\t\topts.percentile = value\n\t\t\t}\n\t\t\tawait this.numInputCallback!(opts)\n\t\t\tthis.tip.hide()\n\t\t})\n\t\treturn valueInput\n\t}\n}\n", "import type { SvgSvg, SvgG } from '../../types/d3'\nimport type { ColorScaleDom, ColorScaleOpts, GradientElem, ColorScaleMenuOpts, NumericInputs } from './types.ts'\nimport { scaleLinear } from 'd3-scale'\nimport { axisBottom, axisTop } from 'd3-axis'\nimport { font } from '../../src/client'\nimport { axisstyle, niceNumLabels } from '#dom'\nimport { ColorScaleMenu } from './ColorScaleMenu'\n// import { format } from 'd3-format'\n// import { interpolateRgb } from 'd3-interpolate'\n// import { decimalPlacesUntilFirstNonZero } from '#shared/roundValue.js'\n\nexport class ColorScale {\n\tdom: ColorScaleDom\n\tbarheight: number\n\tbarwidth: number\n\tcolors: string[]\n\tdomain: number[]\n\tfontSize: number\n\tnumericInputs?: NumericInputs\n\tmarkedValue?: number | null\n\tmenu?: ColorScaleMenu\n\t/** Purely for testing. Not used in the class but can be\n\t * called independently of user click, if needed */\n\tsetColorsCallback?: (val: string, idx: number) => void\n\tticks: number\n\ttickSize: number\n\ttickValues: number[]\n\ttopTicks: boolean\n\n\tconstructor(opts: ColorScaleOpts) {\n\t\tthis.barheight = opts.barheight || 14\n\t\tthis.barwidth = opts.barwidth || 100\n\t\tthis.colors = opts?.colors?.length ? opts.colors : ['white', 'red']\n\t\tthis.domain = opts.domain\n\t\tthis.fontSize = opts.fontSize || 10\n\t\tthis.markedValue = opts.markedValue && opts.markedValue > 0.001 ? opts.markedValue : null\n\t\tthis.ticks = opts.ticks || 5\n\t\tthis.tickSize = opts.tickSize || 1\n\t\tthis.topTicks = opts.topTicks || false\n\n\t\tthis.validateOpts(opts)\n\t\tthis.tickValues = niceNumLabels(opts.domain)\n\n\t\tlet scaleSvg: SvgSvg //\n\t\tif (opts.width || opts.height) {\n\t\t\tscaleSvg = opts.holder\n\t\t\t\t.append('svg')\n\t\t\t\t.attr('width', opts.width || 100)\n\t\t\t\t.attr('height', opts.height || 30)\n\t\t} else scaleSvg = opts.holder\n\t\tscaleSvg.attr('data-testid', 'sjpp-color-scale')\n\t\tlet barG\n\t\tconst position = opts.position || '0,0'\n\t\tif (opts.labels) {\n\t\t\tbarG = this.renderLabels(scaleSvg, opts.labels, position)\n\t\t} else barG = scaleSvg.append('g').attr('transform', `translate(${position})`)\n\t\tconst id = opts.id || Math.random().toString()\n\n\t\tconst defs = barG.append('defs')\n\t\tconst gradient = defs.append('linearGradient').attr('data-testid', 'sjpp-color-scale-bar').attr('id', id)\n\n\t\tif (this.topTicks === true) {\n\t\t\tconst { scale, scaleAxis } = this.makeAxis(barG, id)\n\t\t\tthis.makeColorBar(gradient)\n\t\t\tthis.dom = { gradient, scale, scaleAxis, barG }\n\t\t} else {\n\t\t\tthis.makeColorBar(gradient)\n\t\t\tconst { scale, scaleAxis } = this.makeAxis(barG, id)\n\t\t\tthis.dom = { gradient, scale, scaleAxis, barG }\n\t\t\tthis.markedValueInColorBar()\n\t\t}\n\t\tthis.render()\n\n\t\tif (opts.setColorsCallback || opts.numericInputs) {\n\t\t\t// Menu appearing on color bar click if callbacks are provided\n\t\t\tthis.menu = this.renderMenu(opts, scaleSvg, barG)\n\t\t}\n\t}\n\n\tvalidateOpts(opts: ColorScaleOpts) {\n\t\tif (!opts.holder) throw new Error('No holder provided for #dom/ColorScale.')\n\t\tif (!opts.domain || !opts.domain.length) throw new Error('No data provided for #dom/ColorScale.')\n\t\tif (opts.domain.length != this.colors.length) {\n\t\t\tthrow new Error('Data and color arrays for #dom/ColorScale must be the same length')\n\t\t}\n\t\tif (opts.domain.length != new Set(opts.domain).size) {\n\t\t\tthrow new Error('Duplicate values in #dom/ColorScale opts.domain')\n\t\t}\n\t\t/** TODO: It's possible for very small values to calculate the same the\n\t\t * color for a small range. Need a solution for these edge cases. */\n\t\t// if (this.colors.length != new Set(this.colors).size) {\n\t\t// \tthrow new Error('Duplicate values in #dom/ColorScale opts.colors')\n\t\t// }\n\t\tif (opts.labels && (!opts.labels.left || !opts.labels.right))\n\t\t\tthrow new Error('Missing a label for #dom/ColorScale.')\n\t}\n\n\trenderLabels(scaleSvg: SvgSvg, labels: { left: string; right: string }, position: string) {\n\t\tconst addLabel = (text: string, x: number, y: number) => {\n\t\t\treturn scaleSvg\n\t\t\t\t.append('text')\n\t\t\t\t.text(text)\n\t\t\t\t.attr('class', 'sjpp-color-scale-label')\n\t\t\t\t.attr('font-size', '.8em')\n\t\t\t\t.attr('opacity', 0.6)\n\t\t\t\t.attr('text-anchor', 'end')\n\t\t\t\t.attr('transform', `translate(${x}, ${y})`)\n\t\t}\n\n\t\tconst [posX, posY] = position.split(',').map(Number)\n\n\t\tconst leftLabel = addLabel(labels.left, posX, posY + 10)\n\t\tconst leftBBox = leftLabel.node()!.getBBox()\n\n\t\tconst startXPos = posX + leftBBox.x + leftBBox.width + 20\n\t\tconst barGPos = `${startXPos}, ${posY}`\n\t\tconst rightLabelX = startXPos + this.barwidth + 40\n\t\tconst rightLabelY = posY + 10\n\t\tconst barG = scaleSvg.append('g').attr('transform', `translate(${barGPos})`)\n\t\taddLabel(labels.right, rightLabelX, rightLabelY)\n\t\tconst totalWidth = scaleSvg.node()!.getBBox().width + leftBBox.width\n\t\tscaleSvg.attr('width', totalWidth)\n\n\t\treturn barG\n\t}\n\n\tgetRange() {\n\t\treturn this.tickValues.map((_, i) => {\n\t\t\treturn this.barwidth * (i / (this.tickValues.length - 1))\n\t\t})\n\t}\n\n\tmakeColorBar(gradient?: GradientElem) {\n\t\tconst gradElem = gradient || this.dom.gradient\n\t\tfor (const [idx, c] of this.colors.entries()) {\n\t\t\tconst offset = (idx / (this.colors.length - 1)) * 100\n\t\t\tgradElem.append('stop').attr('offset', `${offset}%`).attr('stop-color', `${c}`)\n\t\t}\n\t}\n\n\tmakeAxis(div: SvgG, id: string) {\n\t\tdiv\n\t\t\t.append('rect')\n\t\t\t.attr('class', 'sjpp-color-scale-rect')\n\t\t\t.attr('height', this.barheight)\n\t\t\t.attr('width', this.barwidth)\n\t\t\t.attr('fill', 'url(#' + id + ')')\n\n\t\tconst scaleAxis = div.append('g').attr('data-testid', 'sjpp-color-scale-axis')\n\t\tif (this.topTicks === false) scaleAxis.attr('transform', `translate(0, ${this.barheight})`)\n\t\tconst scale = scaleLinear().domain(this.tickValues).range(this.getRange())\n\n\t\treturn { scale, scaleAxis }\n\t}\n\n\tmarkedValueInColorBar() {\n\t\tif (this.markedValue == null || this.topTicks === true) return\n\n\t\tthis.dom.line = this.dom.barG\n\t\t\t.append('line')\n\t\t\t.classed('sjpp-color-scale-marked', true)\n\t\t\t.attr('data-testid', 'sjpp-color-scale-marked-tick')\n\t\t\t.attr('y1', this.barheight - 2)\n\t\t\t.attr('y2', this.barheight + 1)\n\t\t\t.attr('stroke', 'black')\n\n\t\tthis.dom.label = this.dom.barG\n\t\t\t.append('text')\n\t\t\t.classed('sjpp-color-scale-marked', true)\n\t\t\t.attr('data-testid', 'sjpp-color-scale-marked-label')\n\t\t\t.attr('text-anchor', 'middle')\n\t\t\t.attr('font-family', font)\n\t\t\t.attr('font-size', `${this.fontSize + 2}px`)\n\t\t\t.attr('y', this.barheight - 3)\n\t\t\t// Text easier to see on dark backgrounds\n\t\t\t.attr('fill', 'white')\n\t\t\t.attr('stroke', 'black')\n\t\t\t.attr('stroke-width', 0.3)\n\n\t\tthis.updateValueInColorBar()\n\t}\n\n\trender() {\n\t\tconst axis = this.getAxis()\n\n\t\taxisstyle({\n\t\t\taxis: this.dom.scaleAxis.call(axis),\n\t\t\tshowline: false,\n\t\t\tfontsize: this.fontSize\n\t\t})\n\t}\n\n\trenderMenu(opts: ColorScaleOpts, scaleSvg: SvgSvg, barG: SvgG) {\n\t\tconst _opts: ColorScaleMenuOpts = {\n\t\t\tscaleSvg,\n\t\t\tbarG,\n\t\t\tdomain: this.domain,\n\t\t\tcolors: this.colors\n\t\t}\n\t\tif (opts.setColorsCallback)\n\t\t\t_opts.setColorsCallback = async (val, idx) => {\n\t\t\t\tif (!val || !isFinite(idx)) return\n\t\t\t\tawait opts.setColorsCallback!(val, idx)\n\t\t\t\tthis.updateColors()\n\t\t\t}\n\t\tif (opts.numericInputs) {\n\t\t\t_opts.cutoffMode = opts.numericInputs.cutoffMode || 'auto'\n\t\t\tif (opts.numericInputs.defaultPercentile || opts.numericInputs.percentile) {\n\t\t\t\t/** If the color scale is rerendered instead of persisted, tracking the default\n\t\t\t\t * vs the user provided percentile within this component is not possible. Give\n\t\t\t\t * the menu the option to receive both values and use whichever is present. */\n\t\t\t\t_opts.defaultPercentile = opts.numericInputs.defaultPercentile ?? opts.numericInputs.percentile\n\t\t\t\t_opts.percentile = opts.numericInputs.percentile ?? opts.numericInputs.defaultPercentile\n\t\t\t}\n\t\t\t_opts.setNumbersCallback = async obj => {\n\t\t\t\tif (!obj) return\n\t\t\t\tawait opts.numericInputs!.callback(obj)\n\t\t\t\tthis.updateAxis()\n\t\t\t}\n\t\t}\n\t\tconst menu = new ColorScaleMenu(_opts)\n\t\treturn menu\n\t}\n\n\tgetAxis() {\n\t\tconst axis = this.topTicks === true ? axisTop(this.dom.scale) : axisBottom(this.dom.scale)\n\t\taxis.ticks(this.ticks).tickSize(this.tickSize)\n\t\treturn axis\n\t}\n\n\tupdateColors() {\n\t\tthis.dom.gradient.selectAll('stop').remove()\n\t\tthis.makeColorBar()\n\t}\n\n\tupdateAxis() {\n\t\tthis.dom.scaleAxis.selectAll('*').remove()\n\n\t\tthis.tickValues = niceNumLabels(this.domain)\n\t\tthis.dom.scale = scaleLinear().domain(this.tickValues).range(this.getRange())\n\n\t\tthis.dom.scaleAxis\n\t\t\t.transition()\n\t\t\t.duration(400)\n\t\t\t.call(this.getAxis())\n\t\t\t//Transition sometimes removes the font size\n\t\t\t.selectAll('text')\n\t\t\t.attr('font-size', `${this.fontSize}px`)\n\n\t\t//The stroke may inherit 'currentColor' from opts.holder\n\t\t//This is a workaround to prevent the black line from appearing\n\t\tconst pathElem = this.dom.scaleAxis.select('path').node()\n\t\tif (pathElem instanceof SVGPathElement) pathElem.style.stroke = 'none'\n\t}\n\n\tupdateValueInColorBar() {\n\t\tif (this.markedValue == null || this.topTicks === true) return\n\t\tif (!this.dom.line || !this.dom.label) {\n\t\t\t/** Allow the line to be made if the init value was < 0.001 */\n\t\t\tthis.markedValueInColorBar()\n\t\t}\n\t\tconst x = Math.min(this.barwidth, this.dom.scale(this.markedValue))\n\t\tthis.dom.line!.attr('x1', x).attr('x2', x)\n\t\tthis.dom.label!.attr('x', x).text(Math.floor(this.markedValue))\n\n\t\t// /**Determine if the text should be white or black based on the\n\t\t// * background color.\n\t\t// *\n\t\t// * Code below passes npm run tsc, but fails on commit. Linters\n\t\t// * contradict each other on how to resolve. */\n\t\t// //eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t// const colorInt = interpolateRgb.apply(null, this.colors)\n\t\t// const color = colorInt(x)\n\t\t// if (color) {\n\t\t// const colorMap = color.match(/\\d+/g)?.map(Number)\n\t\t// const [r, g, b] = colorMap.map(v => v / 255)\n\t\t// const contrast = 0.2126 * r + 0.7152 * g + 0.0722 * b\n\t\t// if (contrast < 0.5) this.dom.label.attr('fill', 'white').attr('stroke', 'black').attr('stroke-width', 0.3)\n\t\t// else this.dom.label.attr('fill', 'black').attr('stroke', 'none')\n\t\t// }\n\t}\n\n\tupdateMenu() {\n\t\tif (!this.menu) return\n\t\tthis.menu.colors = this.colors\n\t\tthis.menu.domain = this.domain\n\t}\n\n\tupdateScale() {\n\t\tif (this.domain.length != this.colors.length)\n\t\t\tthrow new Error('Data and color arrays for #dom/ColorScale must be the same length')\n\t\tthis.updateColors()\n\t\tthis.updateAxis()\n\t\tthis.updateValueInColorBar()\n\t\tthis.updateMenu()\n\t}\n}\n", "import type { GetInterpolatedArg } from './types'\n\n/** Generate an interpolated color scale based on the domain and range.\n * @param absMin - the absolute magnitude of the interpolation domain minimum value\n * @param absMax - the absolute magnitude of the interpolation domain minimum value\n * @param negInterpolator - function to convert number to css color\n * @param posInterpolator - function to convert number to css color\n * @param middleColor - Optional color to insert between two interpolated color ranges,\n * @param totalNumSteps - the target number of increments within the interpolation domain and range\n * @returns the domain and range for the interpolated color scale\n */\n\ntype InterpolatedDomainRange = {\n\tvalues: Set<number>\n\tcolors: string[]\n}\n\nexport function getInterpolatedDomainRange({\n\tabsMin,\n\tabsMax,\n\tnegInterpolator,\n\tposInterpolator,\n\tmiddleColor = 'white',\n\ttotalNumSteps = 100\n}: GetInterpolatedArg) {\n\t/** If the range includes both negative and positive values, dividing\n\t * the steps equally between the neg and pos values ensures the\n\t * return domain does not exceed the intended length (i.e. total num steps)*/\n\tconst denominator = negInterpolator && posInterpolator ? totalNumSteps / 2 : totalNumSteps\n\tconst stepSize = (absMax - absMin) / denominator\n\tconst neg: InterpolatedDomainRange = { values: new Set(), colors: [] }\n\tconst pos: InterpolatedDomainRange = { values: new Set(), colors: [] }\n\tlet n = -absMax\n\tfor (let p = 0; p < absMax; p += stepSize) {\n\t\tif (p == 0) continue //In all instances, 0 is added to the final domain.\n\t\tif (negInterpolator) {\n\t\t\tn += stepSize\n\t\t\tconst vn = n // / absMax\n\t\t\tneg.values.add(vn)\n\t\t\tneg.colors.push(negInterpolator(-vn / absMax))\n\t\t}\n\t\tif (posInterpolator) {\n\t\t\tconst vp = p // / absMax // do not divide by absMax, use raw value\n\t\t\tpos.values.add(vp)\n\t\t\tpos.colors.push(posInterpolator(vp / absMax))\n\t\t}\n\t}\n\t/** Keep separate solution for now to reevlautate at a later time. */\n\t// let p = absMin,\n\t// \tn = -absMax //- stepSize\n\t// for (let i = 0; i < numSteps; i++) {\n\t// \tif (negInterpolator && !neg.values.has(n)) {\n\t// \t\t/** Include the raw value in the domain and calculate the color\n\t// \t\t * as a percent of the absMax. */\n\t// \t\tneg.values.add(n)\n\t// \t\tneg.colors.push(negInterpolator(-n / absMax))\n\t// \t}\n\t// \t// increment negative value after adding entries to neg.values/colors\n\t// \tn += stepSize\n\t// \tp += stepSize\n\t// \tif (posInterpolator && !pos.values.has(p)) {\n\t// \t\tpos.values.add(p)\n\t// \t\tpos.colors.push(posInterpolator(p / absMax))\n\t// \t}\n\t// }\n\n\tif (negInterpolator && posInterpolator) {\n\t\tconst domain = [-absMax, ...neg.values, 0, ...pos.values, absMax]\n\t\tconst range = [negInterpolator(1), ...neg.colors, middleColor, ...pos.colors, posInterpolator(1)]\n\t\tif (domain.length != range.length)\n\t\t\tthrow new Error(`unable to generate same-sized numeric -/+ domain and color range`)\n\t\treturn { domain, range }\n\t} else if (negInterpolator) {\n\t\tconst domain = [-absMax, ...neg.values, 0]\n\t\tconst range = [negInterpolator(1), ...neg.colors, negInterpolator(0)]\n\t\tif (domain.length != range.length) throw new Error(`unable to generate same-sized negative domain and color range`)\n\t\treturn { domain, range }\n\t} else if (posInterpolator) {\n\t\tconst domain = [0, ...pos.values, absMax]\n\t\tconst range = [posInterpolator(0), ...pos.colors, posInterpolator(1)]\n\t\tif (domain.length != range.length) throw new Error(`unable to generate same-sized positive domain and color range`)\n\t\treturn { domain, range }\n\t} else {\n\t\tthrow `missing both negInterpolator and posInterpolator in getInterpolatedDomainRange()`\n\t}\n}\n\n/** Calculate the color difference between two colors.\n * @param rgb1 - first color in rgb format\n * @param rgb2 - second color in rgb format\n * @returns the max difference between the two colors\n */\nexport function colorDelta(rgb1, rgb2) {\n\t// TODO: use ciede2000 when the installed d3-color version has it\n\t// lab = CIELAB, approximate human-perceived color simiilarity\n\t// const color1 = lab(rgb1);\n\t// const color2 = lab(rgb2);\n\t// return ciede2000(color1, color2)\n\n\t// for now, simply compute the max diff across rgb components between the 2 colors\n\tconst a = rgb1.split('(')[1].slice(0, -1).split(',').slice(0, 3)\n\tconst b = rgb2.split('(')[1].slice(0, -1).split(',').slice(0, 3)\n\tlet maxDiff = 0\n\tfor (const [i, v] of a.entries()) {\n\t\tconst d = v - b[i]\n\t\tif (maxDiff < d) maxDiff = d\n\t}\n\treturn maxDiff\n}\n\n/** Remove outliers from the domain array by removing the top and bottom percent of values.\n * Prevents outlier ticks from appearing in the color scale.\n * @param domain - number array to remove outliers from\n * @returns the domain array without outliers\n */\nexport function removeOutliers(domain: number[], _opts = {}) {\n\tconst opts = Object.assign(\n\t\t{\n\t\t\tminPercentile: 0.01,\n\t\t\tmaxPercentile: 0.99,\n\t\t\tbaseValue: undefined // if specified and detected in the domain, this value must not be considered an outlier\n\t\t},\n\t\t_opts\n\t)\n\tconst sorted = domain.sort((a, b) => a - b)\n\tconst first = sorted[0] === opts.baseValue ? opts.baseValue : sorted[Math.floor(sorted.length * opts.minPercentile)]\n\tconst last =\n\t\tsorted[sorted.length - 1] === opts.baseValue\n\t\t\t? opts.baseValue\n\t\t\t: sorted[Math.floor(sorted.length * opts.maxPercentile)]\n\tlet calculatedArray = sorted.filter(d => d >= first && d <= last)\n\tif (calculatedArray.length === 0) {\n\t\t/** It's possible user inputs restrict the range to the point\n\t\t * where no values are included. In this instance, the smallest possible\n\t\t * range is returned to allow the color scale to render. */\n\t\tconst hasNeg = sorted[0] < 0\n\t\tconst hasBoth = hasNeg && sorted[sorted.length - 1] > 0\n\t\tconst idxClosestToZero = () => {\n\t\t\treturn sorted.reduce((closestIdx, currentValue, currentIdx) => {\n\t\t\t\tconst closestValue = sorted[closestIdx]\n\t\t\t\treturn Math.abs(currentValue) < Math.abs(closestValue) ? currentIdx : closestIdx\n\t\t\t}, 0)\n\t\t}\n\t\tconst idx = hasBoth ? idxClosestToZero() : hasNeg ? sorted.length - 1 : 0\n\t\tconst firstValue = sorted[idx] ?? 0\n\t\tconst secondValue = hasBoth\n\t\t\t? sorted[idx - 1] ?? firstValue\n\t\t\t: hasNeg\n\t\t\t? sorted[idx - 1] ?? firstValue\n\t\t\t: sorted[idx + 1] ?? firstValue\n\t\tconst thirdValue = hasBoth\n\t\t\t? sorted[idx + 1] ?? firstValue\n\t\t\t: hasNeg\n\t\t\t? sorted[idx - 2] ?? secondValue\n\t\t\t: sorted[idx + 2] ?? secondValue\n\t\tcalculatedArray = [firstValue, secondValue, thirdValue].sort((a, b) => a - b)\n\t}\n\treturn calculatedArray\n}\n\n/** Removes outlier values from the interpolated domain/range object.\n * @param domainRange domain and range object returned from getInterpolatedDomainRange\n * @param firstPercent Optional percentage to calculate the min percentile cutoff\n * @param lastPercent Optional percentage to calculate the max percentile cutoff\n * @returns\n */\nexport function removeInterpolatedOutliers(\n\tdomainRange: { domain: number[]; range: string[] },\n\tminPercentile = 0.01,\n\tmaxPercentile = 0.99\n) {\n\tconst domain = removeOutliers(domainRange.domain, { minPercentile, maxPercentile })\n\tconst range = domain.map(d => domainRange.range[domainRange.domain.indexOf(d)])\n\treturn { domain, range }\n}\n\n/** Compute the num of desired ticks based on the domain range.\n * Helper mimics the behavior of d3's scale.ticks() method,\n * which calculates the tick num based on the domain\n * range and a target number of intervals. Affords the caller more precision.\n * @param domainRange - the range of the domain (max - min)\n * @param targetIntervals - the desired number of intervals between ticks (i.e. numTicks -1)\n * @returns the computed number of ticks\n */\nexport function computeTicks(domainRange: number, targetIntervals: number): number {\n\tif (!isFinite(domainRange) || domainRange === 0 || targetIntervals == 0) return 1\n\tif (domainRange < 0 || targetIntervals < 0) {\n\t\tthrow new Error(\n\t\t\t`Neither domainRange or targetIntervals can be a non-negative number. Received domainRange: ${domainRange}, targetIntervals: ${targetIntervals}`\n\t\t)\n\t}\n\tconst intervals = Math.max(1, targetIntervals ?? 4)\n\tconst step = domainRange / intervals\n\n\tif (!isFinite(step) || step <= 0) return 1\n\treturn step <= 2 ? 2 : step <= 3 ? 3 : 5\n}\n", "import { Menu, make_radios } from '#dom'\n\n/*\nRenderer for CNV config UI\n\t- radio buttons for toggling altered vs. wildtype\n\t- inputs for CNV gain cutoff, loss cutoff, and max length\n\t- resulting CNV config is provided through callback function\n*/\n\ntype Arg = {\n\tholder: any // D3 holder where UI is rendered\n\tcnvGainCutoff?: number // minimum positive value (log2 ratio) for CNV gain\n\tcnvLossCutoff?: number // maximum negative value (log2 ratio) for CNV loss\n\tcnvMaxLength?: number | null // max segment bp length; null = no length limit (UI shows -1)\n\tfractionOverlap?: number // fraction of query length overlapping with cnv segment, set to 0.8 by default\n\tcallback: (config: {\n\t\tcnvGainCutoff?: number\n\t\tcnvLossCutoff?: number\n\t\tcnvMaxLength?: number | null\n\t\tcnvWT?: boolean\n\t}) => void // called upon clicking apply\n\tcnvWT?: boolean // wildtype for CNV specified by cutoffs\n\tgenotypeToggle?: boolean // display altered vs. wildtype genotype toggle\n\tshowOverlap?: boolean // display percent overlap input\n}\n\nexport function renderCnvConfig(arg: Arg) {\n\tconst { cnvGainCutoff, cnvLossCutoff } = arg\n\tconst cnvMaxLength = arg.cnvMaxLength === null ? -1 : arg.cnvMaxLength\n\tconst fractionOverlap = arg.fractionOverlap || 0.8\n\n\tif (!Number.isFinite(cnvGainCutoff) && !Number.isFinite(cnvLossCutoff) && !Number.isFinite(cnvMaxLength)) {\n\t\t// no cutoffs defined, do not render config UI\n\t\treturn\n\t}\n\n\tconst div = arg.holder\n\tdiv.style('margin', '10px')\n\tconst tip = new Menu({ padding: '5px' })\n\n\tconst genotypeDiv = div.append('div').style('margin-bottom', '10px')\n\n\t// CNV genotype radio buttons\n\tlet genotypeRadio\n\tif (arg.genotypeToggle) {\n\t\tconst cnvWT = arg.cnvWT || false\n\t\tgenotypeDiv\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('margin-right', '5px')\n\t\t\t.style('opacity', 0.7)\n\t\t\t.text('CNV genotype')\n\t\tgenotypeRadio = make_radios({\n\t\t\tholder: genotypeDiv,\n\t\t\tstyles: { display: 'inline-block' },\n\t\t\toptions: [\n\t\t\t\t{ label: 'Altered', value: 'altered', checked: !cnvWT },\n\t\t\t\t{ label: 'Wildtype', value: 'wildtype', checked: cnvWT }\n\t\t\t],\n\t\t\tcallback: () => {}\n\t\t})\n\t}\n\n\tconst cutoffsDiv = div.append('div')\n\tcutoffsDiv.append('div').style('opacity', 0.7).style('margin-bottom', '10px').text('CNV cutoffs:')\n\tconst inputsDiv = cutoffsDiv.append('div').style('margin-left', '10px')\n\n\t// CNV gain input\n\tlet cnvGainInput\n\tif (Number.isFinite(cnvGainCutoff)) {\n\t\tconst cnvGainDiv = inputsDiv.append('div').style('margin-bottom', '5px')\n\t\tcnvGainDiv.append('span').style('opacity', 0.7).text('Minimum CNV Gain (log2 ratio)') // TODO: verify that this will always be log2 ratio\n\t\tcnvGainInput = cnvGainDiv\n\t\t\t.append('input')\n\t\t\t.attr('data-testid', 'sjpp-cnv-gain-input')\n\t\t\t.attr('type', 'number')\n\t\t\t.property('value', cnvGainCutoff)\n\t\t\t.style('width', '100px')\n\t\t\t.style('margin-left', '15px')\n\t\t\t.on('change', event => {\n\t\t\t\tconst value = event.target.value\n\t\t\t\tif (!isValidNumber(value)) {\n\t\t\t\t\twindow.alert('Please enter a numeric value.')\n\t\t\t\t\tevent.target.value = cnvGainCutoff\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (Number(value) < 0) {\n\t\t\t\t\twindow.alert('Value must be a positive value.')\n\t\t\t\t\tevent.target.value = cnvGainCutoff\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t// CNV loss input\n\tlet cnvLossInput\n\tif (Number.isFinite(cnvLossCutoff)) {\n\t\tconst cnvLossDiv = inputsDiv.append('div').style('margin-bottom', '5px')\n\t\tcnvLossDiv.append('span').style('opacity', 0.7).text('Maximum CNV Loss (log2 ratio)') // TODO: verify that this will always be log2 ratio\n\t\tcnvLossInput = cnvLossDiv\n\t\t\t.append('input')\n\t\t\t.attr('data-testid', 'sjpp-cnv-loss-input')\n\t\t\t.attr('type', 'number')\n\t\t\t.property('value', cnvLossCutoff)\n\t\t\t.style('width', '100px')\n\t\t\t.style('margin-left', '15px')\n\t\t\t.on('change', event => {\n\t\t\t\tconst value = event.target.value\n\t\t\t\tif (!isValidNumber(value)) {\n\t\t\t\t\twindow.alert('Please enter a numeric value.')\n\t\t\t\t\tevent.target.value = cnvLossCutoff\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (Number(value) > 0) {\n\t\t\t\t\twindow.alert('Value must be a negative value.')\n\t\t\t\t\tevent.target.value = cnvLossCutoff\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t// CNV max length input\n\tlet cnvLengthInput\n\tif (Number.isFinite(cnvMaxLength)) {\n\t\tconst cnvLengthDiv = inputsDiv.append('div').style('margin-bottom', '5px')\n\t\tcnvLengthDiv.append('span').style('opacity', 0.7).text('CNV Max Length (bp)')\n\t\tcnvLengthInput = cnvLengthDiv\n\t\t\t.append('input')\n\t\t\t.attr('data-testid', 'sjpp-cnv-length-input')\n\t\t\t.attr('type', 'number')\n\t\t\t.property('value', cnvMaxLength)\n\t\t\t.style('width', '100px')\n\t\t\t.style('margin-left', '15px')\n\t\t\t.on('change', event => {\n\t\t\t\tconst value = event.target.value\n\t\t\t\tif (!isValidNumber(value)) {\n\t\t\t\t\twindow.alert('Please enter a numeric value.')\n\t\t\t\t\tevent.target.value = cnvMaxLength\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('mouseover', event => {\n\t\t\t\ttip.clear()\n\t\t\t\ttip.d.append('div').text('Please enter a positive value. To include all CNV segments, enter -1.')\n\t\t\t\ttip.showunder(event.target)\n\t\t\t})\n\t\t\t.on('mouseout', () => {\n\t\t\t\ttip.hide()\n\t\t\t})\n\t}\n\n\t// Percent overlap input\n\tlet overlapInput\n\tif (arg.showOverlap && Number.isFinite(fractionOverlap)) {\n\t\tconst percentOverlap = fractionOverlap * 100\n\t\tconst overlapDiv = inputsDiv.append('div').style('margin-bottom', '5px')\n\t\toverlapDiv.append('span').style('opacity', 0.7).text('Minimum Overlap (%)')\n\t\toverlapInput = overlapDiv\n\t\t\t.append('input')\n\t\t\t.attr('data-testid', 'sjpp-cnv-length-input')\n\t\t\t.attr('type', 'number')\n\t\t\t.property('value', percentOverlap)\n\t\t\t.style('width', '100px')\n\t\t\t.style('margin-left', '15px')\n\t\t\t.on('change', event => {\n\t\t\t\tconst value = event.target.value\n\t\t\t\tif (!isValidNumber(value)) {\n\t\t\t\t\twindow.alert('Please enter a numeric value.')\n\t\t\t\t\tevent.target.value = percentOverlap\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('mouseover', event => {\n\t\t\t\ttip.clear()\n\t\t\t\ttip.d.append('div').text('Percent of query region overlapping CNV segment')\n\t\t\t\ttip.showunder(event.target)\n\t\t\t})\n\t\t\t.on('mouseout', () => {\n\t\t\t\ttip.hide()\n\t\t\t})\n\t}\n\n\t// Apply button\n\tdiv\n\t\t.append('div')\n\t\t.append('button')\n\t\t.attr('class', 'sja_filter_tag_btn sjpp_apply_btn')\n\t\t.style('border-radius', '13px')\n\t\t.style('margin-top', '15px')\n\t\t.style('font-size', '.8em')\n\t\t.text('APPLY')\n\t\t.on('click', () => {\n\t\t\tconst config: any = {}\n\t\t\tif (cnvGainInput) config.cnvGainCutoff = Number(cnvGainInput.property('value'))\n\t\t\tif (cnvLossInput) config.cnvLossCutoff = Number(cnvLossInput.property('value'))\n\t\t\tif (cnvLengthInput) {\n\t\t\t\tconst tempCnvMaxLength = Number(cnvLengthInput.property('value'))\n\t\t\t\t// no max length if value == -1\n\t\t\t\tconfig.cnvMaxLength = tempCnvMaxLength == -1 ? null : tempCnvMaxLength\n\t\t\t}\n\t\t\tif (overlapInput) {\n\t\t\t\tconst percentOverlap = Number(overlapInput.property('value'))\n\t\t\t\tconfig.fractionOverlap = percentOverlap / 100\n\t\t\t}\n\t\t\tif (genotypeRadio) {\n\t\t\t\tconst radios = genotypeRadio.inputs.nodes()\n\t\t\t\tconst selected = radios.find(r => r.checked)\n\t\t\t\tif (!selected) throw 'no selected radio found'\n\t\t\t\tconfig.cnvWT = selected.value == 'wildtype'\n\t\t\t}\n\t\t\targ.callback(config)\n\t\t})\n}\n\nfunction isValidNumber(s: string) {\n\tif (s === '') return false\n\tconst n = Number(s)\n\treturn Number.isFinite(n)\n}\n", "import { select } from 'd3-selection'\nimport { icons, axisstyle, make_one_checkbox } from '#dom'\nimport { axisTop } from 'd3-axis'\nimport { format as d3format } from 'd3-format'\nimport { scaleLinear } from 'd3-scale'\nimport type { Th } from '../types/d3'\nimport type { AxisDomain } from 'd3-axis'\nimport type { TableArgs, TableBarplot, TableCell, TableColumn } from './types/table'\n\n/** incremented input ID will guarantee no collision from using getUniqueNameOrId()*/\nlet idIncr = 0\n/** random suffix will minimize the chance of collission of other code that\nhappen to use the same prefix/beginning substring for element ID */\nconst randomSuffix = Math.random()\n/** generate unique input name or id string */\nfunction getUniqueNameOrId(str = 'elem') {\n\treturn `sjpp-${str}-${idIncr++}-${randomSuffix}`\n}\n\n/*\nPrints an html table, using the specified columns and rows\nSee the paramters in TableArgs; function has no return\n*/\nexport function renderTable({\n\tcolumns,\n\trows,\n\tdiv,\n\tcolumnButtons,\n\tbuttons,\n\tbuttonsToLeft,\n\tnoButtonCallback,\n\tsingleMode = false,\n\tnoRadioBtn = false,\n\tshowLines = true,\n\tstriped = true,\n\tshowHeader = true,\n\theader = {},\n\tmaxWidth = '90vw',\n\tmaxHeight = '40vh',\n\tselectedRows = [],\n\tselectAll = false,\n\tresize = false,\n\tselectedRowStyle = {},\n\tinputName = null,\n\tdataTestId = null,\n\tdownload = undefined,\n\tnoAutoScroll = false,\n\thoverEffects,\n\tallowRestoreRowOrder = false,\n\trestoreButtonInFooter = false\n}: TableArgs) {\n\tvalidateInput()\n\tlet _selectedRowStyle = selectedRowStyle\n\n\t/** make a shallow copy of the rows[] array to preserve the original index for the rows, not affected by sorting\n\ttable may allow to sort rows by a column. in such case, table still needs to report original index of selected rows\n\tto a callback, so that the downstream code can correctly access data for the selected rows after sorting\n\t*/\n\tconst rowsCopy = rows.map(i => i)\n\n\t/** Store reset functions for all sort buttons so we can reset their state when restore is clicked */\n\tconst sortButtonResetFns: Array<() => void> = []\n\n\tfunction validateInput() {\n\t\tif (!columns || columns?.length == 0) throw `Missing columns data`\n\t\tif (!rows) throw `Missing rows data`\n\t\tif (!div) throw `Missing div argument`\n\t\tconst lineNumsWithDataProbs: number[] = []\n\t\tfor (const [i, row] of rows.entries()) {\n\t\t\tif (row.length != columns.length) lineNumsWithDataProbs.push(i + 1)\n\t\t}\n\t\tif (lineNumsWithDataProbs.length > 0)\n\t\t\tthrow `Num of row objects != num of cols. Line num(s) = ${lineNumsWithDataProbs}`\n\t\tif (buttons) {\n\t\t\tfor (const [i, btn] of buttons.entries()) {\n\t\t\t\tif (!btn.text) throw `Missing button.text in buttons, line #${i + 1}`\n\t\t\t\tif (!btn.callback) throw `Missing button.callback in buttons, line #${i + 1}`\n\t\t\t}\n\t\t}\n\n\t\t// Validate allowRestoreRowOrder can only be true when at least one column is sortable\n\t\tif (allowRestoreRowOrder) {\n\t\t\tconst hasSortableColumn = columns.some(col => col.sortable === true)\n\t\t\tif (!hasSortableColumn) {\n\t\t\t\tthrow `allowRestoreRowOrder can only be true when at least one column has sortable:true`\n\t\t\t}\n\t\t}\n\n\t\t// this check is disabled for now as it breaks gdc bam slicing ui\n\t\t//if (singleMode == true && (!buttons || !noButtonCallback)) throw `Missing buttons array and noButtonCallback but singleMode = true`\n\t}\n\n\tconst uniqueInputName = inputName || getUniqueNameOrId('input')\n\n\t// Store the original row order to restore\n\tconst originalRows = rows.map(i => i)\n\n\tconst parentDiv = div.append('div').style('background-color', 'white').style('display', 'inline-block')\n\n\t// Create restore button container (will be shown/hidden based on sort state)\n\t// If restoreButtonInFooter is true, we'll create it later with the footer buttons\n\tlet restoreButtonDiv: any\n\tlet restoreButton: any\n\tif (allowRestoreRowOrder && !restoreButtonInFooter) {\n\t\trestoreButtonDiv = div\n\t\t\t.append('div')\n\t\t\t.style('display', 'none') // Initially hidden\n\t\t\t.style('padding', '5px')\n\t\t\t.style('vertical-align', 'top')\n\n\t\trestoreButton = restoreButtonDiv\n\t\t\t.append('button')\n\t\t\t.text('Restore row order')\n\t\t\t.attr('data-testid', 'sjpp-table-restore-button')\n\t\t\t.on('click', () => {\n\t\t\t\t// Restore original row order\n\t\t\t\trestoreButtonDiv.style('display', 'none')\n\n\t\t\t\tconst checked = getCheckedRowIndex()\n\t\t\t\tconst idxMap = new Map(rowsCopy.map((val, idx) => [val, idx]))\n\t\t\t\tselectedRows = checked.map(i => originalRows.findIndex((v: TableCell[]) => idxMap.get(v) === i))\n\n\t\t\t\t/** Must override caller setting once user selects row(s) */\n\t\t\t\tif (selectedRows.length) selectAll = false\n\n\t\t\t\t// Reset all sort button states\n\t\t\t\tfor (const resetFn of sortButtonResetFns) resetFn()\n\n\t\t\t\trows = originalRows.map(i => i) // Create a copy\n\t\t\t\tupdateRows()\n\t\t\t})\n\t}\n\n\tif (download) {\n\t\tconst downloadDiv = div\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('vertical-align', 'top')\n\n\t\ticons['download'](downloadDiv, {\n\t\t\twidth: 15,\n\t\t\theight: 15,\n\t\t\ttitle: 'Download table',\n\t\t\thandler: () => {\n\t\t\t\tdownloadTable(rows, columns, download.fileName || 'table.tsv')\n\t\t\t}\n\t\t})\n\t}\n\n\tif (resize) {\n\t\tif (rows.length > 15) parentDiv.style('height', maxHeight)\n\t\tparentDiv.style('max-width', maxWidth)\n\t\tparentDiv.style('resize', 'both')\n\t} else {\n\t\tparentDiv.style('max-height', maxHeight).style('max-width', maxWidth)\n\t\tif (columns.length > 2) parentDiv.style('resize', 'horizontal')\n\t}\n\tparentDiv.attr('class', 'sjpp_show_scrollbar')\n\n\tconst table = parentDiv.append('table').style('width', '100%')\n\n\tif (dataTestId) {\n\t\ttable.attr('data-testid', dataTestId)\n\t}\n\t// should not use \"fixed\", it does not make sense to force equal width of all columns. also sample name column is a bit longer than most fields but we do want it to be entirely visible\n\t//.style('table-layout', 'fixed')\n\n\t// header div\n\tconst thead = table\n\t\t.append('thead')\n\t\t.style('position', 'sticky')\n\t\t.style('top', '0')\n\t\t.style('background-color', 'white')\n\t\t.style('padding', '5px')\n\n\tconst theadRow = thead.append('tr')\n\tif (showLines) theadRow.append('td').style('width', '1vw')\n\n\tif (buttons || noButtonCallback) {\n\t\t// rows are clickable\n\t\tif (noRadioBtn) {\n\t\t\t// should be in singleMode and do not want to show radio buttons\n\t\t} else {\n\t\t\t// create column for radio button\n\t\t\tconst cell = theadRow.append('td').attr('class', 'sjpp_table_header').style('width', '1.5vw')\n\t\t\tif (!singleMode) {\n\t\t\t\tmake_one_checkbox({\n\t\t\t\t\tholder: cell,\n\t\t\t\t\tchecked: selectAll,\n\t\t\t\t\ttestid: 'sjpp-table-checkall',\n\t\t\t\t\tcallback: checked => {\n\t\t\t\t\t\tconst nodes = tbody.selectAll('input[type=checkbox]').nodes() // must restrict to type=checkbox and avoid selecting color button <input>\n\t\t\t\t\t\ttbody.selectAll('input').property('checked', checked)\n\t\t\t\t\t\tif (buttons) updateButtons()\n\t\t\t\t\t\tif (noButtonCallback) for (const [i, node] of nodes.entries()) noButtonCallback(i, node)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tif (!showHeader)\n\t\t\t\t\ttheadRow.append('th').text('Check/Uncheck All').attr('class', 'sjpp_table_header sjpp_table_item')\n\t\t\t}\n\t\t}\n\t}\n\n\tif (columnButtons && columnButtons.length > 0) {\n\t\tconst th = theadRow.append('th').text('Actions').attr('class', 'sjpp_table_item sjpp_table_header')\n\t\tif (header?.style) {\n\t\t\tfor (const k in header.style) th.style(k, header.style[k])\n\t\t}\n\t}\n\n\tif (showHeader) {\n\t\tfor (const [i, c] of columns.entries()) {\n\t\t\tconst th = theadRow.append('th').text(c.label).attr('class', 'sjpp_table_item sjpp_table_header')\n\t\t\tif (c.width) th.style('width', c.width)\n\t\t\tif (c.tooltip) th.attr('title', c.tooltip)\n\t\t\tif (header?.allowSort) {\n\t\t\t\t//Only create sort button for columns with data\n\t\t\t\t//(i.e. not html columns)\n\t\t\t\tif (c.sortable) addSort(th, i)\n\t\t\t}\n\t\t\tif (header?.style) {\n\t\t\t\tfor (const k in header.style) th.style(k, header.style[k])\n\t\t\t}\n\t\t\tif (c.barplot) {\n\t\t\t\t// barplot column\n\t\t\t\tth.text('') // quick fix; th.text() has been assigned above in order that sort button can show. here clear the text to render axis svg instead\n\t\t\t\tprepareBarPlot(c.barplot, i, rows)\n\t\t\t\tdrawBarplotAxis(c, th)\n\t\t\t\tif (c.sortable) addSort(th, i) //Add the sort after the scale and title is created\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n\n\tconst tbody = table.append('tbody')\n\tfunction updateRows() {\n\t\ttbody.selectAll('tr').remove()\n\t\tfor (const [rowIdx, row] of rows.entries()) {\n\t\t\tlet checkbox\n\t\t\tconst tr = tbody.append('tr').attr('class', 'sjpp_row_wrapper').attr('tabindex', 0)\n\t\t\tif (striped && rowIdx % 2 == 1) tr.style('background-color', 'rgb(245,245,245)')\n\n\t\t\t// for Section 508 compliance: always create an aria-labelledby attribute on an input\n\t\t\t// NOTE: a title attribute, wrapping with a label element, or other solutions are possible,\n\t\t\t// but using aria-labelled by is less likely to conflict with existing elem attributes or layout\n\t\t\tconst ariaLabelledBy = row.ariaLabelledBy || row[0]?.elemId || getUniqueNameOrId('td')\n\t\t\t// by default, assume that the first data cell should be used to label the input to its left,\n\t\t\t// and should create an element id on it as needed\n\t\t\tif (!row.ariaLabelledBy && row[0] && !row[0].elemId) row[0].elemId = ariaLabelledBy\n\n\t\t\tif (buttons || noButtonCallback) {\n\t\t\t\tconst clickHandler = (e: any) => {\n\t\t\t\t\t// fix for clicking on <a> check/unchecking box to the left\n\t\t\t\t\tif (e.target.tagName == 'A' || e.target.tagName == 'BUTTON' || e.target.tagName === 'INPUT') {\n\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (e.target !== checkbox.node()) {\n\t\t\t\t\t\tif (singleMode)\n\t\t\t\t\t\t\t//not a checkbox\n\t\t\t\t\t\t\tcheckbox.node().checked = true\n\t\t\t\t\t\telse checkbox.node().checked = !checkbox.node().checked\n\t\t\t\t\t\tcheckbox.dispatch('change')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttr.on('click', clickHandler)\n\t\t\t\ttr.on('keydown', event => {\n\t\t\t\t\t// ignore this event if it bubbled up from a descendant element\n\t\t\t\t\tif (event.target.tagName != 'TR') return\n\t\t\t\t\tif (event.key == 'Enter') clickHandler(event)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (showLines) {\n\t\t\t\ttr.append('td')\n\t\t\t\t\t.text(rowIdx + 1)\n\t\t\t\t\t.style('text-align', 'center')\n\t\t\t\t\t.style('width', '1vw')\n\t\t\t\t\t.style('font-size', '0.8rem')\n\t\t\t}\n\n\t\t\tif (buttons || noButtonCallback) {\n\t\t\t\tconst td = tr.append('td').style('width', '1.5vw').style('float', 'center')\n\t\t\t\tif (noRadioBtn) {\n\t\t\t\t\t// should be in singleMode and do not want to show radio buttons for cleaner look. <input> elements are still rendered since \"checkbox\" element is required for selection. thus simply hide <td>.\n\t\t\t\t\ttd.style('display', 'none')\n\t\t\t\t}\n\t\t\t\tconst checkboxValue = rowsCopy.findIndex(r => row == r)\n\t\t\t\tcheckbox = td\n\t\t\t\t\t.append('input')\n\t\t\t\t\t.attr('type', singleMode ? 'radio' : 'checkbox')\n\t\t\t\t\t.attr('name', uniqueInputName)\n\t\t\t\t\t.attr('value', checkboxValue)\n\t\t\t\t\t.attr('aria-labelledby', ariaLabelledBy)\n\t\t\t\t\t.property('checked', selectAll || selectedRows.includes(rowIdx))\n\t\t\t\t\t.on('change', () => {\n\t\t\t\t\t\tif (buttons) updateButtons()\n\t\t\t\t\t\telse noButtonCallback!(rowIdx, checkbox.node())\n\n\t\t\t\t\t\tconst checked = checkbox.property('checked')\n\t\t\t\t\t\tfor (const key in _selectedRowStyle) {\n\t\t\t\t\t\t\ttr.style(key, checked ? _selectedRowStyle[key] : '')\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\tif (noAutoScroll) {\n\t\t\t\t\t// this setting prevents auto scrolling. this is needed due to an unresolved defect that on showing a small table e.g. categorical tvs, the page scrolls undesirably\n\t\t\t\t\t// Edgar's comment: so the fix should just be to take the table height/table cell screen position into account. Somehow, scrollIntoView() is not accurate for the embedded table row\n\t\t\t\t} else {\n\t\t\t\t\t// table is allowed to auto scroll to selected rows. this is desirable to auto-show selected rows from a large table\n\t\t\t\t\t//Do not scroll when all rows are selected. Problem appears when sorting.\n\t\t\t\t\tif (selectedRows.length != rows.length && rowIdx === selectedRows[0] && tr.node()) {\n\t\t\t\t\t\t// if there is at least one selected row (but not all rows are selected),\n\t\t\t\t\t\t// scroll to the table row,so that it's visible and obvious to the user\n\t\t\t\t\t\t// which rows are pre-selected\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\ttr.node()?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n\t\t\t\t\t\t}, 500)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst checked = checkbox.property('checked')\n\t\t\t\tfor (const key in selectedRowStyle) {\n\t\t\t\t\ttr.style(key, checked ? selectedRowStyle[key] : '')\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (columnButtons && columnButtons.length > 0) {\n\t\t\t\tconst td = tr.append('td').attr('class', 'sjpp_table_item')\n\t\t\t\t// Assuming x is your variable\n\t\t\t\tfor (const button of columnButtons) {\n\t\t\t\t\tbutton.button = td\n\t\t\t\t\t\t.append('button')\n\t\t\t\t\t\t.style('white-space', 'normal')\n\t\t\t\t\t\t.text(button.text)\n\t\t\t\t\t\t.on('click', event => button.callback(event, rowIdx))\n\t\t\t\t\tif (button.dataTestId) {\n\t\t\t\t\t\tbutton.button.attr('data-testid', button.dataTestId)\n\t\t\t\t\t}\n\t\t\t\t\tif (button.class) button.button.attr('class', button.class)\n\t\t\t\t\tif ('disabled' in button) button.button.node().disabled = button.disabled!(rowIdx)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [colIdx, cell] of row.entries()) {\n\t\t\t\tconst td = tr\n\t\t\t\t\t.append('td')\n\t\t\t\t\t.attr('id', cell.elemId || null)\n\t\t\t\t\t.attr('class', 'sjpp_table_item')\n\t\t\t\t\t.attr('data-testid', cell.dataTestId || 'sjpp-table-cell-item')\n\n\t\t\t\t// attach <td> for external code to modify\n\t\t\t\tcell.__td = td\n\n\t\t\t\tconst column = columns[colIdx]\n\n\t\t\t\tif (column.barplot) {\n\t\t\t\t\tif (typeof cell.value === 'number') {\n\t\t\t\t\t\tdrawBarplotInCell(cell.value, td, column.barplot)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// column is not barplot\n\t\t\t\tif (column.editCallback && cell.value) {\n\t\t\t\t\ttd.on('click', (event: MouseEvent) => {\n\t\t\t\t\t\tevent.stopImmediatePropagation()\n\t\t\t\t\t\tconst isEdit = td.select('input').empty()\n\t\t\t\t\t\tif (!isEdit) return\n\t\t\t\t\t\ttd.html('')\n\t\t\t\t\t\tconst input = td\n\t\t\t\t\t\t\t.append('input')\n\t\t\t\t\t\t\t.attr('value', cell.value)\n\t\t\t\t\t\t\t.on('change', () => {\n\t\t\t\t\t\t\t\tconst value = input.node().value\n\t\t\t\t\t\t\t\tcell.value = value\n\t\t\t\t\t\t\t\ttd.text(cell.value)\n\t\t\t\t\t\t\t\tcolumn.editCallback!(rowIdx, cell)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\tinput.node().focus()\n\t\t\t\t\t\tinput.node().select()\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (column.width) td.style('width', column.width)\n\t\t\t\tif (column.align) td.style('text-align', column.align)\n\n\t\t\t\tif (column.nowrap) td.style('white-space', 'nowrap')\n\t\t\t\tif (cell.url) {\n\t\t\t\t\ttd.append('a')\n\t\t\t\t\t\t.text(cell.value || cell.value == 0 ? cell.value : cell.url) //Fix for if .value missing, url does not display\n\t\t\t\t\t\t.attr('href', cell.url)\n\t\t\t\t\t\t.attr('target', '_blank')\n\t\t\t\t} else if (cell.html) {\n\t\t\t\t\ttd.html(cell.html)\n\t\t\t\t} else if ('value' in cell) {\n\t\t\t\t\ttd.text(cell.value)\n\t\t\t\t\tif (cell.color) td.style('color', cell.color)\n\t\t\t\t} else if (cell.color) {\n\t\t\t\t\tif (cell.disabled) {\n\t\t\t\t\t\ttd.style('background-color', cell.color)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst input = td\n\t\t\t\t\t\t\t.append('input')\n\t\t\t\t\t\t\t.attr('type', 'color')\n\t\t\t\t\t\t\t.attr('value', cell.color)\n\t\t\t\t\t\t\t.on('change', () => {\n\t\t\t\t\t\t\t\tconst color = input.node().value\n\t\t\t\t\t\t\t\tcell.color = color\n\t\t\t\t\t\t\t\tif (column.editCallback) column.editCallback(rowIdx, cell)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else if (column.fillCell) {\n\t\t\t\t\tcolumn.fillCell(td, rowIdx)\n\t\t\t\t}\n\t\t\t}\n\t\t\t//Table code may update when the caller code does not (e.g. sorting)\n\t\t\t//Added event listeners in caller code will be lost when the rows update.\n\t\t\t//Allows for hover effects to remain consistent when the rows are updated.\n\t\t\tif (hoverEffects) hoverEffects(tr, row)\n\t\t}\n\t}\n\n\tupdateRows()\n\n\t// Create footer div if we have buttons OR if restore button should be in footer\n\tif (buttons || (allowRestoreRowOrder && restoreButtonInFooter)) {\n\t\tconst footerDiv = div\n\t\t\t.append('div')\n\t\t\t.insert('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('float', buttonsToLeft ? 'left' : 'right')\n\t\t\t.style('padding-bottom', '5px')\n\n\t\t// Add restore button to footer if requested (so button is grouped with other action buttons instead of separately below the table)\n\t\tif (allowRestoreRowOrder && restoreButtonInFooter) {\n\t\t\trestoreButton = footerDiv\n\t\t\t\t.append('button')\n\t\t\t\t.text('Restore row order')\n\t\t\t\t.attr('data-testid', 'sjpp-table-restore-button')\n\t\t\t\t.style('display', 'none') // Initially hidden\n\t\t\t\t.on('click', () => {\n\t\t\t\t\t// Restore original row order\n\t\t\t\t\trestoreButton.style('display', 'none')\n\n\t\t\t\t\tconst checked = getCheckedRowIndex()\n\t\t\t\t\tconst idxMap = new Map(rowsCopy.map((val, idx) => [val, idx]))\n\t\t\t\t\tselectedRows = checked.map(i => originalRows.findIndex((v: TableCell[]) => idxMap.get(v) === i))\n\n\t\t\t\t\t/** Must override caller setting once user selects row(s) */\n\t\t\t\t\tif (selectedRows.length) selectAll = false\n\n\t\t\t\t\t// Reset all sort button states\n\t\t\t\t\tfor (const resetFn of sortButtonResetFns) resetFn()\n\n\t\t\t\t\trows = originalRows.map(i => i) // Create a copy\n\t\t\t\t\tupdateRows()\n\t\t\t\t})\n\t\t}\n\n\t\tif (buttons) {\n\t\t\tfor (const bCfg of buttons) {\n\t\t\t\tbCfg.button = footerDiv\n\t\t\t\t\t.append('button')\n\t\t\t\t\t.text(bCfg.text)\n\t\t\t\t\t.style('margin', '10px 10px 0 0')\n\t\t\t\t\t.on('click', () => {\n\t\t\t\t\t\tbCfg.callback(getCheckedRowIndex(), bCfg.button.node())\n\t\t\t\t\t})\n\t\t\t\tif (bCfg.class) bCfg.button.attr('class', bCfg.class)\n\t\t\t\tif (bCfg.dataTestId) bCfg.button.attr('data-testid', bCfg.dataTestId)\n\t\t\t\tbCfg.button.node().disabled = selectedRows.length == 0 && !selectAll\n\t\t\t}\n\n\t\t\t// call function to update buttons with .onChange(), so their text can reflect default checkbox selection\n\t\t\tupdateButtons()\n\t\t}\n\t}\n\n\tfunction updateButtons() {\n\t\tif (!buttons) return\n\t\tconst idxlst = getCheckedRowIndex()\n\t\tfor (const b of buttons) {\n\t\t\tb.button.node().disabled = idxlst.length == 0\n\t\t\tif (b.onChange) b.onChange(idxlst, b.button.node())\n\t\t}\n\t}\n\n\t/** Returns the index from the original input array\n\t * (captured in rowsCopy) not the current array index. */\n\tfunction getCheckedRowIndex() {\n\t\tconst checkboxes = tbody.selectAll('input:checked')\n\t\tconst idxlst: number[] = []\n\t\tif (!checkboxes.empty()) {\n\t\t\tcheckboxes.each((d, i, nodes) => {\n\t\t\t\tconst node = nodes[i]\n\t\t\t\tidxlst.push(Number.parseInt(node.value))\n\t\t\t})\n\t\t}\n\t\treturn idxlst\n\t}\n\n\tfunction addSort(th: Th, i: number) {\n\t\tconst callback = (isAscending: boolean) => sortTableCallBack(i, rows, isAscending)\n\t\tconst updateTable = (newRows: TableCell[][]) => {\n\t\t\tconst checked = getCheckedRowIndex()\n\t\t\tconst idxMap = new Map(rowsCopy.map((val, idx) => [val, idx]))\n\t\t\tselectedRows = checked.map(i => newRows.findIndex((v: TableCell[]) => idxMap.get(v) === i))\n\n\t\t\t/** Must override caller setting once user selects row(s) */\n\t\t\tif (selectedRows.length) selectAll = false\n\n\t\t\trows = newRows\n\t\t\tupdateRows()\n\n\t\t\t// Show restore button when table is sorted (and allowRestoreRowOrder is true)\n\t\t\tif (allowRestoreRowOrder) {\n\t\t\t\tif (restoreButtonInFooter && restoreButton) {\n\t\t\t\t\trestoreButton.style('display', 'inline-block')\n\t\t\t\t} else if (restoreButtonDiv) {\n\t\t\t\t\trestoreButtonDiv.style('display', 'block')\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst resetFn = createSortButton(th, callback, updateTable)\n\t\tsortButtonResetFns.push(resetFn)\n\t}\n\n\tconst api = {\n\t\tupdate(opts) {\n\t\t\tif (opts.selectedRowStyle) {\n\t\t\t\t_selectedRowStyle = opts.selectedRowStyle\n\t\t\t\tconst trs = tbody.selectAll('tr')\n\t\t\t\tfor (const key in _selectedRowStyle) {\n\t\t\t\t\ttrs.style(key, function (this: any) {\n\t\t\t\t\t\treturn select(this).select('td input').property('checked') ? _selectedRowStyle[key] : ''\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn api\n}\n\n/**\n * Downloads table data as a TSV (Tab-Separated Values) file.\n *\n * @param {Array<Array<Cell>>} rows - Array of rows, where each row is an array of cell objects.\n * Each cell object can have one of the following properties:\n * - value: The primary content to display (can be string, number, including 0)\n * - url: A URL to be used if value is not present\n * - color: A color value to be used if neither value nor url is present\n * @param {Array<TableColumn>} cols - Array of column definition objects.\n * Each column object must have:\n * - label: string - The header text for the column\n * @param {string} [filename='table.tsv'] - Optional custom filename for the downloaded file\n *\n * @example\n * // Basic usage\n * const rows = [\n * [{ value: \"John\" }, { value: 25 }, { value: \"New York\" }],\n * [{ value: \"Jane\" }, { value: 0 }, { value: \"Boston\" }]\n * ];\n * const cols = [\n * { label: \"Name\" },\n * { label: \"Age\" },\n * { label: \"City\" }\n * ];\n * await downloadTable(rows, cols, \"users.tsv\");\n *\n * @example\n * // Using different cell property types\n * const rows = [\n * [{ value: \"Doc\" }, { url: \"https://example.com\" }, { color: \"#FF0000\" }]\n * ];\n * const cols = [\n * { label: \"Name\" },\n * { label: \"Link\" },\n * { label: \"Color\" }\n * ];\n * await downloadTable(rows, cols);\n *\n * @returns {Promise<void>} - The function creates and triggers a download in the browser\n */\nexport async function downloadTable(rows, cols, filename = 'table.tsv') {\n\tlet lines = ''\n\n\t// Add header row with column labels\n\tfor (const column of cols) {\n\t\tlines += `${column.label}\\t`\n\t}\n\tlines += '\\n'\n\n\t// Add data rows\n\tfor (const row of rows) {\n\t\tfor (const cell of row) {\n\t\t\tlet value = ''\n\t\t\t// Check for cell.value existence to properly handle zero values\n\t\t\tif ('value' in cell) value = cell.value\n\t\t\telse if (cell.url) value = cell.url\n\t\t\telse if (cell.color) value = cell.color\n\t\t\tlines += `${value}\\t`\n\t\t}\n\t\tlines += '\\n'\n\t}\n\n\t// Create and trigger download\n\tconst dataStr = 'data:text/tsv;charset=utf-8,' + encodeURIComponent(lines)\n\tconst link = document.createElement('a')\n\tlink.setAttribute('href', dataStr)\n\t// If you don't know the name or want to use\n\t// the webserver default set name = ''\n\tlink.setAttribute('download', filename)\n\tdocument.body.appendChild(link)\n\tlink.click()\n\tlink.remove()\n}\n\n/** Toggles between ascending and descending sort\n * Returns a reset function to reset the sort state */\nfunction createSortButton(th: Th, callback, updateTable) {\n\tlet isAscending = false\n\tconst sortDiv = th.append('div').style('display', 'inline-block').attr('class', 'sjpp-table-sort-button')\n\ticons['updown'](sortDiv, {\n\t\thandler: () => {\n\t\t\tisAscending = !isAscending\n\t\t\tconst newRows = callback(isAscending)\n\t\t\tupdateTable(newRows)\n\t\t}\n\t})\n\t// Return a function to reset this sort button's state\n\treturn () => {\n\t\tisAscending = false\n\t}\n}\n\n/** Detects the type of values in a column and sorts accordingly */\nexport function sortTableCallBack(i: number, rows: any, isAscending: boolean) {\n\t/** Some values always returned as strings may be numeric values\n\t * (e.g. file names used as either alphanumeric or numeric ids).\n\t * In the latter case, sorting fails.\n\t * Detect such columns and sort the value as numbers */\n\tlet allNumStrs = true\n\tfor (let r = 0; r < rows.length; r++) {\n\t\tconst v = rows[r][i].value\n\t\tif (typeof v !== 'string' || !Number.isFinite(+v)) {\n\t\t\tallNumStrs = false\n\t\t\tbreak\n\t\t}\n\t}\n\tconst newRows = rows.sort((a: TableCell, b: TableCell) => {\n\t\tconst aVal = a[i].value\n\t\tconst bVal = b[i].value\n\n\t\tif ((aVal == null && aVal !== 0) || (bVal == null && bVal !== 0)) return 0\n\t\t// numbers\n\t\tif (typeof aVal === 'number' && typeof bVal === 'number') {\n\t\t\treturn isAscending ? aVal - bVal : bVal - aVal\n\t\t}\n\t\t// numeric strings, detected above\n\t\tif (allNumStrs) {\n\t\t\tconst aNum = +aVal\n\t\t\tconst bNum = +bVal\n\t\t\treturn isAscending ? aNum - bNum : bNum - aNum\n\t\t}\n\t\t// regular strings\n\t\tif (typeof aVal === 'string' && typeof bVal === 'string') {\n\t\t\treturn isAscending ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal)\n\t\t}\n\t\treturn 0\n\t})\n\treturn newRows\n}\n\nfunction prepareBarPlot(cb: TableBarplot, i: number, rows: any) {\n\tif (!cb.axisWidth) cb.axisWidth = 130\n\tif (!cb.colorPositive) cb.colorPositive = '#d49353'\n\tif (!cb.colorNegative) cb.colorNegative = '#5256d1'\n\tif (!cb.xpadding) cb.xpadding = 5\n\tlet min: number | null = null,\n\t\tmax: number | null = null\n\tfor (const r of rows) {\n\t\tconst v = r[i].value\n\t\tif (!Number.isFinite(v)) continue // ignore invalid value\n\t\tif (min == null) {\n\t\t\tmin = v\n\t\t\tmax = v\n\t\t} else {\n\t\t\tmin = Math.min(min as number, v)\n\t\t\tmax = Math.max(max as number, v)\n\t\t}\n\t}\n\tif (min !== null && max !== null && min < 0 && max > 0) {\n\t\t// force equal span on both sides\n\t\tconst a = Math.max(-min, max)\n\t\tmin = -a\n\t\tmax = a\n\t}\n\tcb.scale = scaleLinear()\n\t\t.domain([min ?? 0, max ?? 0])\n\t\t.range([0, cb.axisWidth])\n}\n\nfunction drawBarplotAxis(c: TableColumn, th: any) {\n\tconst cb = c.barplot! // assert it is truthy\n\tconst labfontsize = 14\n\tconst ypad = 5 // padding between axis label and axis\n\tconst tickfontsize = 12\n\tconst ticksize = 4 // where is ticksize applied in axis?\n\tconst svg = th\n\t\t.append('svg')\n\t\t.attr('width', 2 * (cb.xpadding || 0) + (cb.axisWidth || 0))\n\t\t.attr('height', labfontsize + ypad + tickfontsize + ticksize + 1) // plus 1 so axis bottom line can fully show\n\tconst axis = axisTop(cb.scale).ticks(cb.tickCount || 4)\n\tif (cb.tickFormat) axis.tickFormat(d3format(cb.tickFormat) as (domainValue: AxisDomain, index: number) => string)\n\n\taxisstyle({\n\t\taxis: svg\n\t\t\t.append('g')\n\t\t\t.attr('transform', `translate(0,${labfontsize + ypad + tickfontsize + ticksize})`)\n\t\t\t.call(axis),\n\t\tcolor: 'black',\n\t\tshowline: true\n\t})\n\tsvg\n\t\t.append('text')\n\t\t.attr('fill', 'black')\n\t\t.attr('font-size', labfontsize)\n\t\t.attr('text-anchor', 'middle')\n\t\t.text(c.label)\n\t\t.attr('x', (cb.xpadding || 0) + (cb.axisWidth || 0) / 2)\n\t\t.attr('y', labfontsize)\n}\n\nfunction drawBarplotInCell(value: number, td: any, c: TableBarplot) {\n\tif (!Number.isFinite(value)) return\n\tconst [min, max] = c.scale.domain()\n\tlet x1, x2, color\n\tif (min >= 0) {\n\t\t// all positive values\n\t\tx1 = 0 // bar starts at left and extends to right\n\t\tx2 = c.scale(value)\n\t\tcolor = c.colorPositive\n\t} else if (max <= 0) {\n\t\t// all neg values\n\t\tx2 = c.axisWidth //bar starts at right and extends to left\n\t\tx1 = c.scale(value)\n\t\tcolor = c.colorNegative\n\t} else {\n\t\tconst x0 = c.scale(0)\n\t\tconst xv = c.scale(value)\n\t\tx1 = Math.min(x0, xv)\n\t\tx2 = Math.max(x0, xv)\n\t\tcolor = value > 0 ? c.colorPositive : c.colorNegative\n\t}\n\tconst height = 14\n\ttd.append('svg')\n\t\t.style('margin-top', '4px') // poor fix for the svg to appear in middle of <td> vertically\n\t\t.attr('width', 2 * (c.xpadding ?? 0) + (c.axisWidth ?? 0))\n\t\t.attr('height', height)\n\t\t.append('rect')\n\t\t.attr('data-testid', 'sjpp-table-barplot-item')\n\t\t.attr('x', x1)\n\t\t.attr('y', 0)\n\t\t.attr('width', Math.max(1, x2 - x1)) // avoid bar width of fraction of pixel\n\t\t.attr('height', height)\n\t\t.attr('fill', color)\n}\n", "import * as rx from '../rx'\nimport { select } from 'd3-selection'\nimport { Menu } from '../dom/menu'\nimport { renderTable } from '../dom/table'\nimport { isNumericTerm, isCategoricalTerm, dtTermTypes } from '#shared/terms.js'\n\n/*\n********************** EXPORTED\nTVSInit()\nshowTvsMenu()\n********************** INTERNAL\nsetRenderers(self)\n\tupdateUI()\n\tenterPill()\n\tupdatePill()\n\texitPill()\n\tshowMenu()\n\tmakeValueTable()\n\tremoveValueBtn()\nsetInteractivity()\naddExcludeCheckbox()\n*/\n\nconst tsHandlers = new Set(['termCollection'])\n\nclass TVS {\n\tconstructor(opts) {\n\t\tthis.opts = this.validateOpts(opts)\n\t\tthis.dom = { holder: opts.holder, tip: new Menu({ padding: '5px' }) }\n\t\tthis.durations = { exit: 0 }\n\n\t\tsetInteractivity(this)\n\t\tsetRenderers(this)\n\t\tthis.categoryData = {}\n\t\tthis.handlerByType = {}\n\t\tthis.api = {\n\t\t\tmain: this.main.bind(this),\n\t\t\tshowMenu: this.showMenu\n\t\t}\n\t}\n\n\tvalidateOpts(o) {\n\t\tif (!o.holder) throw '.holder missing'\n\t\tif (!o.vocabApi) throw '.vocabApi missing'\n\t\tif (typeof o.callback != 'function') throw '.callback() is not a function'\n\t\treturn o\n\t}\n\n\tasync main(data = {}) {\n\t\tthis.tvs = data.tvs\n\t\tthis.filter = data.filter\n\t\tawait this.setHandler()\n\t\tawait this.updateUI()\n\t\t// when there are filters to be removed, must account for the delayed\n\t\t// removal after opacity transition, as btn count will decrease only\n\t\t// after the transition and remove() is done\n\t\t//\n\t\t// !!! TODO: how to pass bus.emit('postRender') delay to rx.component.api.update()\n\t\t// this.bus.emit('postRender', null, filters.exit().size() ? this.durations.exit + 100 : 0)\n\t}\n\n\tasync setHandler() {\n\t\tif (!this.tvs || !this.tvs.term) return\n\t\tconst term = this.tvs.term\n\t\tconst type = isNumericTerm(term)\n\t\t\t? 'numeric'\n\t\t\t: isCategoricalTerm(term)\n\t\t\t? 'categorical'\n\t\t\t: term.type == 'dtcnv'\n\t\t\t? this.getDtCnvType(term)\n\t\t\t: term.type\n\t\tif (!this.handlerByType[type]) {\n\t\t\ttry {\n\t\t\t\tconst _ = tsHandlers.has(type) ? await import(`./tvs.${type}.ts`) : await import(`./tvs.${type}.js`)\n\t\t\t\tconst handler = _.handler\n\t\t\t\tthis.handlerByType[type] = handler\n\t\t\t} catch (e) {\n\t\t\t\tthrow `error with handler='./tvs.${type}.js': ${e}`\n\t\t\t}\n\t\t}\n\t\tthis.handler = this.handlerByType[type]\n\t}\n\n\tgetDtCnvType(term) {\n\t\t// determine dtcnv type by whether cnv data is continuous or categorical\n\t\tif (term.type != 'dtcnv') return\n\t\tconst cnv = this.opts.vocabApi.termdbConfig.queries?.cnv\n\t\tif (!cnv) throw 'cnv query is missing'\n\t\tconst keys = Object.keys(cnv)\n\t\tconst mode = keys.includes('cnvGainCutoff') || keys.includes('cnvLossCutoff') ? 'continuous' : 'categorical'\n\t\treturn term.type + '.' + mode\n\t}\n}\n\nexport const TVSInit = rx.getInitFxn(TVS)\n\nfunction setRenderers(self) {\n\tself.updateUI = function () {\n\t\tconst terms_div = self.dom.holder\n\t\t/*\n\t\t\tCurrently, only a single pill per tvs is rendered, so using the \n\t\t\tarray [self.tvs] may seem unnecessary. However, using the\n\t\t\tenter/update/exit pattern helps with coding consistency across components,\n\t\t\tand more clearly indicates whether the whole pill is replaced\n\t\t\tor if only its values are updated.\n\t\t*/\n\t\tconst filters = terms_div.selectAll('.tvs_pill').data([self.tvs], tvs => tvs?.term.id)\n\t\tfilters.exit().each(self.exitPill)\n\t\tfilters.each(self.updatePill)\n\t\tfilters\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'tvs_pill')\n\t\t\t.style('white-space', 'nowrap')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.transition()\n\t\t\t.duration(200)\n\t\t\t.each(self.enterPill)\n\t}\n\n\tself.enterPill = async function () {\n\t\tconst one_term_div = select(this).style('font-size', '.9em')\n\n\t\t//term name div\n\t\tone_term_div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'term_name_btn sja_filter_tag_btn')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('border-radius', '6px 0 0 6px')\n\t\t\t.style('padding', '6px 6px 3px 6px')\n\t\t\t.html(self.handler.term_name_gen)\n\t\t\t.style('text-transform', 'uppercase')\n\n\t\t// negate button\n\t\tone_term_div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'negate_btn')\n\t\t\t.style('cursor', 'default')\n\t\t\t//.style('display', 'inline-block' : 'none')\n\t\t\t.style('padding', '6px 6px 3px 6px')\n\t\t\t.style('background', self.tvs.isnot ? '#f4cccc' : '#a2c4c9')\n\t\t\t.html(\n\t\t\t\tself.handler.getNegateText?.(self) || (self.tvs.isnot && self.tvs.term.type !== 'geneVariant' ? 'NOT' : 'IS')\n\t\t\t)\n\n\t\tself.updatePill.call(this)\n\t}\n\n\t// optional _holder, for example when called by filter.js\n\tself.showMenu = async _holder => {\n\t\tconst holder = _holder ? _holder : self.dom.tip\n\t\tconst loadingDiv = holder.append('div').style('padding', '10px').text('Loading ...')\n\t\ttry {\n\t\t\tif (!dtTermTypes.has(self.tvs.term.type)) {\n\t\t\t\taddExcludeCheckbox(holder, self.tvs, self)\n\t\t\t}\n\t\t\tawait self.handler.fillMenu(self, holder, self.tvs)\n\t\t\tloadingDiv.remove()\n\t\t} catch (e) {\n\t\t\tloadingDiv.text('Error: ' + (e.message || e))\n\t\t\tif (e.stack) console.log(e)\n\t\t}\n\t}\n\n\tself.updatePill = async function () {\n\t\tconst one_term_div = select(this)\n\t\tconst tvs = one_term_div.datum()\n\t\tconst lstlen =\n\t\t\t(self.tvs.values && self.tvs.values.length) ||\n\t\t\t(self.tvs.ranges && self.tvs.ranges.length) ||\n\t\t\tself.tvs.term.type == 'samplelst' ||\n\t\t\tdtTermTypes.has(self.tvs.term.type)\n\n\t\t// update the main label\n\t\tone_term_div.select('.term_name_btn').html(self.handler.term_name_gen)\n\t\t// negate button\n\t\tone_term_div\n\t\t\t.select('.negate_btn')\n\t\t\t.style('display', lstlen ? 'inline-block' : 'none')\n\t\t\t.style('background', self.tvs.isnot ? '#f4cccc' : '#a2c4c9')\n\t\t\t.html(self.handler.getNegateText?.(self) || (tvs.isnot && tvs.term.type !== 'geneVariant' ? 'NOT' : 'IS'))\n\n\t\tconst label = self.handler.get_pill_label(tvs)\n\t\tif (!('grade_type' in label)) label.grade_type = ''\n\n\t\tconst value_btns = one_term_div.selectAll('.value_btn').data(label ? [label] : [], d => d.txt + d.grade_type)\n\n\t\tvalue_btns.exit().each(self.removeValueBtn)\n\n\t\tvalue_btns\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'value_btn sja_filter_tag_btn')\n\t\t\t.style('display', lstlen ? 'inline-block' : 'none')\n\t\t\t.style('padding', '6px 6px 3px 6px')\n\t\t\t.style('border-radius', '0 6px 6px 0')\n\t\t\t.style('font-style', 'italic')\n\t\t\t.html(d => d.txt)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'grade_type_btn')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('margin', '0 5px')\n\t\t\t.style('font-size', '.6em')\n\t\t\t.style('text-transform', 'uppercase')\n\t\t\t.html(d => d.grade_type)\n\t\t\t.style('opacity', 0)\n\t\t\t.transition()\n\t\t\t.duration(200)\n\t\t\t.style('opacity', 1)\n\t}\n\n\tself.exitPill = async function (term) {\n\t\tselect(this).style('opacity', 1).transition().duration(self.durations.exit).style('opacity', 0).remove()\n\t}\n\n\tself.makeValueTable = function (div, tvs, values, callback) {\n\t\tif (values?.length == 0) return div\n\t\tconst containerDiv = div.append('div').style('font-size', '0.8rem')\n\n\t\tconst tableDiv = containerDiv.append('div')\n\t\t// add barchart bar_width for values\n\t\tconst maxCount = Math.max(...values.map(v => v.samplecount), 0)\n\t\tvalues.forEach(v => (v.bar_width_frac = Number((1 - (maxCount - v.samplecount) / maxCount).toFixed(4))))\n\n\t\tconst maxBarWidth = 100\n\t\tconst rows = []\n\t\tconst selectedIdxs = []\n\t\tfor (const [i, value] of values.entries()) {\n\t\t\tlet label = value.label || value.key\n\t\t\tif (value.samplecount) label += ' (n=' + value.samplecount + ')'\n\t\t\tconst barWidth = maxBarWidth * value.bar_width_frac\n\t\t\tconst bar_td = `<div style='margin:1px 10px;width:${barWidth}px;height:15px;background-color:#ddd'>`\n\t\t\trows.push([{ value: label }, { html: bar_td }])\n\t\t\tlet checked = false\n\t\t\tif (tvs.term.type == 'categorical' || tvs.term.type == 'survival' || dtTermTypes.has(tvs.term.type))\n\t\t\t\tchecked = tvs.values.find(a => a.key === value.key)\n\t\t\telse if (tvs.term.type == 'float' || tvs.term.type == 'integer')\n\t\t\t\tchecked = tvs.ranges.find(a => String(a.value) === value.value.toString())\n\t\t\telse if (tvs.term.type == 'condition') checked = tvs.values.find(a => String(a.key) === String(value.key))\n\t\t\tif (checked) selectedIdxs.push(i)\n\t\t}\n\t\tconst columns = [{ label: 'tvs' }, { label: 'bar' }]\n\t\tconst applybt = {\n\t\t\ttext: 'APPLY',\n\t\t\tclass: 'sjpp_apply_btn sja_filter_tag_btn',\n\t\t\tcallback: indexes => {\n\t\t\t\tif (callback) callback(indexes)\n\t\t\t}\n\t\t}\n\n\t\tself.tableApi = renderTable({\n\t\t\trows,\n\t\t\tcolumns,\n\t\t\tdiv: tableDiv,\n\t\t\tmaxWidth: '40vw',\n\t\t\tmaxHeight: '40vh',\n\t\t\tbuttons: [applybt],\n\t\t\tshowHeader: false,\n\t\t\tstriped: false,\n\t\t\tshowLines: false,\n\t\t\tselectedRows: selectedIdxs,\n\t\t\tnoAutoScroll: true,\n\t\t\tselectedRowStyle: {\n\t\t\t\t'text-decoration': tvs.isnot ? 'line-through' : ''\n\t\t\t}\n\t\t})\n\n\t\treturn tableDiv\n\t}\n\n\tself.removeValueBtn = function (d, j) {\n\t\tconst one_term_div = select(this.parentNode)\n\t\tconst tvs = one_term_div.datum()\n\t\tconst select_remove_pos = self.handler.getSelectRemovePos(j, tvs)\n\n\t\tselect(one_term_div.selectAll('.value_select')._groups[0][select_remove_pos]).remove()\n\t\tselect(one_term_div.selectAll('.or_btn')._groups[0][j]).remove()\n\t\tselect(this).style('opacity', 1).transition().duration(self.durations.exit).style('opacity', 0).remove()\n\t}\n}\n\nfunction setInteractivity(self) {\n\t// optional event handlers\n}\n\n// opts is the same argument for the TVS constructor()\nexport async function showTvsMenu(opts) {\n\tconst self = new TVS(opts)\n\tself.tvs = {\n\t\tterm: opts.term\n\t}\n\tself.filter = opts.filter\n\t//addExcludeCheckbox(opts.holder, self.tvs)\n\n\tconst loadingDiv = opts.holder.append('div').style('padding', '10px').text('Loading ...')\n\n\ttry {\n\t\tawait self.setHandler()\n\t\tif (self.handler.setTvsDefaults) self.handler.setTvsDefaults(self.tvs)\n\t\tawait self.handler.fillMenu(self, opts.holder, self.tvs)\n\t\tloadingDiv.remove()\n\t} catch (e) {\n\t\tloadingDiv.text('Error: ' + (e.message || e))\n\t\tif (e.stack) console.log(e)\n\t}\n}\n\nfunction addExcludeCheckbox(holder, tvs, self) {\n\tconst isNotLabels = holder\n\t\t.selectAll('label')\n\t\t.data([{ label: 'Exclude', value: 'false', checked: tvs.isnot !== undefined ? tvs.isnot : false }])\n\t\t.enter()\n\t\t.append('label')\n\t\t.style('margin', '0 5px')\n\tconst isNotInput = isNotLabels\n\t\t.append('input')\n\t\t.attr('type', 'checkbox')\n\t\t.attr('name', 'sja_filter_isnot_input')\n\t\t.attr('value', d => d.value)\n\t\t.property('checked', d => d.checked)\n\t\t.style('vertical-align', 'top')\n\t\t.style('margin-right', '3px')\n\t\t.on('change', () => {\n\t\t\ttvs.isnot = isNotInput.node().checked\n\n\t\t\tif (self.tableApi) {\n\t\t\t\tself.tableApi.update({\n\t\t\t\t\tselectedRowStyle: {\n\t\t\t\t\t\t'text-decoration': tvs.isnot ? 'line-through' : ''\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\tisNotLabels\n\t\t.append('span')\n\t\t.style('margin-right', '5px')\n\t\t.style('vertical-align', 'top')\n\t\t.html(d => d.label)\n}\n", "/***********************\n Utilities\n*************************/\n\nimport { getWrappedTvslst } from '#shared/filter.js'\nexport { getWrappedTvslst } from '#shared/filter.js'\n\n// find the first filter item that has a matching term.id\nexport function findItemByTermId(item, id) {\n\tif (item.type === 'tvs' && item.tvs.term.id === id) return item\n\tif (item.type !== 'tvslst') return\n\tfor (const subitem of item.lst) {\n\t\tconst matchingItem = findItemByTermId(subitem, id)\n\t\tif (matchingItem) return matchingItem\n\t}\n}\n\n// find filter item by the sequential $id\n// assigned at the time of adding a filter entry\nexport function findItem(item, $id) {\n\tif (item.$id === $id) return item\n\tif (item.type !== 'tvslst') return\n\tfor (const subitem of item.lst) {\n\t\tconst matchingItem = findItem(subitem, $id)\n\t\tif (matchingItem) return matchingItem\n\t}\n}\n\nexport function findParent(parent, $id) {\n\tif (parent.$id === $id) return parent\n\tif (!parent.lst) return\n\tfor (const item of parent.lst) {\n\t\tif (item.$id === $id) return parent\n\t\telse if (item.type == 'tvslst') {\n\t\t\tconst matchingParent = findParent(item, $id)\n\t\t\tif (matchingParent) return matchingParent\n\t\t}\n\t}\n}\n\nexport function getFilterItemByTag(item, tag) {\n\tif (item?.tag === tag) return item\n\tif (item?.type !== 'tvslst') return\n\tfor (const subitem of item.lst) {\n\t\tconst matchingItem = getFilterItemByTag(subitem, tag)\n\t\tif (matchingItem) return matchingItem\n\t}\n}\n\nexport function excludeFilterByTag(filter, tag) {\n\tif (!filter) return getNormalRoot(filter)\n\tif (!filter?.lst) return filter\n\tfor (const [i, f] of filter.lst.entries()) {\n\t\tif (f.tag === tag) {\n\t\t\tfilter.lst.splice(i, 1)\n\t\t\tbreak\n\t\t} else if (f.lst) {\n\t\t\texcludeFilterByTag(f, tag)\n\t\t}\n\t}\n\treturn getNormalRoot(filter)\n}\n\n/*\n\tget valid filter data to be used for server requests\n\twill use normalizeFilter recursively as needed\n\n\t.filter{} the raw filter root\n*/\nexport function getNormalRoot(rawFilter) {\n\tif (!rawFilter) return getWrappedTvslst([])\n\t// create a copy, as needed, to not modify the original\n\tconst encoded = typeof rawFilter == 'string' ? rawFilter : JSON.stringify(rawFilter)\n\tconst filter = JSON.parse(encoded)\n\tconst processedFilter = normalizeFilter(filter)\n\treturn processedFilter.type == 'tvslst' ? processedFilter : getWrappedTvslst([processedFilter])\n}\n\n/* \n\tPotentially\n\t- restructure the filter data in a shape \n\tallowed by the server, such as by\n removing an empty tvslst or converting a \n\tsingle-entry tvslst into a tvs\n\t- also will remove unnecessary filter properties\n\tvia normalizeProps()\n\n\t.filter{} the raw filter root or a subnested filter\n*/\nfunction normalizeFilter(filter) {\n\tif (typeof filter != 'object') throw `filter must be an object`\n\tdelete filter.$id\n\tdelete filter.tag\n\tif (filter.tyoe == 'tvs') return filter\n\tif (filter.type != 'tvslst') throw `filter.type must be either 'tvslst' or 'tvs'`\n\n\tconst lst = filter.lst\n\t\t// keep non-tvslst entries or tvslst with non-empty lst.length\n\t\t.filter(f => f.type !== 'tvslst' || f.lst.length > 0)\n\t\t// do not reformat an entry unless it is a tvslst with only one entry,\n\t\t// in which case just return that filter's first lst entry and negated as needed,\n\t\t// instead of returning the filter itself\n\t\t.map(f => {\n\t\t\tif (f.type !== 'tvslst' || f.lst.length > 1) return f\n\t\t\t// f.in defaults to true if missing, negation requires a strict boolean false\n\t\t\tif (f.in !== false) return f.lst[0]\n\t\t\tif (f.lst[0].type !== 'tvs') throw `unable to handle filter entry type='${f.lst[0].type}'`\n\t\t\tif (!f.lst[0].tvs) throw `missing filter entry tvs`\n\t\t\t// handle a single-entry tvslst where filter.in != true, which is not created from the filter UI,\n\t\t\t// but may be created internally by non-UI code, so need to support under the hood\n\t\t\tf.lst[0].tvs.isnot = !f.lst[0].tvs.isnot\n\t\t\t// return the single entry after applying the tvslst negation to the tvs itself\n\t\t\treturn f.lst[0]\n\t\t})\n\n\tlst.forEach(normalizeProps)\n\n\tif (!lst.length) {\n\t\t// return a default empty filter = {type: 'tvslst', lst:[], ...}\n\t\treturn getWrappedTvslst([], '', filter.$id)\n\t} else if (lst.length == 1) {\n\t\t// return the only lst entry after normalizing\n\t\tif (lst[0].type === 'tvslst') {\n\t\t\treturn normalizeFilter(lst[0])\n\t\t} else {\n\t\t\treturn normalizeProps(lst[0])\n\t\t}\n\t} else {\n\t\t// reset and fill-in filter.lst with normalized entries\n\t\tfilter.lst = []\n\t\tfor (const item of lst) {\n\t\t\tif (item.type === 'tvslst') {\n\t\t\t\tconst normalItem = normalizeFilter(item)\n\t\t\t\tif (normalItem.type !== 'tvslst' || normalItem.join != filter.join || normalItem.in != filter.in) {\n\t\t\t\t\tfilter.lst.push(normalItem)\n\t\t\t\t} else if (normalItem.lst.length) {\n\t\t\t\t\t// can flatten and level up the subnested filter.lst items with matching join, in\n\t\t\t\t\tfilter.lst.push(...normalItem.lst)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfilter.lst.push(item)\n\t\t\t}\n\t\t}\n\t\treturn filter\n\t}\n}\n\n/*\n\twill remove unnecessary filter properties\n\tthat are not expected in a server request\n\n\t.filter{} the raw filter root or a subnested filter\n*/\nexport function normalizeProps(filter, callback = null) {\n\tdelete filter.$id\n\tif (typeof callback == 'function') callback(filter)\n\tif (filter.type == 'tvslst') {\n\t\tfor (const item of filter.lst) {\n\t\t\tnormalizeProps(item, callback)\n\t\t}\n\t}\n\treturn filter\n}\n\n/* join a list of filters into the first filter with \"and\", return joined filter\nto be used by caller app to join hidden filters into a visible filter\n\nlst:[]\n a list of filters\n the function returns a (modified) copy of the first filter, and will not modify it\n rest of the array will be joined to the first one under \"and\"\n*/\nexport function filterJoin(lst) {\n\tif (!Array.isArray(lst)) throw 'filterJoin() arg is not array'\n\tif (!lst[0]) return\n\tlet f = JSON.parse(JSON.stringify(lst[0]))\n\tif (lst.length == 1) return getNormalRoot(f) // TODO: are there cases where non-normalize shape is needed from filterJoin()?\n\t// more than 1 item, will join\n\tif (f.lst.length < 2) {\n\t\tif (f.join !== '') throw 'filter.join must be an empty string \"\" when filter.lst.length < 2'\n\t\tf.join = 'and'\n\t} else if (f.join == 'or' || f.in === false) {\n\t\t// f is \"or\", wrap it with another root layer of \"and\"\n\t\tf = {\n\t\t\ttype: 'tvslst',\n\t\t\tjoin: 'and',\n\t\t\tin: true,\n\t\t\tlst: [f]\n\t\t}\n\t} else if (f.join != 'and') {\n\t\tthrow 'filter.join must be either \"and\" or \"or\" when .lst length > 1'\n\t}\n\t// now, f.join should be \"and\"\n\t// if the argument lst[0].join == \"and\",\n\t// then the f.in boolean value is reused\n\tfor (let i = 1; i < lst.length; i++) {\n\t\tconst f2 = JSON.parse(JSON.stringify(lst[i]))\n\t\tif (f2.join == 'or' || f2.in === false) f.lst.push(f2)\n\t\telse f.lst.push(...f2.lst)\n\t}\n\t// if f ends up single-tvs item (from joining single tvs to empty filter), need to set join to '' per filter spec\n\tif (f.lst.length == 1 && f.lst[0].type == 'tvs') {\n\t\tf.join = ''\n\t}\n\treturn getNormalRoot(f) // TODO: are there cases where non-normalize shape is needed from filterJoin()?\n}\n\n/* make copy of input filter, return negated copy\nif tag=filterUiRoot is found, negate that;\nelse, assume is tvslst of single tvs an negate at tvs level\n\nallow other tags for future use\n*/\nexport function negateFilter(f0, tag = 'filterUiRoot') {\n\tconst f = structuredClone(f0)\n\tconst fui = getFilterItemByTag(f, tag)\n\tif (fui) {\n\t\tif (typeof fui.in != 'boolean') throw 'filterUiRoot f.in is not boolean'\n\t\tfui.in = !fui.in\n\t\treturn f\n\t}\n\t// tag not found, try root\n\n\tif (f.lst?.length == 1 && f.lst[0].type == 'tvs' && typeof f.lst[0].tvs == 'object') {\n\t\t// is a tvslst containing a single tvs. negate at tvs level\n\t\tf.lst[0].tvs.isnot = !f.lst[0].tvs.isnot\n\t\treturn f\n\t}\n\tif (f.lst?.length > 1 && typeof f.in == 'boolean') {\n\t\t// is a tvslst with multiple tvs. maybe from a subfilter nested somewhere\n\t\tf.in = !f.in\n\t\treturn f\n\t}\n\tthrow 'cannot negate filter'\n}\n\nexport function getCombinedTermFilter(appState, filter) {\n\tif (!filter) return appState.termfilter\n\tlet _filter = filter\n\tif (appState.termfilter.filter) _filter = filterJoin([appState.termfilter.filter, filter])\n\treturn { filter: _filter, filter0: appState.termfilter.filter0 }\n}\n\n/*\nThis function is used where ever you need to build a group of categorical filters related.\n It builds the filter needed to retrieve a term values after filtering out samples according to the other filters provided.\n The profile filters, for example, use this function to get the filters needed to call filterTermValues, that populate the dropdowns in the controls.\n If no tw is provided it returns a filter that is the combination of all the categorical filters provided in the filterTWs array.\n Input:\n - filterTWs: list of term wrappers (tw) that are used to filter the samples\n - values: an object with term ids as keys and the values to filter by\n - excludedTw: The term wrapper for which the filter is being built. If provided, it will be excluded from the filter.\n Output:\n - a filter object that can be used to filter term values based on the provided term wrappers and values.\n\nNOTE: Consumer code should submit the global filter in the request payload, so that the server code\n can combine it with each of the generated filter here.\n*/\nexport function getCategoricalTermFilter(filterTWs, values, excludedTw) {\n\tconst lst = []\n\tfor (const tw of filterTWs) {\n\t\tif (excludedTw && tw.id === excludedTw.id) continue\n\t\tprocessTW(tw, values, lst)\n\t}\n\t// returning null to represent empty filter value since\n\t// - tvslst filter bloats the payload and clutters the server log\n\t// - undefined value would be left out during JSON-encoding of an object-as-data\n\treturn {\n\t\ttype: 'tvslst',\n\t\tin: true,\n\t\tjoin: lst.length > 1 ? 'and' : '',\n\t\tlst\n\t}\n}\n\nfunction processTW(tw, values, lst) {\n\tconst value = values[tw.term.id]\n\tif (value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tconst tvs = {\n\t\t\t\ttype: 'tvs',\n\t\t\t\ttvs: {\n\t\t\t\t\tterm: tw.term,\n\t\t\t\t\tvalues: []\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const item of value) if (item) tvs.tvs.values.push({ key: item })\n\t\t\tif (tvs.tvs.values.length) lst.push(tvs)\n\t\t} else\n\t\t\tlst.push({\n\t\t\t\ttype: 'tvs',\n\t\t\t\ttvs: {\n\t\t\t\t\tterm: tw.term,\n\t\t\t\t\tvalues: [{ key: value }]\n\t\t\t\t}\n\t\t\t})\n\t}\n}\n", "import { select } from 'd3-selection'\nimport { TVSInit } from './tvs'\nimport { findItem } from './filter.utils'\n\n// will assign an incremented index to each filter UI instance\n// to help namespace the body.on('click') event handler;\n// other click handlers are specific to the rendered\n// elements within instance.dom.holder, so no need for this index\nlet filterIndex = 0\n\nexport function setRenderers(self) {\n\tself.initUI = async function () {\n\t\tif (self.opts.newBtn) {\n\t\t\tself.opts.newBtn.on('click.filter', self.displayTreeNew)\n\t\t} else {\n\t\t\tself.dom.newBtn = self.dom.holder\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_new_filter_btn sja_menuoption')\n\t\t\t\t.attr('data-testid', 'sjpp-new-filter-btn')\n\t\t\t\t.html(self.opts.emptyLabel)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.on('click', self.displayTreeNew)\n\t\t}\n\n\t\tself.dom.filterContainer = self.dom.holder.append('div').attr('class', 'sja_filter_container')\n\n\t\tself.dom.holder\n\t\t\t.selectAll('.sja_filter_add_transformer')\n\t\t\t.data(self.opts.joinWith)\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_filter_add_transformer')\n\t\t\t.style('display', d => (self.filter && self.filter.join != d ? 'inline-block' : 'none'))\n\t\t\t.style('margin-left', '10px')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('border-radius', '5px')\n\t\t\t//.style('background-color', '#ececec')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.html(d => '+' + d.toUpperCase())\n\t\t\t.on('click', self.displayTreeNew)\n\n\t\tself.dom.table = self.dom.controlsTip.clear().d.append('table').style('border-collapse', 'collapse')\n\n\t\tconst menuOptions = [\n\t\t\t{ action: 'edit', html: ['', 'Edit', '›'], handler: self.editTerm },\n\t\t\t{ action: 'join', html: ['✚', '', '›'], handler: self.displayTreeMenu },\n\t\t\t{ action: 'switch', html: ['', 'Switch to', ''], handler: self.switchJoin },\n\t\t\t{ action: 'negate', html: ['', 'Negate', ''], handler: self.negateClause },\n\t\t\t{ action: 'remove', html: ['✖', 'Remove', ''], handler: self.removeTransform }\n\t\t]\n\n\t\t// option to add a Replace option in the second row\n\t\tif (self.opts.vocab) {\n\t\t\tmenuOptions.splice(1, 0, {\n\t\t\t\taction: 'replace',\n\t\t\t\thtml: ['', 'Replace', '›'],\n\t\t\t\thandler: self.displayTreeMenu\n\t\t\t})\n\t\t}\n\n\t\tself.dom.table\n\t\t\t.selectAll('tr')\n\t\t\t.data(menuOptions)\n\t\t\t.enter()\n\t\t\t.append('tr')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('data-testid', d => `sjpp-menu-option-${d.action}`)\n\t\t\t.on('click', self.handleMenuOptionClick)\n\t\t\t.selectAll('td')\n\t\t\t.data(d => d.html)\n\t\t\t.enter()\n\t\t\t.append('td')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('border-top', 'solid 1px white')\n\t\t\t.style('color', (d, i) => (d == '✖' ? '#a00' : i === 0 ? '#0a0' : '#111'))\n\t\t\t.style('opacity', (d, i) => (i === 0 ? 0.8 : 1))\n\t\t\t.html(d => d)\n\n\t\tself.dom.treeHead = self.dom.treeTip.d.append('div').attr('class', 'sja_tree_tip_head').style('padding', '3px')\n\t\tself.dom.termSrcDiv = self.dom.treeTip.d.append('div').attr('class', 'sja_term_src_body')\n\n\t\tself.dom.treeHeadTitle = self.dom.treeHead.append('div')\n\n\t\tselect('body').on('mousedown.sja_filter_' + filterIndex++, event => {\n\t\t\tif (\n\t\t\t\t[\n\t\t\t\t\t'sja_filter_join_label',\n\t\t\t\t\t'sja_filter_clause_negate',\n\t\t\t\t\t'sja_filter_paren_open',\n\t\t\t\t\t'sja_filter_paren_close'\n\t\t\t\t].includes(event.target.className)\n\t\t\t)\n\t\t\t\treturn\n\t\t\tself.dom.filterContainer?.selectAll('.sja_filter_grp').style('background-color', 'transparent')\n\t\t\tself.removeBlankPill()\n\t\t\tthis.dom.holder?.selectAll('.sja_filter_add_transformer').style('display', this.getAddTransformerBtnDisplay)\n\t\t})\n\t}\n\n\tself.updateUI = async function (container, filter) {\n\t\tcontainer.datum(filter).style('display', !filter.lst || !filter.lst.length ? 'none' : 'inline-block')\n\t\tconst pills = container\n\t\t\t.selectAll(':scope > .sja_filter_grp')\n\t\t\t.style('background-color', 'transparent')\n\t\t\t.data([filter], self.getId)\n\n\t\tpills.exit().each(self.removeGrp)\n\t\tpills.each(self.updateGrp)\n\t\tpills.enter().append('div').attr('class', 'sja_filter_grp').style('margin', '5px').each(self.addGrp)\n\n\t\tself.updatePromise(0)\n\t}\n\n\tself.addGrp = function (item, i) {\n\t\tconst filter = this.parentNode.__data__\n\n\t\tselect(this).style('display', 'inline-block')\n\n\t\tselect(this)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_filter_clause_negate')\n\t\t\t.style('display', filter.in ? 'none' : 'inline-block')\n\t\t\t.style('color', 'rgb(102,0,0)')\n\t\t\t.style('font-weight', 500)\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.html('NOT')\n\t\t\t.on('click', self.displayControlsMenu)\n\n\t\tselect(this)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_filter_paren_open')\n\t\t\t.html('(')\n\t\t\t.style('display', 'none')\n\t\t\t.style('padding', '0 5px')\n\t\t\t.style('font-weight', 500)\n\t\t\t.style('font-size', '24px')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.on('click', self.displayControlsMenu)\n\n\t\tconst data = item.type == 'tvslst' ? item.lst : [item]\n\t\tconst pills = select(this).selectAll(':scope > .sja_filter_item').data(data, self.getId)\n\t\tpills.enter().append('div').attr('class', 'sja_filter_item').each(self.addItem)\n\n\t\tif (self.opts.joinWith.length == 1) {\n\t\t\tself.dom.last_join_div = select(this)\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_filter_last_join')\n\t\t\t\t.style('display', 'inline')\n\t\t\tself.dom.last_join_label = self.dom.last_join_div\n\t\t\t\t.append('div')\n\t\t\t\t.datum({ action: 'join', html: ['✚', '', '›'], handler: self.displayTreeMenu })\n\t\t\t\t.attr('class', 'sja_filter_last_join_label')\n\t\t\t\t.style('padding', '0 5px')\n\t\t\t\t.style('display', filter.lst.length ? 'inline' : 'none')\n\t\t\t\t.style('font-weight', 500)\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.html('+' + self.opts.joinWith[0].toUpperCase())\n\t\t\t\t.on('click', self.showLastJoinBlank)\n\n\t\t\tselect('body').on('mousedown.sja_filter_last_join', () => {\n\t\t\t\tself.dom.last_join_label.style('display', 'inline')\n\t\t\t})\n\t\t}\n\t\tselect(this)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_filter_paren_close')\n\t\t\t.style('padding', '0 5px')\n\t\t\t.html(')')\n\t\t\t.style('display', 'none')\n\t\t\t.style('font-weight', 500)\n\t\t\t.style('font-size', '24px')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.on('click', self.displayControlsMenu)\n\n\t\tselect(this)\n\t\t\t.selectAll(':scope > .sja_filter_paren_open, :scope > .sja_filter_paren_close')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length < 2 || data.length < 2\n\t\t\t\t\t? 'none'\n\t\t\t\t\t: !filter.in || (data.length > 1 && filter.tag != 'filterUiRoot')\n\t\t\t\t\t? 'inline-block'\n\t\t\t\t\t: 'none'\n\t\t\t)\n\t}\n\n\tself.updateGrp = function (item, i) {\n\t\tconst filter = this.parentNode.__data__\n\n\t\tselect(this)\n\t\t\t.select(':scope > .sja_filter_clause_negate')\n\t\t\t.style('display', filter.in ? 'none' : 'inline-block')\n\n\t\tconst data = item.type == 'tvslst' ? item.lst : [item]\n\n\t\tselect(this)\n\t\t\t.selectAll(':scope > .sja_filter_paren_open, :scope > .sja_filter_paren_close')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length < 2 || data.length < 2\n\t\t\t\t\t? 'none'\n\t\t\t\t\t: !filter.in || (data.length > 1 && filter.tag != 'filterUiRoot')\n\t\t\t\t\t? 'inline-block'\n\t\t\t\t\t: 'none'\n\t\t\t)\n\n\t\tconst pills = select(this).selectAll(':scope > .sja_filter_item').data(data, self.getId)\n\n\t\tpills.exit().each(self.removeItem)\n\t\tpills.each(self.updateItem)\n\t\tpills.enter().insert('div', ':scope > .sja_filter_paren_close').attr('class', 'sja_filter_item').each(self.addItem)\n\n\t\tselect(this)\n\t\t\t.selectAll(':scope > .sja_filter_item')\n\t\t\t.sort((a, b) => data.indexOf(a) - data.indexOf(b))\n\n\t\tif (self.dom.last_join_label) {\n\t\t\tself.dom.last_join_div.datum(filter)\n\t\t\tthis.insertBefore(self.dom.last_join_div.node(), select(this).select(':scope > .sja_filter_paren_close').node())\n\t\t\tself.dom.last_join_label.style('display', 'inline')\n\t\t}\n\t}\n\n\tself.removeGrp = function (item) {\n\t\tself.numExpectedItems += 1\n\t\tif (item.type == 'tvslst') {\n\t\t\tfor (const subitem of item.lst) {\n\t\t\t\tif (subitem.lst) self.removeGrp(subitem)\n\t\t\t\telse {\n\t\t\t\t\tdelete self.pills[subitem.$id]\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tdelete self.pills[item.$id]\n\t\t}\n\t\tif (this instanceof Node) {\n\t\t\tselect(this).selectAll('*').on('click', null)\n\t\t\tselect(this).on('click', null).remove()\n\t\t}\n\t\tself.updatePromise()\n\t}\n\n\tself.addItem = async function (item, i) {\n\t\tconst filter = this.parentNode.__data__\n\n\t\tif (item.type == 'tvslst') {\n\t\t\tself.updateUI(select(this), item)\n\t\t\tself.addJoinLabel(this, filter, item)\n\t\t\treturn\n\t\t}\n\n\t\tself.numExpectedItems += 1\n\n\t\t// holder for blue pill\n\t\tconst holder = select(this)\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('position', 'relative')\n\t\t\t.style('white-space', 'nowrap')\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_pill_wrapper')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('margin', self.opts.joinWith.length > 1 ? '' : '2px')\n\t\t\t.on('click', item.renderAs === 'htmlSelect' ? null : self.displayControlsMenu)\n\n\t\tself.addJoinLabel(this, filter, item)\n\t\tif (item.renderAs == 'htmlSelect') {\n\t\t\tconst values = getValuesForHtmlSelect(self, item)\n\t\t\tconst selectElem = holder.append('select').on('change', function () {\n\t\t\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\t\t\tconst filterCopy = findItem(filterUiRoot, filter.$id)\n\t\t\t\tconst i = filter.lst.indexOf(item)\n\t\t\t\tif (i == -1) return\n\t\t\t\tconst index = +this.value\n\t\t\t\tconst itemCopy = JSON.parse(JSON.stringify(item))\n\t\t\t\tconst keys = 'keys' in values[index] ? values[index].keys : [values[index].key]\n\t\t\t\titemCopy.tvs.values = keys.map(key => {\n\t\t\t\t\treturn { key, label: key } //may be missing list if term type is samplelst\n\t\t\t\t})\n\t\t\t\tfilterCopy.lst[i] = itemCopy\n\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t})\n\n\t\t\tconst defaultVal = getDefaultValueForHtmlSelect(self, item)\n\t\t\tselectElem\n\t\t\t\t.selectAll('option')\n\t\t\t\t.data(values)\n\t\t\t\t.enter()\n\t\t\t\t.append('option')\n\t\t\t\t.property('value', (d, i) => i)\n\t\t\t\t.property('selected', (d, i) => i == defaultVal)\n\t\t\t\t.html(d => (d.shortLabel ? d.shortLabel : d.label ? d.label : d.key))\n\t\t} else {\n\t\t\tconst pill = await TVSInit({\n\t\t\t\tvocabApi: self.vocabApi,\n\t\t\t\tholder,\n\t\t\t\tdebug: self.opts.debug,\n\t\t\t\tgetCategoriesArguments: self.opts.getCategoriesArguments,\n\t\t\t\tisMafFilter: self.opts.isMafFilter,\n\t\t\t\tcallback: tvs => {\n\t\t\t\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\t\t\t\tconst filterCopy = findItem(filterUiRoot, filter.$id)\n\t\t\t\t\tconst i = filter.lst.indexOf(item)\n\t\t\t\t\tif (i == -1) return\n\t\t\t\t\t// if tvs already present in the filterCopy just replace it rather than adding new one\n\t\t\t\t\tconst item_i = filterCopy.lst.findIndex(t => t.$id == item.$id)\n\t\t\t\t\tif (item_i == -1) filterCopy.lst[i] = { $id: item.$id, type: 'tvs', tvs }\n\t\t\t\t\telse filterCopy.lst[item_i].tvs = tvs\n\t\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t\t}\n\t\t\t})\n\t\t\tself.pills[item.$id] = pill\n\t\t\tawait pill.main({ tvs: item.tvs, filter: self.getFilterExcludingPill(item.$id) })\n\t\t}\n\t\tself.updatePromise()\n\t}\n\n\tself.updateItem = async function (item, i) {\n\t\tconst filter = this.parentNode.__data__\n\t\tselect(this)\n\t\t\t.select(':scope > .sja_filter_join_label')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length > 1 && filter.lst.indexOf(item) < filter.lst.length - 1 ? 'inline-block' : 'none'\n\t\t\t)\n\t\t\t.style('margin', self.opts.joinWith.length > 1 ? '' : '2px')\n\t\t\t.html(filter.join == 'and' ? 'AND' : 'OR')\n\n\t\tif (item.type == 'tvslst') {\n\t\t\tself.updateUI(select(this), item)\n\t\t} else if (item.renderAs === 'htmlSelect') {\n\t\t\tself.numExpectedItems += 1\n\t\t\tselect(this)\n\t\t\t\t.select('select')\n\t\t\t\t.property('value', '' + getDefaultValueForHtmlSelect(self, item))\n\t\t} else {\n\t\t\tif (!self.pills[item.$id]) return\n\t\t\tself.numExpectedItems += 1\n\t\t\tawait self.pills[item.$id].main({ tvs: item.tvs, filter: self.getFilterExcludingPill(item.$id) })\n\t\t}\n\t\tself.updatePromise()\n\t}\n\n\tself.removeItem = function (item) {\n\t\tdelete self.pills[item.$id]\n\t\tselect(this).on('click', null).remove()\n\t}\n\n\tself.addJoinLabel = function (elem, filter, item) {\n\t\tconst i = filter.lst.findIndex(d => d.$id === item.$id)\n\t\tselect(elem)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_filter_join_label')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length > 1 && filter.lst.length > 1 && item && i != -1 && i < filter.lst.length - 1\n\t\t\t\t\t? 'inline-block'\n\t\t\t\t\t: 'none'\n\t\t\t)\n\t\t\t.style('width', '50px')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('border', 'none')\n\t\t\t.style('border-radius', '5px')\n\t\t\t.style('text-align', 'center')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.html(filter.lst.length < 2 ? '' : filter.join == 'and' ? 'AND' : 'OR')\n\t\t\t.on('click', self.displayControlsMenu)\n\t}\n\n\tself.updateJoinLabel = function (item) {\n\t\tconst filter = this.parentNode.parentNode.parentNode.__data__\n\t\tconst i = filter.lst.findIndex(d => d.$id === item.$id)\n\t\tselect(this).style(\n\t\t\t'display',\n\t\t\tself.opts.joinWith.length > 1 && filter.lst.length > 1 && item && i != -1 && i < filter.lst.length - 1\n\t\t\t\t? 'inline-block'\n\t\t\t\t: 'none'\n\t\t)\n\t}\n\n\tself.getAddTransformerBtnDisplay = function (d) {\n\t\tif (self.opts.joinWith.length < 2) {\n\t\t\treturn 'none'\n\t\t} else if (self.filter && self.filter.lst.find(f => f.tag === 'cohortFilter')) {\n\t\t\t// assume that a cohortFilter is always joined via intersection with other filters\n\t\t\treturn self.filter.lst.length == 1 && d == 'and' ? 'inline-block' : 'none'\n\t\t} else {\n\t\t\treturn self.filter && self.filter.lst.length > 0 && (self.filter.join !== d || !self.filter.in)\n\t\t\t\t? 'inline-block'\n\t\t\t\t: 'none'\n\t\t}\n\t}\n}\n\nfunction getValuesForHtmlSelect(self, item) {\n\treturn item.selectOptionsFrom == 'selectCohort'\n\t\t? self.opts.termdbConfig.selectCohort.values\n\t\t: Array.isArray(item.tvs.term.values)\n\t\t? item.tvs.term.values\n\t\t: Object.values(item.tvs.term.values)\n}\n\nfunction getDefaultValueForHtmlSelect(self, item) {\n\tconst values = getValuesForHtmlSelect(self, item)\n\tconst defaultKey = JSON.stringify(item.tvs.values.map(o => o.key).sort())\n\tconst i = values.findIndex(d => (d.keys ? defaultKey === JSON.stringify(d.keys.sort()) : d.key === defaultKey))\n\treturn i\n}\n", "import { select } from 'd3-selection'\nimport { findItem, findParent, getWrappedTvslst, filterJoin } from './filter.utils'\n\nconst MENU_OPTION_HIGHLIGHT_COLOR = '#fff'\n\nexport function setInteractivity(self) {\n\tself.displayControlsMenu = function (event) {\n\t\tevent.stopPropagation() // in mass/group ui, to prevent pill-clicking to check/uncheck table rows\n\n\t\tif (!self.activeData) return\n\t\tconst item = this.parentNode.__data__\n\t\tconst filter = findParent(self.filter, item.$id)\n\t\tself.activeData = { item, filter, elem: this }\n\t\tself.removeBlankPill()\n\t\tself.resetGrpHighlights(this, filter)\n\n\t\t// disabled for now as it breaks CI\n\t\tif (item.noEdit)\n\t\t\tself.dom.table\n\t\t\t\t.selectAll('tr')\n\t\t\t\t.filter(d => d.action == 'edit')\n\t\t\t\t.style('display', 'none')\n\n\t\tself.dom.controlsTip.showunder(this)\n\t}\n\n\tself.resetGrpHighlights = function (elem, filter) {\n\t\tconst cls = elem.className\n\t\tconst grpAction = cls.includes('join') || cls.includes('negate') || cls.includes('paren')\n\t\tconst menuRows = self.dom.controlsTip.d.selectAll('tr').style('background-color', '')\n\t\tmenuRows.filter(d => d.action == 'edit' || d.action == 'replace').style('display', grpAction ? 'none' : 'table-row')\n\t\tmenuRows\n\t\t\t.filter(d => /*d.action == 'negate' ||*/ d.action == 'remove')\n\t\t\t.style('display', cls.includes('_join_') && filter.lst.find(d => d.tag == 'cohortFilter') ? 'none' : 'table-row')\n\n\t\tmenuRows\n\t\t\t.filter(d => d.action == 'join')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length < 2 ||\n\t\t\t\t\t(filter.$id == self.filter.$id && filter.lst.length == 1) ||\n\t\t\t\t\tcls.includes('negate') ||\n\t\t\t\t\tcls.includes('paren')\n\t\t\t\t\t? 'none'\n\t\t\t\t\t: 'table-row'\n\t\t\t)\n\t\t\t.select('td:nth-child(2)')\n\t\t\t.html(grpAction ? filter.join.toUpperCase() : filter.join == 'and' ? 'OR' : 'AND')\n\n\t\tmenuRows\n\t\t\t.filter(d => d.action == 'switch')\n\t\t\t.style(\n\t\t\t\t'display',\n\t\t\t\tself.opts.joinWith.length < 2 ||\n\t\t\t\t\t(filter.$id == self.filter.$id && filter.lst.length == 1) ||\n\t\t\t\t\t!cls.includes('_join_')\n\t\t\t\t\t? 'none'\n\t\t\t\t\t: 'table-row'\n\t\t\t)\n\t\t\t.select('td:nth-child(2)')\n\t\t\t.html(d => (filter.join == 'and' ? 'Switch to OR' : 'Switch to AND'))\n\n\t\tself.dom.filterContainer.selectAll('.sja_filter_grp').style('background-color', 'transparent')\n\t\tif (grpAction) {\n\t\t\tif (cls.includes('join')) elem.parentNode.parentNode.style.backgroundColor = '#ee5'\n\t\t\telse elem.parentNode.style.backgroundColor = '#ee5'\n\t\t}\n\t}\n\n\tself.handleMenuOptionClick = async function (event, d) {\n\t\tevent.stopPropagation()\n\t\tif (d == self.activeData.menuOpt) return\n\t\tself.activeData.menuOpt = d\n\t\tif (self.activeData.elem.className.includes('join') && d.action !== 'join' && d.action != 'switch') {\n\t\t\tself.activeData.item = self.activeData.filter\n\t\t\tself.activeData.filter = findParent(self.filter, self.activeData.item)\n\t\t}\n\t\tself.resetBlankPill(d.action)\n\t\tself.dom.controlsTip.d.selectAll('tr').style('background-color', '')\n\t\tawait d.handler(this, d)\n\t}\n\n\tself.resetBlankPill = function (action) {\n\t\t// clear any currently highlighted blank pill/parenthesis\n\t\tself.removeBlankPill()\n\t\tself.dom.filterContainer.selectAll('.sja_filter_grp').style('background-color', 'transparent')\n\t\tif (action != 'join') return\n\t\tconst elem = self.dom.last_join_div\n\t\t\t? self.dom.last_join_div.node()\n\t\t\t: self.activeData.elem.className.includes('join_label')\n\t\t\t? self.activeData.elem.parentNode.parentNode\n\t\t\t: self.activeData.item.type == 'tvs' || self.activeData.filter === self.filter\n\t\t\t? self.activeData.elem\n\t\t\t: self.activeData.elem.parentNode.parentNode\n\t\tconst joiner =\n\t\t\tself.opts.joinWith.length === 1\n\t\t\t\t? self.opts.joinWith[0].toUpperCase()\n\t\t\t\t: self.activeData.elem.className.includes('join_label')\n\t\t\t\t? self.activeData.filter.join.toUpperCase()\n\t\t\t\t: self.activeData.btn && typeof self.activeData.btn.__data__ === 'string'\n\t\t\t\t? self.activeData.btn.__data__.toUpperCase()\n\t\t\t\t: self.activeData.item.type == 'tvslst'\n\t\t\t\t? self.activeData.filter.join.toUpperCase()\n\t\t\t\t: self.activeData.filter.join == 'or'\n\t\t\t\t? 'AND'\n\t\t\t\t: 'OR'\n\n\t\tif (\n\t\t\tself.activeData.item.type == 'tvs' &&\n\t\t\t//&& self.activeData.filter != self.filter\n\t\t\t!self.activeData.elem.className.includes('join_label')\n\t\t) {\n\t\t\tselect(elem)\n\t\t\t\t.insert('div', 'div')\n\t\t\t\t.attr('class', 'sja_filter_paren_open')\n\t\t\t\t.style('display', self.opts.joinWith.length > 1 ? 'inline-block' : 'none')\n\t\t\t\t.style('padding', '0 5px')\n\t\t\t\t.style('font-weight', 500)\n\t\t\t\t.style('font-size', '24px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.html('(')\n\t\t}\n\n\t\tconst blank = select(elem)\n\t\t\t.insert('div', ':scope > .sja_filter_paren_close')\n\t\t\t.attr('class', 'sja_filter_blank_pill')\n\t\t\t.style('display', 'inline-block')\n\t\t\t//.style('width', '120px')\n\t\t\t.style('height', '20px')\n\t\t\t//.style('margin-right', '20px')\n\t\t\t.style('overflow', 'visible')\n\n\t\tblank\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('width', '50px')\n\t\t\t.style('text-align', 'center')\n\t\t\t.html(joiner)\n\n\t\tblank\n\t\t\t.append('div')\n\t\t\t.style('position', 'relative')\n\t\t\t.style('top', '-7px')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('width', '80px')\n\t\t\t.style('height', '22px')\n\t\t\t.style('margin-right', '5px')\n\t\t\t.style('border', '3px dashed #b8d3ea')\n\t\t\t.style('vertical-align', 'top')\n\t\t\t.style('background-color', '#ee5')\n\n\t\tif (\n\t\t\tself.activeData.item.type == 'tvs' &&\n\t\t\t//&& self.activeData.filter != self.filter\n\t\t\t!self.activeData.elem.className.includes('join_label')\n\t\t) {\n\t\t\tselect(elem)\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_filter_paren_close')\n\t\t\t\t.style('display', self.opts.joinWith.length > 1 ? 'inline-block' : 'none')\n\t\t\t\t.style('padding', '0 5px')\n\t\t\t\t.style('font-weight', 500)\n\t\t\t\t.style('font-size', '24px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.html(')')\n\t\t}\n\n\t\tif (elem == self.dom.filterContainer.node()) {\n\t\t\tself.dom.filterContainer\n\t\t\t\t.selectAll(\n\t\t\t\t\t':scope > .sja_filter_grp > .sja_filter_paren_open, :scope > .sja_filter_grp > .sja_filter_paren_close'\n\t\t\t\t)\n\t\t\t\t.style('display', self.opts.joinWith.length > 1 && self.filter.lst.length > 1 ? 'inline-block' : 'none')\n\t\t}\n\t}\n\n\tself.removeBlankPill = function () {\n\t\tself.dom.holder\n\t\t\t?.selectAll(\n\t\t\t\t'.sja_filter_blank_pill, .sja_pill_wrapper > .sja_filter_paren_open, .sja_pill_wrapper > .sja_filter_paren_close'\n\t\t\t)\n\t\t\t.remove()\n\n\t\t// in case of potentially root filter subnesting, may have to\n\t\t// revert the visibility of root filter group parentheses\n\t\t// that subnest existing pill + blank pill\n\t\tif (self.filter.in && self.filter.lst.filter(f => f.type === 'tvslst').length < 1) {\n\t\t\tself.dom.filterContainer\n\t\t\t\t?.selectAll(\n\t\t\t\t\t':scope > .sja_filter_grp > .sja_filter_paren_open, :scope > .sja_filter_grp > .sja_filter_paren_close'\n\t\t\t\t)\n\t\t\t\t.style('display', 'none')\n\t\t}\n\t}\n\n\t// menu to add a new term\n\tself.displayTreeNew = async function (event, d) {\n\t\tevent.stopPropagation() // in mass/group ui, to prevent pill-clicking to check/uncheck table rows\n\n\t\tif (self.opts.newBtn && this.className !== 'sja_filter_add_transformer' && self.filter.lst.length) return\n\t\tself.dom.filterContainer.selectAll('.sja_filter_grp').style('background-color', 'transparent')\n\t\tif (self.filter.lst.length > 0) {\n\t\t\tself.activeData = {\n\t\t\t\titem: self.filter,\n\t\t\t\tfilter: self.filter,\n\t\t\t\telem: self.dom.filterContainer.node(), //.select(':scope > .sja_filter_grp').node()\n\t\t\t\tbtn: this\n\t\t\t}\n\t\t}\n\t\tif (self.filter.lst.length) self.resetBlankPill('join')\n\t\tconst blankPill = self.dom.filterContainer.select('.sja_filter_blank_pill').node()\n\t\tif (blankPill) {\n\t\t\tself.dom.holder.selectAll('.sja_filter_add_transformer').style('display', 'none')\n\t\t\tself.dom.treeTip.clear().showunder(blankPill)\n\t\t} else {\n\t\t\tself.dom.treeTip.clear().showunder(this)\n\t\t}\n\n\t\tconst treeFilter = self.getTreeFilter(d)\n\t\tconst termdb = await import('../termdb/app')\n\n\t\ttermdb.appInit({\n\t\t\tvocabApi: self.vocabApi,\n\t\t\tholder: self.dom.termSrcDiv,\n\t\t\tgetCategoriesArguments: self.opts.getCategoriesArguments,\n\t\t\tisMafFilter: self.opts.isMafFilter,\n\t\t\tstate: {\n\t\t\t\tactiveCohort: self.activeCohort,\n\t\t\t\ttermfilter: { filter: treeFilter },\n\t\t\t\ttree: { usecase: { target: 'filter' } },\n\t\t\t\tnav: { header_mode: self.opts.header_mode }\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tdisable_terms:\n\t\t\t\t\tself.activeData && self.activeData.filter && self.activeData.filter.lst && d == 'and'\n\t\t\t\t\t\t? self.activeData.filter.lst\n\t\t\t\t\t\t\t\t.filter(d => d.type === 'tvs' && d.tvs.term.type !== 'condition')\n\t\t\t\t\t\t\t\t.map(d => d.tvs.term)\n\t\t\t\t\t\t: [],\n\n\t\t\t\tclick_term2select_tvs(tvs) {\n\t\t\t\t\tself.editFilterRoot(d, [{ type: 'tvs', tvs }])\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\t// join='and' | 'or'\n\tself.getTreeFilter = (join, filter) => {\n\t\tconst filterCopy = filter\n\t\t\t? filter\n\t\t\t: self.activeData\n\t\t\t? self.getAdjustedRoot(self.activeData.filter.$id, join)\n\t\t\t: JSON.parse(self.rawCopy)\n\n\t\tif (filterCopy.lst.length < 2) filterCopy.join = ''\n\n\t\tconst globalFilter = self.opts?.app?.getState()?.termfilter?.filter\n\t\treturn globalFilter && join != 'or' ? filterJoin([filterCopy, globalFilter]) : filterCopy\n\t}\n\n\t/*\n\t\tArguments: \n\t\td: the data bound to a button element like +New, AND, OR\n\t\ttvslst\n\t*/\n\tself.editFilterRoot = (d, tvslst) => {\n\t\t// NOTE: default to 'tvs' argument once bar_click_override is unsupported\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\n\t\tif (!filterUiRoot.lst.length) {\n\t\t\tif (tvslst.length > 1) filterUiRoot.join = 'and'\n\t\t\tfilterUiRoot.lst.push(...tvslst)\n\t\t\tself.refresh(filterUiRoot)\n\t\t} else if (d != 'or' && d != 'and') {\n\t\t\tthrow 'unhandled new term(s): invalid appender join value'\n\t\t} else {\n\t\t\tif (!filterUiRoot.join) filterUiRoot.join = d // 'and' || 'or'\n\n\t\t\tif (filterUiRoot.join == d && filterUiRoot.in) {\n\t\t\t\tif (tvslst.length < 2 || filterUiRoot.join == 'and') {\n\t\t\t\t\tfilterUiRoot.lst.push(...tvslst)\n\t\t\t\t} else {\n\t\t\t\t\tfilterUiRoot.push({\n\t\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\t\tin: true,\n\t\t\t\t\t\tjoin: 'and',\n\t\t\t\t\t\tlst: tvslst\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t} else if (d == 'and' || tvslst.length < 2) {\n\t\t\t\tdelete filterUiRoot.tag\n\t\t\t\tself.refresh({\n\t\t\t\t\ttag: 'filterUiRoot',\n\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\tin: true,\n\t\t\t\t\tjoin: d,\n\t\t\t\t\tlst: [filterUiRoot, ...tvslst]\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tdelete filterUiRoot.tag\n\t\t\t\tself.refresh({\n\t\t\t\t\ttag: 'filterUiRoot',\n\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\tin: true,\n\t\t\t\t\tjoin: 'or',\n\t\t\t\t\tlst: [\n\t\t\t\t\t\tfilterUiRoot,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\t\t\tin: true,\n\t\t\t\t\t\t\tjoin: 'and',\n\t\t\t\t\t\t\tlst: tvslst\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// menu to replace a term or add a subnested filter\n\t// elem: the clicked menu row option\n\t// d: elem.__data__\n\tself.displayTreeMenu = async function (elem, d) {\n\t\tselect(elem).style('background-color', MENU_OPTION_HIGHLIGHT_COLOR)\n\t\tself.dom.holder.selectAll('.sja_filter_add_transformer').style('display', 'none')\n\t\tconst blankPill = self.dom.filterContainer.select('.sja_filter_blank_pill').node()\n\t\tif (blankPill) {\n\t\t\tself.dom.controlsTip.hide()\n\t\t\tself.dom.treeTip.clear().showunder(blankPill)\n\t\t} else if (elem.lastChild instanceof HTMLElement) {\n\t\t\tself.dom.treeTip.clear().showunderoffset(elem.lastChild)\n\t\t} else {\n\t\t\tself.dom.treeTip.clear().showunder(elem)\n\t\t}\n\t\tconst filter = self.getTreeFilter(d, self.activeData.filter)\n\n\t\tconst termdb = await import('../termdb/app')\n\t\ttermdb.appInit({\n\t\t\tvocabApi: self.vocabApi,\n\t\t\tholder: self.dom.termSrcDiv,\n\t\t\tgetCategoriesArguments: self.opts.getCategoriesArguments,\n\t\t\tisMafFilter: self.opts.isMafFilter,\n\t\t\tstate: {\n\t\t\t\tactiveCohort: self.activeCohort,\n\t\t\t\tnav: { header_mode: self.opts.header_mode || 'search_only' },\n\t\t\t\ttermfilter: { filter: self.getAdjustedRoot(filter.$id, filter.join) },\n\t\t\t\ttree: { usecase: { target: 'filter' } }\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tdisable_terms:\n\t\t\t\t\tfilter && filter.lst && filter.join == 'and'\n\t\t\t\t\t\t? filter.lst.filter(d => d.type === 'tvs' && d.tvs.term.type !== 'condition').map(d => d.tvs.term)\n\t\t\t\t\t\t: !self.activeData.item\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: self.activeData.item.type == 'tvs'\n\t\t\t\t\t\t? [self.activeData.item.tvs.term]\n\t\t\t\t\t\t: self.activeData.item.lst\n\t\t\t\t\t\t? self.activeData.item.lst.filter(f => f.type == 'tvs').map(f => f.tvs.term)\n\t\t\t\t\t\t: [],\n\n\t\t\t\tclick_term2select_tvs:\n\t\t\t\t\td.action == 'replace'\n\t\t\t\t\t\t? self.replaceTerm\n\t\t\t\t\t\t: !filter.join ||\n\t\t\t\t\t\t !filter.lst.length ||\n\t\t\t\t\t\t (self.activeData.elem && self.activeData.elem.className.includes('join'))\n\t\t\t\t\t\t? self.appendTerm\n\t\t\t\t\t\t: self.subnestFilter\n\t\t\t}\n\t\t})\n\t}\n\n\tself.editTerm = function (elem) {\n\t\tselect(elem.parentNode).selectAll('tr').style('background-color', self.highlightEditRow)\n\t\tconst holder = self.dom.termSrcDiv\n\t\tconst item = self.activeData.item\n\t\tself.dom.treeTip.clear()\n\t\tself.pills[item.$id].showMenu(holder)\n\t\tself.dom.treeTip.showunderoffset(elem.lastChild)\n\t}\n\n\tself.highlightEditRow = function (d) {\n\t\treturn d.action == 'edit' ? MENU_OPTION_HIGHLIGHT_COLOR : ''\n\t}\n\n\tself.handleNotLabelClick = function (event, d) {\n\t\tself.activeData = {\n\t\t\titem: this.__data__\n\t\t}\n\t\tself.negateClause()\n\t}\n\n\tself.negateClause = function () {\n\t\t//const filter = self.activeData.filter\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst item = findItem(filterUiRoot, self.activeData.item.$id)\n\t\tif (item.type == 'tvslst') item.in = !item.in\n\t\telse if (item.type == 'tvs' && item.tvs?.term?.type == 'geneVariant') {\n\t\t\tconst modifiedGrp = item.tvs.values.filter(v => v.mclassExcludeLst.length > 0)[0]\n\t\t\tconst tmp = modifiedGrp.mclassLst\n\t\t\tmodifiedGrp.mclassLst = modifiedGrp.mclassExcludeLst\n\t\t\tmodifiedGrp.mclassExcludeLst = tmp\n\t\t\titem.tvs.isnot = !item.tvs.isnot\n\t\t} else item.tvs.isnot = !item.tvs.isnot\n\t\tself.refresh(filterUiRoot)\n\t}\n\n\tself.replaceTerm = _tvs_ => {\n\t\t// NOTE: default to type: 'tvs' argument once bar_click_override is unsupported\n\t\tconst tvslst = Array.isArray(_tvs_) ? _tvs_ : [{ type: 'tvs', tvs: _tvs_ }]\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst filterCopy = findItem(filterUiRoot, self.activeData.filter.$id)\n\t\tconst i = filterCopy.lst.findIndex(t => t.$id === self.activeData.item.$id)\n\t\t// FIXME: will replace with just one tvs, once bar_click_override is unsupported\n\t\tif (tvslst.length < 2 || filterCopy.join == 'and') {\n\t\t\tfilterCopy.lst.splice(i, 1, ...tvslst)\n\t\t} else {\n\t\t\tfilterCopy.lst[i] = {\n\t\t\t\t// transform from tvs to tvslst\n\t\t\t\tin: !_tvs_.isnot,\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tjoin: 'and',\n\t\t\t\tlst: tvslst\n\t\t\t}\n\t\t}\n\t\tself.refresh(filterUiRoot)\n\t}\n\n\tself.appendTerm = _tvs_ => {\n\t\t// FIXME: default to type: 'tvs' argument once bar_click_override is unsupported\n\t\tconst tvslst = Array.isArray(_tvs_) ? _tvs_ : [{ type: 'tvs', tvs: _tvs_ }]\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst filterCopy = findItem(filterUiRoot, self.activeData.filter.$id)\n\t\t// FIXME: will just push one tvs, once bar_click_override is unsupported\n\t\tif (tvslst.length < 2 || filterCopy.join == 'and') {\n\t\t\tfilterCopy.lst.push(...tvslst)\n\t\t\tif (filterCopy.join == '' && self.opts.joinWith.length === 1) filterCopy.join = self.opts.joinWith[0]\n\t\t} else {\n\t\t\tfilterCopy.lst.push({\n\t\t\t\t// transform from tvs to tvslst\n\t\t\t\tin: true,\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tjoin: 'and',\n\t\t\t\tlst: tvslst\n\t\t\t})\n\t\t}\n\t\tself.refresh(filterUiRoot)\n\t}\n\n\tself.subnestFilter = t => {\n\t\tlet tvslst\n\t\tif (Array.isArray(t)) {\n\t\t\ttvslst = t\n\t\t} else {\n\t\t\ttvslst = [{ type: 'tvs', tvs: t }]\n\t\t}\n\n\t\tconst item = self.activeData.item\n\t\tconst filter = self.activeData.filter\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst filterCopy = findItem(filterUiRoot, filter.$id)\n\t\tconst i = filterCopy.lst.findIndex(t => t.$id === item.$id)\n\t\t// transform from tvs to tvslst\n\t\tfilterCopy.lst[i] = {\n\t\t\tin: true,\n\t\t\ttype: 'tvslst',\n\t\t\tjoin: filter.join == 'or' ? 'and' : 'or',\n\t\t\tlst: [item, ...tvslst]\n\t\t}\n\t\tself.refresh(filterUiRoot)\n\t}\n\n\tself.removeTransform = function (elem, t) {\n\t\tconst item = t.action || typeof t !== 'object' ? self.activeData.item : findItem(self.filter, t.$id)\n\t\tconst filter = findParent(self.filter, item.$id) //self.activeData.filter\n\t\tif (item == filter) {\n\t\t\tself.refresh(getWrappedTvslst([], '', item.$id))\n\t\t\treturn\n\t\t}\n\t\tconst i = filter.lst.findIndex(t => t.$id === item.$id)\n\t\tif (i == -1) return\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst filterCopy = findItem(filterUiRoot, filter.$id)\n\t\tfilterCopy.lst.splice(i, 1)\n\t\tif (filterCopy.lst.length === 1) {\n\t\t\tconst parent = findParent(filterUiRoot, filterCopy.$id)\n\t\t\tif (filterCopy.lst[0].type == 'tvslst') {\n\t\t\t\tif (parent == filterUiRoot) {\n\t\t\t\t\tfilterCopy.lst[0].tag = 'filterUiRoot'\n\t\t\t\t\tself.refresh(filterCopy.lst[0])\n\t\t\t\t} else {\n\t\t\t\t\tconst j = parent.lst.findIndex(t => t.$id == filterCopy.$id)\n\t\t\t\t\tif (filterCopy.lst[0].join == parent.join) {\n\t\t\t\t\t\tparent.lst.splice(j, 1, ...filterCopy.lst[0].lst)\n\t\t\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparent.lst[j] = filterCopy.lst[0]\n\t\t\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfilterCopy.join = ''\n\t\t\t\tconst j = parent.lst.findIndex(t => t.$id === filterCopy.$id)\n\t\t\t\tparent.lst[j] = filterCopy.lst[0]\n\t\t\t\tif (!filterCopy.in) {\n\t\t\t\t\tparent.lst[j].tvs.isnot = !parent.lst[j].tvs.isnot\n\t\t\t\t\tif (parent == filterUiRoot) parent.in = true\n\t\t\t\t}\n\t\t\t\tself.refresh(filterUiRoot)\n\t\t\t}\n\t\t} else {\n\t\t\tself.refresh(filterUiRoot)\n\t\t}\n\t}\n\n\tself.showLastJoinBlank = function (event, d) {\n\t\tevent.stopPropagation()\n\t\tconst elem = self.dom.last_join_div.node()\n\t\tself.dom.last_join_label.style('display', 'none')\n\t\tconst filter = this.parentNode.__data__\n\t\tself.activeData = { item: filter, filter, elem }\n\t\tself.resetBlankPill(d.action)\n\t\tself.displayTreeMenu(elem, d)\n\t}\n\n\tself.switchJoin = function (event, d) {\n\t\tconst filterUiRoot = JSON.parse(JSON.stringify(self.filter))\n\t\tconst filterCopy = findItem(filterUiRoot, self.activeData.filter.$id)\n\t\tif (filterCopy.join < 2) return\n\t\tfilterCopy.join = filterCopy.join == 'and' ? 'or' : 'and'\n\t\tself.refresh(filterUiRoot)\n\t}\n}\n", "import { dofetch3, isInSession, getRequiredAuth, getSavedToken, setTokenByDsRoute } from '#common/dofetch'\nimport { isDictionaryType } from '#shared/terms.js'\n\nexport class Vocab {\n\ttermdbConfig = {}\n\n\tconstructor(opts) {\n\t\tthis.app = opts.app\n\t\tthis.opts = opts\n\t\tthis.state = opts.state\n\t\tthis.vocab = opts.state.vocab\n\t\tthis.currAnnoData = { samples: {}, refs: { byTermId: {} }, lastTerms: [], lastFilter: {} }\n\t\t/*\n some categorical terms may not have an initial term.values object,\n but is expected to be filled from data requests such as nestedChartSeriesData()\n TODO: \n - add values-filling logic to other data requests besides nestedChartSeriesData()\n - instead of this workaround, should query all available values in getterm()\n \t*/\n\t\tthis.missingCatValsByTermId = {}\n\t\tconst dslabel = this.vocab?.dslabel || this.state?.dslabel\n\n\t\t// Calling dofetch3() as a method of Vocab/TermdbVocab will allow\n\t\t// dofetch3() to have access to this.app.getAbortSignal(), to get an\n\t\t// AbortSignal if the dofetch3() 2nd argument doesn't set init.signal.\n\t\t// This signal can cancel any request due to a state change, such as\n\t\t// when the GDC cohort changes, thus aborting stale data requests that may\n\t\t// result in misleading rendered plots. This approach is more reliable than\n\t\t// requiring consumer code that use vocabApi methods to supply an\n\t\t// init.signal option, or for a vocabApi method to supply a default\n\t\t// init.signal.\n\t\tthis.dofetch3 = dofetch3\n\t}\n\n\tasync main(stateOverride = null) {\n\t\tif (stateOverride) Object.assign(this.state, stateOverride)\n\t\telse this.state = structuredClone(this.app?.getState?.() || this.opts.state)\n\n\t\t// frontend vocab may replace the vocab object reference\n\t\tif (this.state.vocab) this.vocab = this.state.vocab\n\t\t// may or may not need a verified token for a dslabel, based on genome response.dsAuth\n\t\tconst dslabel = this.state.dslabel || this.state.vocab.dslabel\n\t\tthis.verifiedToken = !this.state.termdbConfig?.requiredAuth?.length || (await isInSession(dslabel, 'termdb'))\n\t\t// secured plots need to confirm that a verified token exists\n\t\tif (dslabel) await this.maySetVerifiedToken(dslabel)\n\t}\n\n\tasync maySetVerifiedToken(dslabel) {\n\t\t// strict true boolean value means no auth required\n\t\tif (this.verifiedToken === true) return this.verifiedToken\n\t\tconst protectedRoute = 'termdb'\n\t\tconst auth =\n\t\t\tthis.state.termdbConfig?.requiredAuth.find(a => a.route == protectedRoute) ||\n\t\t\tgetRequiredAuth(dslabel, protectedRoute)\n\n\t\tif (!auth) {\n\t\t\tthis.verifiedToken = true\n\t\t\treturn\n\t\t}\n\n\t\tconst token = (await this.opts.getDatasetAccessToken?.(protectedRoute)) || getSavedToken(dslabel, protectedRoute)\n\t\tif (this.verifedToken && token === this.verifiedToken) return this.verifiedToken\n\n\t\ttry {\n\t\t\tif (!token && auth.type == 'jwt') {\n\t\t\t\tdelete this.verifiedToken\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// NOTE: if there is a saved token for a dataset/route, and the auth.type is not 'jwt',\n\t\t\t// then assume that the saved jwt was generated by the PP server after a password (basic) login,\n\t\t\t// so that the saved, stateless jwt can be reused across different PP server instances\n\t\t\t// with a clear expiration date\n\t\t\tif (auth.type == 'jwt' || (auth.type == 'basic' && !this.verifedToken && token)) {\n\t\t\t\tconst headers = {\n\t\t\t\t\t[auth.headerKey]: token\n\t\t\t\t}\n\t\t\t\t// TODO: do not hardcode 'termdb' here, assume that Vocab is only called within a termdb or mass app\n\t\t\t\tconst route = auth.route || 'termdb'\n\t\t\t\tif (!headers.authorization && token) headers.authorization = `Bearer ${btoa(token)}`\n\t\t\t\tconst data = await dofetch3('/jwt-status', {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders,\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tdslabel,\n\t\t\t\t\t\troute,\n\t\t\t\t\t\tembedder: location.hostname\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\t// TODO: later may check against expiration time in response if included\n\t\t\t\tthis.verifiedToken = data.status === 'ok' //&& token\n\t\t\t\tif (data.error) {\n\t\t\t\t\tthis.tokenVerificationPayload = data\n\t\t\t\t\tthrow data.error\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: remove the need for legacy support of hardcoded session names\n\t\t\t\t\tthis.sessionId =\n\t\t\t\t\t\t(auth.headerKey && data[auth.headerKey]) || data['x-sjppds-sessionid'] || data['x-ds-access-token']\n\t\t\t\t\tdelete this.tokenVerificationMessage\n\t\t\t\t\tdelete this.tokenVerificationPayload\n\t\t\t\t\tif (data.jwt) {\n\t\t\t\t\t\t// NOTE:\n\t\t\t\t\t\t// - must save token in localStorage, so that mayAddJwtToRequest()\n\t\t\t\t\t\t// in dofetch can add it as header.authorization: Bearer token,\n\t\t\t\t\t\t// which addresses unshared login/session state in a multi-server farm\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// - data.jwt is a more persistent, session-like token that\n\t\t\t\t\t\t// \"replaces\" the embedder's jwt, which may have a much more limited\n\t\t\t\t\t\t// expiration date or other concerns that prevents effective/performant\n\t\t\t\t\t\t// reuse, for example, we don't want a user to login every 5 minutes\n\t\t\t\t\t\t// if an embedder's jwt expires quickly\n\t\t\t\t\t\tsetTokenByDsRoute(dslabel, data.route, data.jwt)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (auth.route != '/**') {\n\t\t\t\t// for termdb routes, assume only jwt login is supported for\n\t\t\t\t// pre-specified routes, since mass app is public for most termdb routes,\n\t\t\t\t// whereas basic/password login has been coded to protect all routes\n\t\t\t\t// (nothing is shown except login form in landing page)\n\t\t\t\tthrow `unsupported requiredAuth='${auth.type}'`\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.tokenVerificationMessage = e.message || e.reason || e\n\t\t\t// may uncomment below to help troubleshoot auth errors\n\t\t\t// console.log(e)\n\t\t}\n\t}\n\n\thasVerifiedToken() {\n\t\t// should not return the string token value, only a boolean\n\t\treturn this.verifiedToken && true\n\t}\n\n\tasync mayGetAuthHeaders(route = '') {\n\t\tconst dslabel = this.state.vocab.dslabel\n\t\tconst auth = this.state.termdbConfig?.requiredAuth?.find(a => a.route == route) || getRequiredAuth(dslabel, route)\n\n\t\tif (!auth) return {}\n\t\tif (!this.verifiedToken) {\n\t\t\tif (await isInSession(dslabel, 'termdb')) {\n\t\t\t\tconst jwt = getSavedToken(this.state.vocab.dslabel, route)\n\t\t\t\tif (jwt) this.verifiedToken = jwt\n\t\t\t} else {\n\t\t\t\tthis.tokenVerificationMessage = `requires login for this data`\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tconst headers = {}\n\t\t// TODO: may remove custom header later, after extensive testing that nothing would break in prod\n\t\tif (auth.headerKey && typeof this.verifiedToken == 'string') headers[auth.headerKey] = this.verifiedToken\n\t\t// in cases where CORS prevents an http-domain based session cookie from being passed to the PP server,\n\t\t// then this header will be used by the PP server\n\t\tif (this.sessionId) headers['x-sjppds-sessionid'] = this.sessionId\n\t\t// may use a saved jwt to verify against a random server process in a farm;\n\t\t// at this point, should prefer to use a saved PP-server generated jwt instead of reusing an\n\t\t// embedder's jwt callback, because a PP-issued jwt would already have a tracked session id\n\t\t// so it's easier to verify\n\t\tconst jwt = getSavedToken(dslabel, route) || (await this.opts.getDatasetAccessToken?.(route))\n\t\tif (jwt) headers.authorization = `Bearer ${btoa(jwt)}`\n\t\treturn headers\n\t}\n\n\tgetClientAuthResult() {\n\t\treturn this.state.termdbConfig?.clientAuthResult\n\t}\n\n\tasync trackDsAction({ action, details }) {\n\t\tconst headers = { 'x-sjppds-sessionid': this.sessionId }\n\t\t// NOTE: do not hardcode the .termdb route here, there may be more tracked actions later\n\t\tconst jwt = await this.opts.getDatasetAccessToken?.('termdb')\n\t\tif (jwt) headers.authorization = 'Bearer ' + btoa(jwt)\n\t\tawait dofetch3('/authorizedActions', {\n\t\t\tmethod: 'POST',\n\t\t\tcredentials: 'include',\n\t\t\theaders,\n\t\t\tbody: Object.assign({\n\t\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t\taction,\n\t\t\t\tdetails,\n\t\t\t\t'x-sjppds-sessionid': this.sessionId\n\t\t\t})\n\t\t})\n\t}\n\n\t// get a minimum copy of tw\n\t// for better GET caching by the browser\n\tgetTwMinCopy(tw) {\n\t\tif (!tw) return\n\t\tconst copy = { term: {}, q: tw.q }\n\t\tdelete copy.q.isAtomic\n\t\tif (tw.$id) copy.$id = tw.$id\n\t\tif (tw.term) {\n\t\t\tif (isDictionaryType(tw.term.type)) {\n\t\t\t\t// dictionary term\n\t\t\t\tif (tw.term.id) copy.term.id = tw.term.id\n\t\t\t\tif (tw.term.name) copy.term.name = tw.term.name\n\t\t\t\tif (tw.term.type) copy.term.type = tw.term.type\n\t\t\t\tif (tw.term.values) copy.term.values = tw.term.values\n\t\t\t\tif (tw.term.groupsetting) copy.term.groupsetting = tw.term.groupsetting\n\t\t\t\tif (tw.term.termIds) copy.term.termIds = tw.term.termIds\n\t\t\t\tif (tw.term.memberType) copy.term.memberType = tw.term.memberType\n\t\t\t\tif (tw.term.valueTransform) copy.term.valueTransform = tw.term.valueTransform\n\t\t\t\tif (tw.term.categoryKeys) copy.term.categoryKeys = tw.term.categoryKeys\n\t\t\t\tif (tw.term.termlst) copy.term.termlst = tw.term.termlst\n\t\t\t\tif (tw.term.propsByTermId) copy.term.propsByTermId = tw.term.propsByTermId\n\t\t\t\tif (tw.term.isCustom) copy.term.isCustom = tw.term.isCustom\n\t\t\t} else {\n\t\t\t\t// non-dictionary term\n\t\t\t\t// pass entire tw.term because non-dictionary terms\n\t\t\t\t// cannot get rehydrated on server-side\n\t\t\t\tcopy.term = structuredClone(tw.term)\n\t\t\t\t// dummy preset bins should not affect the uniqueness of a request payload\n\t\t\t\tif (copy.term.bins?.default?.isDummyPreset) delete copy.term.bins\n\t\t\t}\n\t\t}\n\t\treturn copy\n\t}\n\n\tcacheTermQ(term, q) {\n\t\t// only save q with a user or automatically assigned name\n\t\tif (!q.reuseId) throw `missing term q.reuseId for term.id='${term.id}'`\n\t\tthis.app.dispatch({\n\t\t\ttype: 'cache_termq',\n\t\t\ttermId: term.id,\n\t\t\tq\n\t\t})\n\t}\n\n\tasync uncacheTermQ(term, q) {\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'uncache_termq',\n\t\t\tterm,\n\t\t\tq\n\t\t})\n\t}\n\n\tgetCustomTermQLst(term) {\n\t\tif (term.id) {\n\t\t\tconst cache = this.state.reuse.customTermQ.byId[term.id] || {}\n\t\t\tconst qlst = Object.values(cache).map(q => JSON.parse(JSON.stringify(q)))\n\t\t\t// find a non-conflicting reuseId for saving a new term.q\n\t\t\tfor (let i = qlst.length + 1; i < 1000; i++) {\n\t\t\t\tconst nextReuseId = `Setting #${i}`\n\t\t\t\tif (!qlst.find(q => q.reuseId === nextReuseId)) {\n\t\t\t\t\tqlst.nextReuseId = nextReuseId\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\t// last resort to use a random reuseId that is harder to read\n\t\t\tif (!qlst.nextReuseId) {\n\t\t\t\tqlst.nextReuseId = btoa((+new Date()).toString()).slice(10, -3)\n\t\t\t}\n\t\t\treturn qlst\n\t\t} else return []\n\t}\n\n\tasync addCustomTerm(obj) {\n\t\t// save one custom term\n\t\t// obj = { name:str, term:{} }\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'add_customTerm',\n\t\t\tobj\n\t\t})\n\t}\n\tasync deleteCustomTerm(name) {\n\t\t// delete by name\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'delete_customTerm',\n\t\t\tname\n\t\t})\n\t}\n\n\tasync getCustomTerms() {\n\t\tif (!Array.isArray(this.state.customTerms)) return [] // only mass state has this, here this instance is missing it. do not crash\n\t\t// return list of term{}; do not return whole object\n\t\treturn this.state.customTerms.map(i => i.tw)\n\t}\n\n\tasync addGroup(obj) {\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'add_group',\n\t\t\tobj\n\t\t})\n\t}\n\n\tasync deleteGroup(name) {\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'delete_group',\n\t\t\tname\n\t\t})\n\t}\n\n\tasync getGroups() {\n\t\tif (!Array.isArray(this.state.groups)) return [] // only mass state has this, here this instance is missing it. do not crash\n\t\t// return list of term{}; do not return whole object\n\t\treturn this.state.groups\n\t}\n\n\tisAbortError(e) {\n\t\tif (e instanceof DOMException) return e.name === 'AbortError'\n\t\tif (typeof e == 'string') return e.includes('stale sequenceId') || e.includes('AbortError')\n\t\treturn false\n\t}\n}\n", "import { disappear } from './animation'\n\n/*\n---------Exported---------\nsayerror()\n\t- Displays error message in new, closable, red div OR error message.\n\nthrowMsgWithFilePathAndFnName()\n\t- Generic throw message that includes the file and function name in this format: `Message [fileName functionName()]\n\nshowErrorWithCounter\n\t- Displays the error message with a counter in a red div. \n*/\n\nexport function sayerror(holder: any, o: any) {\n\t// 2nd argument is a string or an Error object\n\tlet msg: any // string message for display\n\tif (typeof o == 'string') {\n\t\tmsg = o\n\t} else {\n\t\tmsg = o.message || o.error\n\t\tif (o.stack) console.log(o.stack) // print out stack\n\t}\n\tholder.style('padding-left', '10px') //to align with sandbox padding\n\tconst div = holder\n\t\t.append('div')\n\t\t.attr('class', holder.classed('sja_errorbar') ? null : 'sja_errorbar')\n\t\t.style('border-radius', '5px')\n\tdiv\n\t\t.append('div')\n\t\t.style('padding-right', '8px')\n\t\t.html('✕')\n\t\t.style('display', 'inline-block')\n\t\t.on('click', () => {\n\t\t\tdisappear(div, true)\n\t\t})\n\t// msg can contain injected XSS, so never do .html(msg)\n\tdiv.append('div').style('display', 'inline-block').text(msg)\n}\n\nexport function throwMsgWithFilePathAndFnName(message: string) {\n\ttry {\n\t\tthrow new Error()\n\t} catch (error: any) {\n\t\tconst stackLines = error.stack.split('\\n')\n\t\tconst callerLine = stackLines[2].trim()\n\n\t\t// Extract the file name and function name\n\t\tconst regex = /\\s*at\\s+(.*)\\s+\\((.*).proteinpaint.js:(\\d+):(\\d+)\\)/\n\t\tconst match = callerLine.match(regex)\n\n\t\tif (match) {\n\t\t\tconst functionName = match[1]\n\t\t\tconst fileName = match[2]\n\t\t\t\t.replace(/^.*\\/bin\\//, '') //remove window.origin\n\t\t\t\t.replace(/_([^_]+)$/, '.$1') //readable file extension\n\t\t\t\t.replaceAll(/_/g, '/') //readable file path pattern\n\t\t\tconst errorMsg = `${message} [${fileName} ${functionName}()]`\n\t\t\tthrow new Error(errorMsg)\n\t\t} else {\n\t\t\tthrow new Error(message)\n\t\t}\n\t}\n}\n\nexport function showErrorsWithCounter(errs: string | string[], holder: any) {\n\tif (typeof errs == 'string') return sayerror(holder, errs)\n\tif (errs.length === 0) return\n\tif (errs.length === 1) return sayerror(holder, errs[0])\n\n\tlet showErrors = false\n\t//Anywhere on the error bar is clickable to show/hide the error messages\n\tconst wrapper = holder\n\t\t.append('div')\n\t\t.attr('class', 'sja_errorbar')\n\t\t.on('click', () => {\n\t\t\tshowErrors = !showErrors\n\t\t\terrorsDiv.style('display', showErrors ? 'block' : 'none')\n\t\t})\n\n\t// Close button\n\twrapper\n\t\t.append('div')\n\t\t.style('padding-right', '8px')\n\t\t.style('display', 'inline-block')\n\t\t.html('✕')\n\t\t.on('click', () => {\n\t\t\tdisappear(wrapper, true)\n\t\t})\n\n\t// Counter\n\tconst counterTextDiv = wrapper.append('div').style('display', 'inline-block')\n\n\tcounterTextDiv\n\t\t.append('div')\n\t\t.style('display', 'inline-block')\n\t\t.style('color', 'white')\n\t\t.style('background-color', 'red')\n\t\t.style('border-radius', '100px')\n\t\t.style('padding', '1px 4px')\n\t\t.text(errs.length)\n\n\t// Text\n\tcounterTextDiv.append('div').text('errors found.').style('padding', '3px').style('display', 'inline-block')\n\n\t//Error messages\n\tconst errorsDiv = wrapper.append('div').style('display', 'none').style('margin-left', '10px')\n\n\tfor (const err of errs) {\n\t\terrorsDiv.append('div').text(err)\n\t}\n}\n", "import { Vocab } from './Vocab'\nimport { getNormalRoot } from '#filter'\nimport { isUsableTerm } from '#shared/termdb.usecase.js'\nimport { throwMsgWithFilePathAndFnName } from '../dom/sayerror'\nimport { isDictionaryType } from '#shared/terms.js'\n\nexport class TermdbVocab extends Vocab {\n\t// migrated from termdb/store\n\tasync getTermdbConfig() {\n\t\tif (this.opts.getDatasetAccessToken) {\n\t\t\t// mass app init may need clientAuthResult, so need to trigger\n\t\t\t// login so termdb/config response would match the user log-in status\n\n\t\t\ttry {\n\t\t\t\t// sets this.app.vocabApi.verifiedToken to false if the token was not valid. nav.js checks this value and throws an error\n\t\t\t\t// when the token is not valid no error is thrown but a response with an error message is sent\n\t\t\t\tawait this.maySetVerifiedToken(this.state.vocab.dslabel)\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e)\n\t\t\t}\n\t\t}\n\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\tconst data = await this.dofetch3('termdb/config', {\n\t\t\theaders,\n\t\t\tbody: {\n\t\t\t\tgenome: this.vocab.genome,\n\t\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t\tembedder: window.location.hostname\n\t\t\t}\n\t\t})\n\n\t\tif (data.error) throw data.error\n\n\t\t// note: in case of error such as missing dataset, supply empty object\n\t\tthis.termdbConfig = data.termdbConfig || {}\n\t\treturn this.termdbConfig\n\t}\n\n\tasync getTermChildren(term, cohortValuelst, filter) {\n\t\tlet data\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tfilter: getNormalRoot(filter)\n\t\t}\n\t\tif (cohortValuelst) {\n\t\t\tbody.cohortValues = cohortValuelst.slice().sort().join(',')\n\t\t}\n\t\tif (this.state.treeFilter) {\n\t\t\tbody.treeFilter = this.state.treeFilter\n\t\t}\n\t\tif (term.__tree_isroot) {\n\t\t\tbody.default_rootterm = 1\n\t\t\tdata = await this.dofetch3('termdb/rootterm', { body }, this.opts.fetchOpts)\n\t\t} else {\n\t\t\tbody.get_children = 1\n\t\t\tbody.tid = term.id\n\t\t\tdata = await this.dofetch3('termdb/termchildren', { body }, this.opts.fetchOpts)\n\t\t}\n\t\tif (data.error) throw data.error\n\t\tfor (const term of data.lst) {\n\t\t\tif (term.type == 'integer' || term.type == 'float') {\n\t\t\t\tif (term.bins?.rounding) term.bins.default.rounding = term.bins.rounding\n\t\t\t\tif (term.bins?.label_offset && !term.bins?.default?.label_offset)\n\t\t\t\t\tterm.bins.default.label_offset = term.bins.label_offset\n\t\t\t}\n\t\t}\n\t\treturn data\n\t}\n\n\t/* from termdb/plot\n Input:\n opts{}\n .term={}\n .id=str\n .term={}\n .q={}\n .term2={}\n id/term/q\n .term0={}\n id/term/q\n .filter={}\n Output:\n a structure from the termdb/barsql route\n */\n\tasync getNestedChartSeriesData(opts, signal = undefined) {\n\t\tconst [route, body] = this.getTdbDataUrl(opts)\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\tconst initOpts = { headers, body }\n\t\tinitOpts.signal = signal\n\t\tconst data = await this.dofetch3(route, initOpts, this.opts.fetchOpts)\n\t\tif (data.error) throw data.error\n\n\t\tconst valuesByTermId = {}\n\n\t\t// TODO: instead of this workaround to fill in missing categorical term.values,\n\t\t// should query all available values in getterm()\n\t\tif (data.charts) {\n\t\t\tfor (const chart of data.charts) {\n\t\t\t\tthis.mayFillInMissingCatValues(opts.term0, chart.chartId, chart.total)\n\n\t\t\t\tfor (const series of chart.serieses) {\n\t\t\t\t\tthis.mayFillInMissingCatValues(opts.term, series.seriesId, series.total)\n\n\t\t\t\t\tfor (const data of series.data) {\n\t\t\t\t\t\tthis.mayFillInMissingCatValues(opts.term2, data.dataId, data.total)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.mayFillCategories(opts, data.categories)\n\n\t\treturn data\n\t}\n\n\tmayFillInMissingCatValues(term, key, total) {\n\t\tif (!key) return\n\t\tif (!(term?.id in this.missingCatValsByTermId)) return\n\t\tconst t = this.missingCatValsByTermId[term.id]\n\t\tif (!(key in t.values)) {\n\t\t\t// TODO: assign color here so that the same color is used for a value even as the chart gets updated or reused\n\t\t\tt.values[key] = { key, label: key /*color: */ }\n\t\t\tt.samplecount[key] = { samplecount: 0, key, label: key }\n\t\t}\n\t\t// !!! NOTE: assumes a sample may only have at most one value by term\n\t\t// and so can add samplecount totals for an overlay term across charts and serieses\n\t\tt.samplecount[key].samplecount += total\n\t}\n\n\t// fill in term.categories with\n\t// categories computed from the data\n\tmayFillCategories(opts, categories) {\n\t\tif (!categories) return\n\t\tif (!Array.isArray(categories)) throw 'categories is not array'\n\t\tfor (const [i, k] of ['term0', 'term', 'term2'].entries()) {\n\t\t\tconst tw = opts[k]\n\t\t\tif (!tw) continue\n\t\t\tconst c = categories[i]\n\t\t\tif (!Object.keys(c).length) continue\n\t\t\ttw.term.categories = c\n\t\t}\n\t}\n\n\t/*\n Create URL parameters for charts that use the \n `/termdb*` server route, which expects the \n term0, term, term2 variable naming convention\n\n Arguments:\n opts\n - chart configuration object with termwrappers of\n term (required), term0 (optional) and term2 (optional)\n \t\n .term \n required, {term, q}\n .term2\n optional overlay term, {term, q}\n .term0\n optional divide-by term, {term, q}\n .filter\n optional filter object \n .filter0\n optional gdc filter\n */\n\tgetTdbDataUrl(opts) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\tif (opts.chartType == 'cuminc') body.getcuminc = 1\n\t\tif (opts.chartType == 'survival') body.getsurvival = 1\n\n\t\tfor (const _key of ['term0', 'term', 'term2']) {\n\t\t\t// \"term\" on client is \"term1\" at backend\n\t\t\tconst tw = this.getTwMinCopy(opts[_key])\n\t\t\tif (!tw) continue\n\t\t\tconst key = _key == 'term' ? 'term1' : _key\n\t\t\tbody[key + '_$id'] = tw.$id\n\t\t\t// will need to generalize to also consider type=geneExpression\n\t\t\tif ('id' in tw.term && (!tw.term?.type || isDictionaryType(tw.term.type))) {\n\t\t\t\tbody[key + '_id'] = tw.term.id\n\t\t\t} else {\n\t\t\t\tbody[key] = tw.term\n\t\t\t}\n\t\t\tif (!tw.q) throw 'plot.' + _key + '.q{} missing: ' + tw.term.id\n\t\t\tbody[key + '_q'] = tw.q //q_to_param(tw.q) ????\n\t\t}\n\n\t\tif (opts.filter) {\n\t\t\tconst filter = getNormalRoot(opts.filter)\n\t\t\tif (filter.lst.length) {\n\t\t\t\tbody.filter = filter\n\t\t\t}\n\t\t}\n\t\tif (opts.filter0) body.filter0 = opts.filter0\n\n\t\tif ('grade' in opts) body.grade = opts.grade\n\t\tif ('minSampleSize' in opts) body.minSampleSize = opts.minSampleSize\n\n\t\tif (opts.term2) {\n\t\t\t//send the hidden group labels to server to ignore them when computing association test pvalues\n\t\t\tconst hiddenValues = {\n\t\t\t\tterm1: opts.term.q.hiddenValues\n\t\t\t\t\t? Object.keys(opts.term.q.hiddenValues).map(h => opts.term.term.values?.[h]?.label || h)\n\t\t\t\t\t: [],\n\t\t\t\tterm2: opts.term2.q.hiddenValues\n\t\t\t\t\t? Object.keys(opts.term2.q.hiddenValues).map(h => opts.term2.term.values?.[h]?.label || h)\n\t\t\t\t\t: []\n\t\t\t}\n\t\t\tbody.hiddenValues = hiddenValues\n\t\t}\n\n\t\t// start of mds3 parameters for variant2sample query\n\t\tif (opts.get) body.get = opts.get\n\t\t// end of mds3 parameters\n\n\t\treturn [opts.chartType ? 'termdb' : 'termdb/barsql', body]\n\t}\n\n\t/*\n May override certain term-related configuration (like bins),\n from the server response data to the corresponding term's \n current state.\n\n Arguments\n config\n - chart configuration object with termwrappers of\n term (required), term0 (optional) and term2 (optional)\n\n - data\n server response data in the format of \n {\n charts: [{\n chartId: '...',\n serieses: [{\n seriesId: '...',\n data: [{\n dataId: '...',\n total: *samplecount*\n }, ...],\n total: *samplecount*\n }, ...],\n total: *samplecount*\n }, ...],\n\n refs: {...}\n }\n */\n\tsyncTermData(config, data, prevConfig = {}) {\n\t\tif (!data || !data.refs) return\n\t\t// must maintain the order of term* string values in the looped array,\n\t\t// so that the entry index must matches the data.refs.bins[], q[] order\n\t\tfor (const [i, key] of ['term0', 'term', 'term2'].entries()) {\n\t\t\tconst term = config[key]\n\t\t\tconst persistTerm = !prevConfig[key] || prevConfig[key].term?.id === term?.term?.id\n\t\t\tif (term == 'genotype') continue\n\t\t\tif (!term) {\n\t\t\t\tif (key == 'term') throw `missing plot.term{}`\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (data.refs.bins) {\n\t\t\t\tterm.bins = data.refs.bins[i]\n\t\t\t\tif (data.refs.q && data.refs.q[i]) {\n\t\t\t\t\tif (!term.q) term.q = {}\n\t\t\t\t\tconst q = data.refs.q[i]\n\t\t\t\t\t// FIGURE OUT: when will q equal term.q?\n\t\t\t\t\tif (q !== term.q || !persistTerm) {\n\t\t\t\t\t\tif (q.type != term.q.type || q.mode != term.q.mode) {\n\t\t\t\t\t\t\tfor (const key in term.q) {\n\t\t\t\t\t\t\t\t// persist hiddenValues if it exists, but may be overridden by the server data's q\n\t\t\t\t\t\t\t\tif (key != 'hiddenValues' || !persistTerm) delete term.q[key]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tObject.assign(term.q, q)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!term.q) term.q = {}\n\t\t}\n\t}\n\n\t/* \n Generate regression analysis results\n config{}\n .regressionType: 'linear' | 'logistic'\n .outcome {id, term, q, refGrp}\n .independent[ {id, term, q, refGrp}, ... ]\n */\n\tasync getRegressionData(opts) {\n\t\tif (!isDictionaryType(opts.outcome.term.type)) throw 'outcome must be dictionary term'\n\t\tconst outcome = this.getTwMinCopy(opts.outcome)\n\t\toutcome.id = outcome.term.id\n\t\toutcome.q = JSON.parse(JSON.stringify(opts.outcome.q))\n\t\toutcome.type = outcome.term.type // TODO: refactor backend to not require outcome.type (similar issue with independent variables, see below)\n\t\tif (!outcome.q.mode && opts.regressionType == 'linear') outcome.q.mode = 'continuous'\n\t\tconst contQkeys = ['mode', 'scale']\n\t\toutcome.refGrp = outcome.q.mode == 'continuous' ? 'NA' : opts.outcome.refGrp\n\t\tif (opts.outcome.nonRefGrp) outcome.nonRefGrp = opts.outcome.nonRefGrp\n\n\t\tif (outcome.q.mode == 'continuous') {\n\t\t\t// remove unneeded parameters from q\n\t\t\tfor (const key in outcome.q) {\n\t\t\t\tif (!contQkeys.includes(key)) delete outcome.q[key]\n\t\t\t}\n\t\t}\n\n\t\tconst body = {\n\t\t\tgetregression: 1,\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tregressionType: opts.regressionType,\n\t\t\toutcome,\n\t\t\tindependent: opts.independent.map(tw => {\n\t\t\t\tconst t = this.getTwMinCopy(tw)\n\t\t\t\tt.refGrp = tw.refGrp\n\t\t\t\tt.interactions = tw.interactions\n\t\t\t\tconst q = JSON.parse(JSON.stringify(t.q))\n\t\t\t\tdelete q.values\n\t\t\t\tdelete q.totalCount\n\t\t\t\tif (t.q.mode == 'continuous') {\n\t\t\t\t\t// remove unneeded parameters from q\n\t\t\t\t\tfor (const key in q) {\n\t\t\t\t\t\tif (!contQkeys.includes(key)) delete q[key]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t// TODO: refactor backend code to not have to pass\n\t\t\t\t\t// term.id, term.type, and term.values separately\n\t\t\t\t\t$id: tw.$id,\n\t\t\t\t\tid: t.term.id,\n\t\t\t\t\tq,\n\t\t\t\t\tterm: t.term,\n\t\t\t\t\ttype: t.term.type,\n\t\t\t\t\trefGrp: t.q.mode == 'continuous' ? 'NA' : t.refGrp,\n\t\t\t\t\tinteractions: t.interactions || [],\n\t\t\t\t\tvalues: t.term.values\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tconst filterData = getNormalRoot(opts.filter)\n\t\tif (filterData.lst.length) body.filter = filterData\n\t\tif (opts.includeUnivariate) body.includeUnivariate = opts.includeUnivariate\n\t\tconst data = await this.dofetch3('termdb', { body }, this.opts.fetchOpts)\n\t\tif (data.error) throw data.error\n\t\treturn data\n\t}\n\n\t/*\n\tstr: search phrase\n\tcohorStr\n\tusecase\n\ttargetType\n\t\tsnp = find if str matches with dbsnp\n\t\tcategory = match with catgory of a term (not implemented yet)\n\t\tblank string for default behavior of matching with dict term or gene names\n\t*/\n\tasync findTerm(str, cohortStr = '', usecase = null, targetType = '') {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tfindterm: encodeURIComponent(str),\n\t\t\tcohortStr\n\t\t}\n\t\tif (usecase) body.usecase = usecase\n\t\tif (this.state.treeFilter) body.treeFilter = this.state.treeFilter\n\t\tif (targetType) body.targetType = targetType\n\t\tconst data = await this.dofetch3('termdb', { body })\n\t\tif (data.error) throw data.error\n\t\t// sort results\n\t\tconst n = str.toUpperCase()\n\t\tconst r = { equals: [], startsWith: [], startsWord: [], includes: [] }\n\t\tfor (const i of data.lst) {\n\t\t\tconst name = i.name.toUpperCase()\n\t\t\tif (name === n) r.equals.push(i)\n\t\t\telse if (name.startsWith(n)) r.startsWith.push(i)\n\t\t\telse if (name.includes(' ' + n)) r.startsWord.push(i)\n\t\t\telse r.includes.push(i)\n\t\t}\n\t\tdata.lst = [...r.equals, ...r.startsWith, ...r.startsWord, ...r.includes]\n\t\treturn data\n\t}\n\n\t// from termdb/terminfo\n\tasync getTermInfo(id) {\n\t\tif (!id) throw '.getTermInfo: Missing term id' //If missing doesn't throw as expected in later calls\n\t\tconst args = ['genome=' + this.vocab.genome + '&dslabel=' + this.vocab.dslabel + '&getterminfo=1&tid=' + id]\n\t\tconst data = await this.dofetch3('/termdb?' + args.join('&'), {}, this.opts.fetchOpts)\n\t\tif (data.error) throw data.error\n\t\treturn data\n\t}\n\n\tasync getCohortSampleCount(cohort) {\n\t\t// if dataset does not use subchort, cohortName=null and total number of samples is returned\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tcohort\n\t\t}\n\t\tconst data = await this.dofetch3('termdb/cohort/summary', { body }, this.opts.fetchOpts)\n\t\tif (!data) throw 'missing data'\n\t\tif (data.error) throw data.error\n\t\treturn data.count\n\t}\n\n\t/** opts: \n\t \tfilterJSON: JSON || string, required\n\t\treturns sample list in array of [{id, name}....]\n\t */\n\tasync getFilteredSampleList(filterJSON) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tgetsamplelist: 1,\n\t\t\tfilter: typeof filterJSON == 'string' ? filterJSON : getNormalRoot(filterJSON)\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', { body }, this.opts.fetchOpts)\n\t\tif (!data) throw `missing data`\n\t\tif (data.error) throw data.error\n\t\tif (!Array.isArray(data)) throw 'data is not array'\n\t\treturn data\n\t}\n\t/** opts: \n\t \tfilterJSON: JSON || string, required\n\t\treturns sample count per type\n\t */\n\tasync getGrin2Data(body, signal) {\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\tconst payload = { ...body, genome: this.vocab.genome, dslabel: this.vocab.dslabel }\n\t\tconst data = await this.dofetch3('grin2', { headers, body: payload, signal }, this.opts.fetchOpts)\n\t\tif (data.error) throw data.error\n\t\treturn data\n\t}\n\n\tasync getFilteredSampleCount(filterJSON) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tgetsamplecount: 1,\n\t\t\tfilter: getNormalRoot(filterJSON)\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', { body }, this.opts.fetchOpts)\n\t\tif (!data) throw `missing data`\n\t\tif (data.error) throw data.error\n\t\treturn data.count\n\t}\n\n\tasync getViolinBox(arg, _body = {}, signal = undefined) {\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\targ.tw = this.getTwMinCopy(arg.tw)\n\t\targ.tw.q.mode = 'continuous'\n\t\tif (arg.overlayTw) arg.overlayTw = this.getTwMinCopy(arg.overlayTw)\n\t\tif (arg.divideTw) arg.divideTw = this.getTwMinCopy(arg.divideTw)\n\n\t\t// Set chartType based on plotType argument\n\t\tif (!arg.plotType) throw new Error('plotType is required: must be \"violin\" or \"box\"')\n\t\tif (arg.plotType !== 'violin' && arg.plotType !== 'box') {\n\t\t\tthrow new Error('plotType must be either \"violin\" or \"box\"')\n\t\t}\n\n\t\tconst body = Object.assign(\n\t\t\t{\n\t\t\t\tplotType: arg.plotType,\n\t\t\t\tgenome: this.vocab.genome,\n\t\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t\tfilter: arg.filter || this.state.termfilter?.filter,\n\t\t\t\tfilter0: this.state.termfilter?.filter0\n\t\t\t},\n\t\t\targ\n\t\t)\n\n\t\t// Add violin-specific defaults\n\t\tif (arg.plotType === 'violin') {\n\t\t\tObject.assign(body, {\n\t\t\t\tembedder: window.location.hostname,\n\t\t\t\tdevicePixelRatio: window.devicePixelRatio,\n\t\t\t\tisKDE: 'isKDE' in arg ? arg.isKDE : true,\n\t\t\t\tticks: arg.ticks,\n\t\t\t\tdatasymbol: arg.datasymbol || 'rug',\n\t\t\t\torientation: arg.orientation || 'horizontal',\n\t\t\t\tradius: arg.radius || 8,\n\t\t\t\tsvgw: arg.svgw || 200\n\t\t\t})\n\t\t}\n\n\t\t// Merge additional body properties\n\t\tObject.assign(body, _body)\n\n\t\tif (body.filter) body.filter = getNormalRoot(body.filter)\n\t\tconst init = { headers, body, signal }\n\t\tconst data = await this.dofetch3('termdb/violinBox', init)\n\t\tif (data.error) throw data.error\n\t\treturn data\n\t}\n\n\tasync getPercentile(term, percentile_lst, termfilter) {\n\t\t// for a numeric term, convert a percentile to an actual value, with respect to a given filter\n\t\tif (percentile_lst.find(p => !Number.isInteger(p))) throw 'non-integer percentiles found'\n\t\tif (Math.max(...percentile_lst) > 99 || Math.min(...percentile_lst) < 1) throw 'percentiles must be between 1-99'\n\t\tconst body = {\n\t\t\tgetpercentile: percentile_lst,\n\t\t\tterm,\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel\n\t\t}\n\t\tif (termfilter) {\n\t\t\tif (termfilter.filter) body.filter = getNormalRoot(termfilter.filter)\n\t\t\tif (termfilter.filter0) body.filter0 = termfilter.filter0\n\t\t}\n\t\tconst signal = this.app?.getAbortSignal?.() // ok to be undefined\n\t\treturn await this.dofetch3('termdb/getpercentile', { body, signal })\n\t}\n\n\tasync getDescrStats(tw, termfilter, logScale, signal) {\n\t\t// for a numeric term, get descriptive statistics e.g mean, median, standard deviation, min, max\n\t\t// logScale is boolean\n\t\tconst body = {\n\t\t\ttw,\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel\n\t\t}\n\t\tif (logScale) body.logScale = true\n\t\tif (termfilter) {\n\t\t\tif (termfilter.filter) body.filter = getNormalRoot(termfilter.filter)\n\t\t\tif (termfilter.filter0) body.filter0 = termfilter.filter0\n\t\t}\n\t\treturn await this.dofetch3('/termdb/descrstats', { body, signal })\n\t}\n\n\t/**\n\t * Retrieve terms by ids from the term database.\n\t * @param {Array} ids - The array of term ids to retrieve\n\t * @param {string} [_dslabel=null] - The dataset label (optional)\n\t * @param {string} [_genome=null] - The genome identifier (optional)\n\t * @return {Object} The terms data retrieved based on the provided ids\n\t */\n\tasync getTerms(ids, _dslabel = null, _genome = null) {\n\t\tif (!ids) throw 'getTerms: ids missing'\n\t\tif (!Array.isArray(ids)) throw `invalid ids` // should use typescript\n\t\tconst dslabel = _dslabel || this.state.vocab?.dslabel // this.vocab is guaranteed to exist?\n\t\tconst genome = _genome || this.state.vocab?.genome // this.vocab is guaranteed to exist?\n\t\tif (!dslabel) throw 'getTerms: dslabel missing'\n\t\tif (!genome) throw 'getTerms: genome missing'\n\n\t\tconst body = {\n\t\t\tgenome,\n\t\t\tdslabel,\n\t\t\tids,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\n\t\tconst data = await this.dofetch3(`termdb/termsbyids`, { body })\n\t\tif (data.error) throw 'getTerm: ' + data.error\n\t\tfor (const id in data.terms) {\n\t\t\tconst term = data.terms[id]\n\t\t\tif (term.type == 'categorical' && !term.values) this.missingCatValsByTermId[term.id] = term\n\t\t}\n\t\treturn data.terms\n\t}\n\n\tasync getterm(termid, dslabel = null, genome = null) {\n\t\tif (!termid) throw 'getterm: termid missing'\n\n\t\tconst result = await this.getTerms([termid], dslabel, genome)\n\t\tconst term = result[termid]\n\t\tif (!term) throw 'no term found for ' + termid\n\n\t\treturn term\n\t}\n\n\tgraphable(term) {\n\t\tif (!term) throw 'graphable: term is missing'\n\t\treturn isUsableTerm(term).has('plot')\n\t}\n\n\t/*\n\taccepts one term of any type, including categorical, non-categorical, and non-dictionary\n\treturn number of samples per category/bin/grade/group etc\n\toptionally, caller can supply a {term1_q: {...}} key-object value in _body to customize categories\n\t*/\n\tasync getCategories(term, filter, _body = {}) {\n\t\tconst signal = this.app?.getAbortSignal?.()\n\t\tconst headers = await this.mayGetAuthHeaders()\n\t\tif (term.type == 'snplst' || term.type == 'snplocus') {\n\t\t\tconst body = Object.assign(\n\t\t\t\t{\n\t\t\t\t\tvalidateSnps: 1,\n\t\t\t\t\tsumSamples: 1,\n\t\t\t\t\tgenome: this.state.vocab.genome,\n\t\t\t\t\tdslabel: this.state.vocab.dslabel\n\t\t\t\t},\n\t\t\t\t_body\n\t\t\t)\n\n\t\t\tif (filter) body.filter = getNormalRoot(filter)\n\t\t\tif (this.state.termfilter?.filter0) body.filter0 = this.state.termfilter.filter0\n\t\t\treturn await this.dofetch3('/termdb', { headers, body, signal })\n\t\t}\n\n\t\tif (term.category2samplecount) {\n\t\t\t// grab directly from term and not the server\n\t\t\t// { categoryKey: count }\n\t\t\tconst l2 = []\n\t\t\tfor (const key in term.category2samplecount) {\n\t\t\t\tl2.push({\n\t\t\t\t\tkey,\n\t\t\t\t\tlabel: term?.values?.[key]?.label || key,\n\t\t\t\t\tsamplecount: term.category2samplecount[key]\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn { lst: l2 }\n\t\t}\n\n\t\tif (_body.categories) {\n\t\t\t// grab directly from body and not server\n\t\t\treturn _body.categories\n\t\t}\n\n\t\tif (_body.skip_categories) {\n\t\t\t// do not query server\n\t\t\treturn { lst: [] }\n\t\t}\n\n\t\t// no need to supply tw.$id: 1) this method is one term only and no need to distinguish multiple terms 2) backend will auto fill $id before retrieving data\n\t\tconst tw = { term, q: _body.term1_q || {} }\n\t\tdelete _body.term1_q // is now tw.q, so no longer needed\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\ttw: this.getTwMinCopy(tw),\n\t\t\t..._body\n\t\t}\n\n\t\tif (filter) {\n\t\t\tbody.filter = getNormalRoot(filter)\n\t\t}\n\n\t\tif (this.state.termfilter?.filter0) body.filter0 = this.state.termfilter.filter0\n\n\t\tconst data = await this.dofetch3('termdb/categories', { headers, body, signal })\n\t\tif (data.error) throwMsgWithFilePathAndFnName(data.error)\n\t\treturn data\n\t}\n\n\tasync getNumericUncomputableCategories(term, filter) {\n\t\t// for numeric term\n\t\t// return number of samples per uncomputable categories\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\ttid: term.id\n\t\t}\n\t\tif (filter) body.filter = getNormalRoot(filter)\n\t\tif (this.state.termfilter?.filter0) body.filter0 = this.state.termfilter.filter0\n\n\t\ttry {\n\t\t\tconst data = await this.dofetch3('/termdb/numericcategories', { body })\n\t\t\tif (data.error) throw data.error\n\t\t\treturn data\n\t\t} catch (e) {\n\t\t\tif (!this.isAbortError(e)) window.alert(e.message || e)\n\t\t}\n\t}\n\n\t/* when arg.text is true, arg should only be {text} from a snplst term;\n else, it should be the q{} of snplocus term: {chr,start,stop,variant_filter}\n to generate snp-sample gt matrix cache file and return file name\n */\n\tasync validateSnps(arg) {\n\t\tconst lst = ['validateSnps=1', 'genome=' + this.state.vocab.genome, 'dslabel=' + this.state.vocab.dslabel]\n\t\tif (arg.text) {\n\t\t\tlst.push('snptext=' + encodeURIComponent(arg.text))\n\t\t} else if (arg.chr) {\n\t\t\tlst.push('chr=' + arg.chr)\n\t\t\tlst.push('start=' + arg.start)\n\t\t\tlst.push('stop=' + arg.stop)\n\t\t\tif (arg.variant_filter) lst.push('variant_filter=' + encodeURIComponent(JSON.stringify(arg.variant_filter)))\n\t\t}\n\t\treturn await this.dofetch3('/termdb?' + lst.join('&'))\n\t}\n\n\tasync get_variantFilter() {\n\t\tconst body = { getvariantfilter: 1, genome: this.state.vocab.genome, dslabel: this.state.vocab.dslabel }\n\t\tif (this.state.termfilter?.filter0) body.filter0 = this.state.termfilter.filter0\n\t\t// used for snplocus term type\n\t\treturn await this.dofetch3('termdb', { body })\n\t}\n\n\t/*\n The server data sample annotations and refs are both indexed \n by term id, but will be remapped to be annotated instead with \n tw.$id. This will prevent conflicts when the same term.id is used\n multiple times in the terms[] argument, such as for the matrix plot.\n\n Arguments:\n\n opts{}\n .filter a filter object\n .filter0 read-only json object, only used for gdc dataset to store the cohort filter obj built by CohortBuilder\n .terms[{}] an array of termWrapper objects\n tw.$id id to disambugate when multiple terms\n with the same ID are in terms[], such as in matrix plot\n .termsPerRequest optional, a number greater than 1;\n\t when provided, a request includes the number of terms specified, improving the response times\n Returns \n {\n lst: [{\n sample, \n term1: {key, value}, \n term2: {key, values}, \n ...\n }],\n refs: {\n byTermId: {termIdorName1: {term, q}},\n bySampleId: {...}\n }\n }\n\t\n\t\n Expected server-data response\n {}\n .samples{}\n [sample]{}\n sample: the sample ID\n [$id]: {} // $id is tw id, not term id\n\t\t\t\tkey, value, // only used for dict term\n\t\t\t\tvalues:[]\n\t\t\t\t\t// used for non-dict term e.g. gene mutation\n\t\t\t\t\t{sample, ...mutation properties...}\n\t\n .refs{}\n .byTermId{}\n [$id]: {bins, etc} metadata for processed terms, useful\n for specifying value order, colors, etc.\n\t\t.bySampleId{}\n\t\t\t[sample]: {\n\t\t\t\tlabel:str, // required, the display name of this sample\n\t\t\t\totherLabels:[ {map to sjcloud}, {link to pbtp},] // optional, to define later\n\t\t\t}\n\t\t\tavailable sample name(s) mapped to each sample, for display only\n\n !!! NOTE !!!\n May fill in following attributes on term object if missing or met conditions:\n (the modifications are on term object and not tracked in state)\n\n tw.term.category2samplecount = {}\n tw.term.values={}\n */\n\tasync getAnnotatedSampleData(opts, _refs = {}) {\n\t\t// may check against required auth credentials for the server route\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\t// unlike scatter and violin, the matrix plot will NOT display anything\n\t\t// if sample names are not allowed to be displayed\n\t\t// TODO: may allow a request to proceed, but not display sampleNames???\n\t\t// Answer: showing multiple term values aligned for a sample can be considered identifying.\n\t\t// thus simply disable matrix plot if sample name is now allowed to show\n\t\tif (!headers) return\n\t\tconst filter = getNormalRoot(opts.filter)\n\t\tconst samples = {}\n\t\tconst refs = { byTermId: _refs.byTermId || {}, bySampleId: _refs.bySampleId || {} }\n\t\tconst promises = []\n\t\tconst samplesToShow = new Set()\n\n\t\t/************** tricky\n need list of gene names of current geneVariant terms from opts.terms[]\n\t\tassumption is that if this array is not empty,\n request for a dictionary term also from opts.terms[] will only retrieve samples mutated on this gene list, rather than whole cohort\n\t\tif currentGeneNames[] is empty, then dict term data return will not be restricted\n\t\t(even when this is needed, this is a poor fix as flat list of gene names does not allow restricting mclass or use genomic region)\n\n\t\t*************** and trickier\n\t\tdo not supply gene list if opts.isHierCluster is set!!! (doing hierarchical clustering)\n\t\tin such case, samples requested for dictionary term are based on those with data for hierCluster,\n\t\tbut not by mutation status of gene list\n */\n\t\tconst currentGeneNames =\n\t\t\topts.isHierCluster || opts.isSummary\n\t\t\t\t? null\n\t\t\t\t: opts.terms\n\t\t\t\t\t\t.filter(tw => tw.term.type === 'geneVariant')\n\t\t\t\t\t\t.map(tw => (tw.term.chr ? `${tw.term.chr}:${tw.term.start}-${tw.term.stop}` : tw.term.name))\n\t\t\t\t\t\t.sort() // sort the gene names by the default alphanumeric order to improve cache reuse even when terms are resorted\n\t\tconst allTerms2update = opts.terms.slice().sort((a, b) => (a.term.name < b.term.name ? -1 : 1)) // make copy of array as it will be truncated to empty. do not modify original\n\t\tconst maxNumTerms = this.opts.app.vocabApi.termdbConfig?.maxAnnoTermsPerClientRequest || opts.terms.length // this.vocab.dslabel === 'GDC' ? opts.terms.length : 1 // revert back to 1 to revert to previous behavior\n\t\tlet numResponses = 0\n\t\tif (opts.loadingDiv) opts.loadingDiv.html('Updating data ...')\n\n\t\tconst warnings = []\n\t\tconst frozenEmptyObj = Object.freeze({})\n\t\tconst signal = opts.signal || this.app?.getAbortSignal?.()\n\n\t\twhile (true) {\n\t\t\tconst copies = getTerms2update(allTerms2update, maxNumTerms) // list of unique terms to update in this round\n\t\t\tif (copies.length == 0) break // at the end of list, break loop\n\t\t\tconst init = {\n\t\t\t\theaders,\n\t\t\t\tcredentials: 'include',\n\t\t\t\tbody: {\n\t\t\t\t\tfor: 'matrix',\n\t\t\t\t\tgenome: this.vocab.genome,\n\t\t\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t\t\t// one request per term\n\t\t\t\t\tterms: copies.map(this.getTwMinCopy),\n\t\t\t\t\tfilter,\n\t\t\t\t\tembedder: window.location.hostname,\n\t\t\t\t\tisSummary: opts.isSummary\n\t\t\t\t},\n\t\t\t\tsignal\n\t\t\t}\n\n\t\t\tif (opts.filter0) init.body.filter0 = opts.filter0 // avoid adding \"undefined\" value\n\t\t\tif (opts.isHierCluster) init.body.isHierCluster = true // special arg from matrix, just pass along\n\t\t\tif (\n\t\t\t\tthis.vocab.dslabel == 'GDC' &&\n\t\t\t\tcopies.find(tw => tw.term.id && (!tw.term?.type || isDictionaryType(tw.term.type))) &&\n\t\t\t\tcurrentGeneNames?.length\n\t\t\t) {\n\t\t\t\t//term is dictionary term and there are gene terms,\n\t\t\t\t//add this to limit to mutated cases\n\t\t\t\tinit.body.currentGeneNames = currentGeneNames\n\t\t\t}\n\n\t\t\tpromises.push(\n\t\t\t\tthis.dofetch3('termdb', init)\n\t\t\t\t\t.then(data => {\n\t\t\t\t\t\tif (data.error) throw data.error\n\t\t\t\t\t\tif (data.warning) warnings.push(data.warning.message)\n\t\t\t\t\t\t// console.log(825, structuredClone(Object.fromEntries(Object.entries(data.samples).slice(0, 5))))\n\t\t\t\t\t\tif (!data.refs.bySampleId) data.refs.bySampleId = {}\n\n\t\t\t\t\t\tconst $copyAs = data.refs.$codes.copyAs || {}\n\t\t\t\t\t\tconst $objAssign = data.refs.$codes.objAssign || {}\n\n\t\t\t\t\t\tfor (const tw of copies) {\n\t\t\t\t\t\t\tconst { shortId, gene } = data.refs.byTermId[tw.$id] || frozenEmptyObj // avoid unnecessarily creating placeholder objects\n\t\t\t\t\t\t\tconst origTw = opts.terms.find(o => o.$id === tw.$id)\n\n\t\t\t\t\t\t\tfor (const [sampleId, sample] of Object.entries(data.samples)) {\n\t\t\t\t\t\t\t\t// ignore sample objects that are not annotated by other keys besides 'sample'\n\t\t\t\t\t\t\t\tif (!Object.keys(sample).filter(k => k != 'sample').length) continue\n\t\t\t\t\t\t\t\tsamplesToShow.add(sampleId)\n\t\t\t\t\t\t\t\tif (!(sampleId in samples)) {\n\t\t\t\t\t\t\t\t\t// normalize the expected data shape\n\t\t\t\t\t\t\t\t\tif (!data.refs.bySampleId[sampleId]) data.refs.bySampleId[sampleId] = {}\n\t\t\t\t\t\t\t\t\tif (typeof data.refs.bySampleId[sampleId] == 'string')\n\t\t\t\t\t\t\t\t\t\tdata.refs.bySampleId[sampleId] = { label: data.refs.bySampleId[sampleId] }\n\n\t\t\t\t\t\t\t\t\tconst _ref_ = data.refs.bySampleId[sampleId]\n\t\t\t\t\t\t\t\t\t// assign default sample ref values here\n\t\t\t\t\t\t\t\t\t// TODO: may assign an empty string value if not allowed to display sample IDs or names ???\n\t\t\t\t\t\t\t\t\tif (!_ref_.label) _ref_.label = sampleId\n\t\t\t\t\t\t\t\t\tconst s = {\n\t\t\t\t\t\t\t\t\t\tsample: sampleId,\n\t\t\t\t\t\t\t\t\t\t// must reserve _ref -> should not be used as a term.id or tw.$id\n\t\t\t\t\t\t\t\t\t\t_ref_\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsamples[sampleId] = s\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!sample.sample) sample.sample = data.refs.bySampleId[sampleId].sample || sampleId\n\t\t\t\t\t\t\t\tif (!sample.sampleName) sample.sampleName = data.refs.bySampleId[sampleId].sampleName || sample.sample\n\n\t\t\t\t\t\t\t\tconst d = shortId ? sample[shortId] : sample[tw.$id]\n\t\t\t\t\t\t\t\tif (!d) continue\n\t\t\t\t\t\t\t\tif (shortId in sample) {\n\t\t\t\t\t\t\t\t\tsample[tw.$id] = d\n\t\t\t\t\t\t\t\t\tdelete sample[shortId]\n\n\t\t\t\t\t\t\t\t\t// rehydrate stripped props\n\t\t\t\t\t\t\t\t\tif (d.$) d[$copyAs[d.$]] = d.key\n\n\t\t\t\t\t\t\t\t\tif (gene && d.values) {\n\t\t\t\t\t\t\t\t\t\tfor (const v of d.values) {\n\t\t\t\t\t\t\t\t\t\t\tif (!v.class && v.$) {\n\t\t\t\t\t\t\t\t\t\t\t\tv.gene = gene\n\t\t\t\t\t\t\t\t\t\t\t\t// rehydrate stripped props\n\t\t\t\t\t\t\t\t\t\t\t\tObject.assign(v, $objAssign[v.$])\n\t\t\t\t\t\t\t\t\t\t\t\tdelete v.$\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (origTw.transformData) origTw.transformData(d)\n\t\t\t\t\t\t\t\tsamples[sampleId][tw.$id] = d\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (const sampleId in data.refs.bySampleId) {\n\t\t\t\t\t\t\t\trefs.bySampleId[sampleId] = data.refs.bySampleId[sampleId]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\trefs.byTermId[tw.$id] = tw\n\t\t\t\t\t\t\tif (tw.$id in data.refs.byTermId) {\n\t\t\t\t\t\t\t\trefs.byTermId[tw.$id] = Object.assign({}, refs.byTermId[tw.$id], data.refs.byTermId[tw.$id])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnumResponses++\n\t\t\t\t\t\tif (opts.loadingDiv) opts.loadingDiv.html(`Updating data (${numResponses}/${promises.length}) ...`)\n\t\t\t\t\t})\n\t\t\t\t\t.catch(e => {\n\t\t\t\t\t\tif (signal) this.app?.triggerAbort('', signal)\n\t\t\t\t\t\tthrow e\n\t\t\t\t\t})\n\t\t\t)\n\t\t}\n\t\ttry {\n\t\t\tif (opts.loadingDiv) opts.loadingDiv.html(`Updating data (0/${promises.length})`)\n\t\t\tawait Promise.all(promises)\n\t\t\tif (opts.loadingDiv) opts.loadingDiv.html('')\n\t\t} catch (e) {\n\t\t\tif (typeof e == 'string') {\n\t\t\t\tconst _e = e.toLowerCase()\n\t\t\t\t// TODO: standardize the auth error message across all SJ viz tools/portals,\n\t\t\t\t// which may be difficult since embedders can specify custom auth error messages,\n\t\t\t\t// or use an error object with separate code and string message\n\t\t\t\tif (\n\t\t\t\t\te.includes('token') ||\n\t\t\t\t\te.includes('jwt') ||\n\t\t\t\t\te.includes('login') ||\n\t\t\t\t\te.includes('sign') ||\n\t\t\t\t\te.includes('auth') ||\n\t\t\t\t\te.includes('credential')\n\t\t\t\t) {\n\t\t\t\t\t//\n\t\t\t\t\t// do not track non-auth related errors as a tokenVerificationMessage\n\t\t\t\t\t// only applies in SJ-portals where password or JWT auth tokens are used by embedders\n\t\t\t\t\t//\n\t\t\t\t\t// - app/viz must use vocabApi.hasVerifiedToken() method to verify access to tool features,\n\t\t\t\t\t// instead of relying on an empty string value for tokenVerificationMessage\n\t\t\t\t\t//\n\t\t\t\t\t// - !!! not used in the GDC portal, where auth is handled in the tool react wrapper + domain-based cookie session !!!\n\t\t\t\t\t//\n\t\t\t\t\tthis.tokenVerificationMessage = e\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t\ttry {\n\t\t\tif (opts.loadingDiv) opts.loadingDiv.html(`Processing data ...`)\n\t\t\tconst dictTerm$ids = opts.terms.filter(tw => isDictionaryType(tw.term.type)).map(tw => tw.$id)\n\t\t\t// const lst = Object.values(samples)\n\n\t\t\t// NOTE: Reactivated so that filtering works as expectd for pnet, mbmeta, etc\n\t\t\t// verified to work with two GDC matrix examples\n\t\t\t// TODO: verify with other GDC examples???\n\t\t\tconst lst = []\n\t\t\tif (!dictTerm$ids.length) {\n\t\t\t\t// If there are no dictionary terms, okay to show any samples with geneVariants\n\t\t\t\tlst.push(...Object.values(samples))\n\t\t\t} else {\n\t\t\t\t// If there are dictionary terms, only show samples that have been annotated\n\t\t\t\t// for at least one dictionary term, otherwise do NOT show samples that\n\t\t\t\t// are only annotated for non-dictionary terms like gene variants\n\t\t\t\t// NOTE: there is an exception when using matrix?.settings?.displayDictRowWithNoValues\n\t\t\t\tfor (const sampleId in samples) {\n\t\t\t\t\tconst row = samples[sampleId]\n\t\t\t\t\tfor (const $id in row) {\n\t\t\t\t\t\tif (dictTerm$ids.includes($id)) {\n\t\t\t\t\t\t\tlst.push(row)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!lst.length && this.termdbConfig?.matrix?.settings?.displayDictRowWithNoValues) {\n\t\t\t\t\t// this prevents the display of 'no matching sample data for the current gene list',\n\t\t\t\t\t// which may be confusing if there is data for genes but not for dictionary terms\n\t\t\t\t\tlst.push(...Object.values(samples))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst sampleFilter = new RegExp(opts.sampleNameFilter || '.*')\n\t\t\tconst data = {\n\t\t\t\tlst: lst.filter(row => samplesToShow.has(row.sample) && sampleFilter.test(row.sample)),\n\t\t\t\trefs,\n\t\t\t\twarnings\n\t\t\t}\n\t\t\tdata.samples = data.lst.reduce((obj, row) => {\n\t\t\t\tobj[row.sample] = row\n\t\t\t\treturn obj\n\t\t\t}, {})\n\n\t\t\tfor (const tw of opts.terms) {\n\t\t\t\tmayFillInCategory2samplecount4term(tw, data.lst, this.termdbConfig)\n\t\t\t}\n\t\t\treturn data\n\t\t} catch (e) {\n\t\t\tconsole.log(e)\n\t\t\tthrow e\n\t\t}\n\t}\n\n\t// ids: [str], where str are string term IDS or names\n\tasync getTermTypes(ids) {\n\t\tconst init = {\n\t\t\tbody: {\n\t\t\t\tfor: 'termTypes',\n\t\t\t\tgenome: this.vocab.genome,\n\t\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t\tids: JSON.stringify(ids)\n\t\t\t}\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', init, this.opts.fetchOpts)\n\t\tif (data.error) throw data.error\n\t\treturn data\n\t}\n\n\tasync getLDdata(tkname, m) {\n\t\tconst body = {\n\t\t\tgetLDdata: 1,\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tldtkname: tkname,\n\t\t\tm: { chr: m.chr, pos: m.pos, ref: m.ref, alt: m.alt }\n\t\t}\n\t\treturn await this.dofetch3('termdb', { body })\n\t}\n\n\tasync getScatterData(opts, signal = undefined) {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tplotName: opts.name,\n\t\t\tcoordTWs: opts.coordTWs?.map(tw => this.getTwMinCopy(tw)),\n\t\t\tfilter: getNormalRoot(opts.filter),\n\t\t\tfilter0: opts.filter0,\n\t\t\tembedder: window.location.hostname,\n\t\t\tsingleCellPlot: opts.singleCellPlot,\n\t\t\tchartType: opts.chartType\n\t\t}\n\t\tif (opts.colorColumn) body.colorColumn = opts.colorColumn\n\t\tif (opts.colorTW) body.colorTW = this.getTwMinCopy(opts.colorTW)\n\t\tif (opts.shapeTW) body.shapeTW = this.getTwMinCopy(opts.shapeTW)\n\t\tif (opts.divideByTW) body.divideByTW = this.getTwMinCopy(opts.divideByTW)\n\t\tif (opts.scaleDotTW) body.scaleDotTW = this.getTwMinCopy(opts.scaleDotTW)\n\t\tbody.excludeOutliers = opts.excludeOutliers\n\t\treturn await this.dofetch3('termdb/sampleScatter', { headers, body, signal })\n\t}\n\n\tasync getDefaultBins(opts) {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\t\tconst body = {\n\t\t\tfor: 'getDefaultBins',\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\ttw: opts.tw.getMinCopy?.({ q: {} }) || this.getTwMinCopy({ term: opts.tw.term, q: {} }),\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\t// this.state.termfilter is updated when there's a dispatch,\n\t\t// while this.opts.state.termfilter is only accurate on init(),\n\t\t// which may be sufficient in a standalone use case, but not when\n\t\t// used for controls.config term input components in a mass app;\n\t\t// comment out `/* this.state.termfilter || */` to simulate the\n\t\t// issue with filter0 (GDC case filter) not being sent when it is updated\n\t\tconst tf = this.state.termfilter || this.opts?.state?.termfilter\n\t\tif (tf) {\n\t\t\tif (tf.filter) body.filter = getNormalRoot(tf.filter)\n\t\t\tif (tf.filter0) body.filter0 = tf.filter0\n\t\t}\n\t\tconst signal = opts.signal || this.app?.getAbortSignal?.()\n\t\treturn await this.dofetch3('termdb', { headers, body, signal })\n\t}\n\n\t// it's safer to separately treat term and q as persisted objects but not tw,\n\t// since tw may have been constructed only as an argument for this function\n\t// and not as a persisted object elsewhere\n\tasync setTermBins({ $id, term, q }) {\n\t\t//TODO use the PresetNumericBins type for presetBins\n\t\tlet presetBins = await this.getDefaultBins({ tw: { $id, term, q } })\n\t\tif ('error' in presetBins) throw presetBins.error\n\t\tif (presetBins.default?.bin_size === null || presetBins.default?.first_bin.stop === null) {\n\t\t\t// allow no data error to be caught by plot code, to display a more\n\t\t\t// user-friendly error message instead of obscure bin-related error message\n\t\t\tpresetBins = {\n\t\t\t\tdefault: {\n\t\t\t\t\tmode: 'discrete',\n\t\t\t\t\ttype: 'regular-bin',\n\t\t\t\t\tbin_size: 1,\n\t\t\t\t\tfirst_bin: { startunbounded: true, stop: 2 },\n\t\t\t\t\tisDummyPreset: true\n\t\t\t\t}\n\t\t\t} // dummy presetBins\n\t\t}\n\t\t// NOTE: if term is frozen, creating an unfrozen copy here will\n\t\t// not propagate changes to the original term\n\t\tterm.bins = presetBins\n\t\tif (q.mode == 'discrete' && !q.type) {\n\t\t\t// only fill-in q if missing values are detected\n\t\t\tconst currMode = q.mode // record current mode before q{} is overriden\n\t\t\tfor (const key in q) {\n\t\t\t\tif (key != 'isAtomic') delete q[key]\n\t\t\t}\n\t\t\tObject.assign(q, term.bins.default)\n\t\t\tq.mode = currMode\n\t\t}\n\t}\n\n\tasync getSingleSampleData(opts) {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tfor: 'singleSampleData',\n\t\t\tsampleId: opts.sampleId,\n\t\t\tterm_ids: opts.term_ids,\n\t\t\tfilter: getNormalRoot(opts.filter),\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', { headers, body })\n\t\tconst byTermId = {}\n\t\tif ('error' in data) return data\n\t\tfor (const row of data) {\n\t\t\tconst term = JSON.parse(row.jsondata)\n\t\t\tbyTermId[row.term_id] = { value: row.value, term }\n\t\t}\n\t\treturn byTermId\n\t}\n\n\tasync getAllSamples() {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tfor: 'getAllSamples',\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', { headers, body })\n\t\treturn data\n\t}\n\n\tasync getSamplesByName(opts) {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tfor: 'getSamplesByName',\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\tif (opts?.filter) body.filter = getNormalRoot(opts.filter)\n\t\tconst data = await this.dofetch3('termdb', { headers, body })\n\t\treturn data\n\t}\n\n\tasync getProfileFacilities() {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tfor: 'getProfileFacilities',\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tembedder: window.location.hostname\n\t\t}\n\t\tconst data = await this.dofetch3('termdb', { headers, body })\n\t\tconst result = []\n\t\tfor (const row of data) result.push(row.name)\n\t\treturn result\n\t}\n\n\tasync getLowessCurve(opts) {\n\t\t// the scatter plot may still render when not in session,\n\t\t// but not have an option to list samples\n\t\tconst headers = await this.mayGetAuthHeaders('termb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tgetLowessCurve: 1,\n\t\t\tcoords: opts.coords\n\t\t}\n\n\t\treturn await this.dofetch3('termdb', { headers, body })\n\t}\n\n\tasync getMultivalueTWs(opts) {\n\t\tconst headers = await this.mayGetAuthHeaders('termb')\n\n\t\t// dofetch* mayAdjustRequest() will automatically\n\t\t// convert to GET query params or POST body, as needed\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\tfor: 'getMultivalueTWs',\n\t\t\tparent_id: opts?.parent_id\n\t\t}\n\t\treturn await this.dofetch3('termdb', { headers, body })\n\t}\n\n\tasync getCohortsData(opts) {\n\t\tconst body = {\n\t\t\tgenome: this.state.vocab.genome,\n\t\t\tdslabel: this.state.vocab.dslabel\n\t\t}\n\t\treturn await this.dofetch3('termdb/cohorts', { body })\n\t}\n\n\tasync getMatrixByName(name) {\n\t\t// find a pre-built matrix by name from this dataset\n\t\treturn await this.dofetch3('termdb', {\n\t\t\tbody: {\n\t\t\t\tfor: 'matrix',\n\t\t\t\tgetPlotDataByName: name,\n\t\t\t\tgenome: this.state.vocab.genome,\n\t\t\t\tdslabel: this.state.vocab.dslabel\n\t\t\t}\n\t\t})\n\t}\n\n\tasync getNumericDictTermClusterByName(name) {\n\t\t// find a pre-built numericDictTermCluster by name from this dataset\n\t\treturn await this.dofetch3('termdb', {\n\t\t\tbody: {\n\t\t\t\tfor: 'numericDictTermCluster',\n\t\t\t\tgetPlotDataByName: name,\n\t\t\t\tgenome: this.state.vocab.genome,\n\t\t\t\tdslabel: this.state.vocab.dslabel\n\t\t\t}\n\t\t})\n\t}\n\n\tasync getTopVariablyExpressedGenes(arg) {\n\t\treturn await this.dofetch3('termdb/topVariablyExpressedGenes', { method: 'GET', body: arg })\n\t}\n\n\tasync getTopTermsByType(args) {\n\t\targs.genome = this.state.vocab.genome\n\t\targs.dslabel = this.state.vocab.dslabel\n\t\tif (args.filter) args.filter = getNormalRoot(args.filter)\n\t\treturn await this.dofetch3('termdb/getTopTermsByType', { method: 'GET', body: args })\n\t}\n\n\tasync getSampleImages(sampleId) {\n\t\tconst args = {}\n\t\targs.genome = this.state.vocab.genome\n\t\targs.dslabel = this.state.vocab.dslabel\n\t\targs.sampleId = sampleId\n\t\treturn await this.dofetch3('termdb/getSampleImages', { method: 'GET', body: args })\n\t}\n\n\t/* \n\t\tsamples[]\t\t\t\t\t!!! CRITICAL: the samples data must not be modified !!!\n\t\t\tsample{} \t\t\t the source sample object, will not be changed directly\n\t\t\t\t[attr.from] any collection of keys from the attributes[] argument\n\n\t\tattributes[]\n\t\t\t.attr{}\n\t\t\t\t.from string, the object to map from, required\n\t\t\t\t.to string, the object to map to, optional\n\t\t\t\t.convert optional step, somehow the caller must know this is needed?\n\t*/\n\tasync convertSampleId(samples, attributes) {\n\t\t// first pass of attributes[] and perform id conversion\n\t\tconst byAttr = new Map()\n\t\tconst bySample = []\n\t\t// !!! do NOT modify the sample object or samples array\n\t\tfor (const sample of samples) {\n\t\t\tconst obj = {}\n\t\t\tbySample.push(obj)\n\t\t\tfor (const attr of attributes) {\n\t\t\t\tif (!('to' in attr)) attr.to = attr.from\n\t\t\t\tif (!attr.convert) {\n\t\t\t\t\t// do not convert, no need for server request\n\t\t\t\t\tmayAssign(obj, attr.to, sample[attr.from])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (sample._ref_?.[attr.to]) {\n\t\t\t\t\t// can convert id using sample ref, no need for server request\n\t\t\t\t\tmayAssign(obj, attr.to, sample._ref_[attr.to])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// this attr requires conversion;\n\t\t\t\t// collect all values from all samples and later call server for each attribute? //once to convert\n\t\t\t\tif (!byAttr.has(attr)) byAttr.set(attr, {})\n\t\t\t\tconst fromValMap = byAttr.get(attr)\n\t\t\t\tconst v = sample[attr.from]\n\t\t\t\tif (!fromValMap[v]) fromValMap[v] = []\n\t\t\t\tfromValMap[v].push({ obj, sample })\n\t\t\t}\n\t\t}\n\n\t\t// perform the required conversion of sample attributes\n\t\tconst promises = []\n\t\tfor (const [attr, fromValMap] of byAttr) {\n\t\t\tconst inputs = Object.keys(fromValMap)\n\t\t\tpromises.push(\n\t\t\t\tawait this.dofetch3('termdb', {\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tfor: 'convertSampleId',\n\t\t\t\t\t\tinputs,\n\t\t\t\t\t\tgenome: this.state.vocab.genome,\n\t\t\t\t\t\tdslabel: this.state.vocab.dslabel\n\t\t\t\t\t}\n\t\t\t\t}).then(r => {\n\t\t\t\t\tfor (const v of inputs) {\n\t\t\t\t\t\tfor (const { sample, obj } of fromValMap[v]) {\n\t\t\t\t\t\t\tmayAssign(obj, attr.to, r.mapping[v])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\tawait Promise.all(promises)\n\n\t\t// return non-empty sample mappings\n\t\treturn bySample.filter(d => Object.keys(d).length)\n\n\t\t// assign sample mapping if not already present in bySample{}\n\t\tfunction mayAssign(obj, key, value) {\n\t\t\tif (!bySample.some(d => d[key] == value)) {\n\t\t\t\tobj[key] = value\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getCorrelationVolcanoData(arg, _body = {}) {\n\t\t// Is this auth needed for this plot??\n\t\tconst headers = await this.mayGetAuthHeaders('termdb')\n\n\t\t//Add more args here (e.g. filter, etc. )\n\t\targ.featureTw = this.getTwMinCopy(arg.featureTw)\n\t\tfor (const tw of arg.variableTwLst) {\n\t\t\tthis.getTwMinCopy(tw)\n\t\t}\n\n\t\tconst body = Object.assign(\n\t\t\t{\n\t\t\t\tgenome: this.vocab.genome,\n\t\t\t\tdslabel: this.vocab.dslabel\n\t\t\t},\n\t\t\targ,\n\t\t\t_body\n\t\t)\n\n\t\tif (body.filter) body.filter = getNormalRoot(body.filter)\n\t\tconst d = await this.dofetch3('termdb/correlationVolcano', { headers, body })\n\n\t\treturn d\n\t}\n\n\tasync filterTermValues(args) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t...args\n\t\t}\n\t\tif (body.filter) body.filter = getNormalRoot(body.filter)\n\t\tif (body.terms) {\n\t\t\tbody.terms = structuredClone(body.terms)\n\t\t\tfor (const tw of body.terms) {\n\t\t\t\tthis.mayStripTwProps(tw)\n\t\t\t}\n\t\t}\n\t\tif (body.facilityTW) this.mayStripTwProps(body.facilityTW)\n\t\treturn await this.dofetch3('termdb/filterTermValues', { body })\n\t}\n\n\tasync getProfileScores(args) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t...args\n\t\t}\n\t\tif (body.filter) body.filter = getNormalRoot(body.filter)\n\t\tbody.facilityTW = structuredClone(body.facilityTW)\n\t\tthis.mayStripTwProps(body.facilityTW)\n\t\tif (body.scoreTerms) {\n\t\t\t// replace with a mutable copy\n\t\t\tbody.scoreTerms = structuredClone(body.scoreTerms)\n\t\t\tfor (const t of body.scoreTerms) {\n\t\t\t\tif (typeof t.maxScore != 'number') this.mayStripTwProps(t.maxScore)\n\t\t\t\tthis.mayStripTwProps(t.score)\n\t\t\t}\n\t\t}\n\t\treturn await this.dofetch3('termdb/profileScores', { body })\n\t}\n\n\tasync getProfileFormScores(args) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t...args\n\t\t}\n\t\tif (body.filter) body.filter = getNormalRoot(body.filter)\n\t\tif (body.terms) {\n\t\t\tfor (const t of body.terms) {\n\t\t\t\tif (t.term.id) t.term = { id: t.term.id }\n\t\t\t}\n\t\t}\n\t\treturn await this.dofetch3('termdb/profileFormScores', { body })\n\t}\n\n\t// strip some tw properties that\n\t// - are not used in the server (relevant to only client-side code),\n\t// - may recovered on the server side such as for dictionary terms\n\tmayStripTwProps(tw) {\n\t\tif (!tw) return\n\t\tdelete tw.type // TODO: may keep this if needed by the backend code\n\t\tdelete tw.isAtomic\n\t\tdelete tw.hiddenValues\n\t\tdelete tw.q.isAtomic\n\t\tdelete tw.q.hiddenValues\n\t\t// the full term object may be sql-queried on the server side,\n\t\t// no need to include the full body in the request payload\n\t\tif (tw.term.id && (!tw.term.type || isDictionaryType(tw.term.type))) tw.term = { id: tw.term.id }\n\t}\n\n\tasync buildAdHocDictionary() {\n\t\tconst body = {\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\tgenome: this.vocab.genome,\n\t\t\tfor: 'buildAdHocDictionary'\n\t\t}\n\t\treturn await this.dofetch3('termdb', { method: 'GET', body })\n\t}\n\n\tasync getFilteredAiImages(project, filter) {\n\t\tconst body = {\n\t\t\tgenome: this.vocab.genome,\n\t\t\tdslabel: this.vocab.dslabel,\n\t\t\t// make a copy of the project object\n\t\t\tproject: Object.assign({}, project, { filter: getNormalRoot(filter) }),\n\t\t\tfor: 'filterImages'\n\t\t}\n\n\t\treturn await this.dofetch3('aiProjectAdmin', { body })\n\t}\n}\n\n/*\nInput:\n tw {\n $id\n term { type }\n }\n lst[]\n each element is annotation object for a sample\n sample: samplename\n [$termid] : {}\n .key\n category key for this category?\n .value\n category label for this category?\n .filteredValues[]\nOutput:\n none\n\nif a term is eligible, modify term object as below:\n- create tw.term.category2samplecount = {categoryKey: count}\n- fill in tw.term.values{}, see below\n*/\nfunction mayFillInCategory2samplecount4term(tw, lst, termdbConfig) {\n\t// define conditions when not to do it\n\tif (tw.term.type != 'categorical') {\n\t\t// for now only do it for categorical term\n\t\treturn\n\t}\n\tif (!('$id' in tw)) {\n\t\t// tw.$id not found\n\t\treturn\n\t}\n\tconst k2c = {} // key: category key, value: sample count annotated to this category\n\tconst k2label = {} // key: category key, value: category label\n\tfor (const s of lst) {\n\t\tif (!s[tw.$id]) continue // sample is not annotated by this term\n\t\tconst categoryKey = s[tw.$id].key\n\t\tk2c[categoryKey] = 1 + (k2c[categoryKey] || 0)\n\t\tk2label[categoryKey] = { key: categoryKey, label: categoryKey }\n\t}\n\ttw.term.category2samplecount = k2c\n\n\t/* one of three conditions on whether to fill tw.term.values{}\n\t- with the flag from termdbConfig, e.g. all gdc categorical terms are with blank \"values{}\" and should be refilled everytime\n\t refilling everytime data is loaded helps with groupsetting changes, when a refill is needed to flush out old settings\n\t e.g. canceling groupsetting\n\t- missing term.values{}\n\t- blank term.values{}\n\t*/\n\tif (termdbConfig?.alwaysRefillCategoricalTermValues || !tw.term.values || Object.keys(tw.term.values).length == 0) {\n\t\ttw.term.values = k2label\n\t}\n}\n\n/*\nfrom input list of termwrappers, get up to \"count\" number of unique tw and return in new list; original lst will be truncated\ncopies cannot contain multiple tw of same term, e.g. matrix can have same age term in two rows as continuous and discrete, having 2 age tw will confuse downstream code of getAnnotatedSampleData()\nduplicating tw will be pushed to the end of lst and are returned one at a time\n*/\nfunction getTerms2update(lst, count) {\n\tconst copies = []\n\tlet i = 0,\n\t\tn = lst.length\n\twhile (i < n) {\n\t\ti++\n\t\tconst _tw = lst.shift() // first of lst[]\n\t\tconst tw = _tw.getMinCopy?.() || _tw\n\t\tif (\n\t\t\tcopies.find(\n\t\t\t\tc =>\n\t\t\t\t\tc.term.type === tw.term.type &&\n\t\t\t\t\t((('id' in c.term || 'id' in tw.term) && c.term.id === tw.term.id) || c.term.name === tw.term.name)\n\t\t\t)\n\t\t) {\n\t\t\t// tw already exists in copies[], do not put into copies[], put it at the end of lst to be processed later\n\t\t\tlst.push(tw)\n\t\t} else {\n\t\t\t// tw is not in copies[], which should only contain up to \"count\" of unique terms\n\t\t\tcopies.push(tw)\n\t\t}\n\t\tif (copies.length >= count) break\n\t}\n\treturn copies\n}\n", "import { getBarchartData, getCategoryData } from '../plots/barchart.data'\nimport { scaleLinear } from 'd3-scale'\nimport { sample_match_termvaluesetting } from '#common/termutils'\nimport { isUsableTerm } from '#shared/termdb.usecase.js'\nimport { isNumeric } from '#shared/helpers.js'\nimport computePercentile from '#shared/compute.percentile.js'\nimport { roundValueAuto } from '#shared/roundValue.js'\nimport { Vocab } from './Vocab'\n\nexport class FrontendVocab extends Vocab {\n\tconstructor(opts) {\n\t\tsuper(opts)\n\t\tthis.datarows = []\n\t\tif (opts.state.vocab.sampleannotation) {\n\t\t\tconst anno = opts.state.vocab.sampleannotation\n\t\t\tObject.keys(anno).forEach(sample => this.datarows.push({ sample, data: anno[sample] }))\n\t\t}\n\t}\n\n\tgetTermdbConfig() {\n\t\treturn { selectCohort: this.vocab.selectCohort, supportedChartTypes: [] }\n\t}\n\n\tgetTermChildren(term, cohortValuelst) {\n\t\tconst cohortValuestr = (cohortValuelst || []).slice().sort().join(',')\n\t\t// TODO: handle treeFilter\n\t\tconst parent_id = term.__tree_isroot ? null : term.id\n\t\treturn {\n\t\t\tlst: this.vocab.terms.filter(\n\t\t\t\tt =>\n\t\t\t\t\tt.parent_id === parent_id &&\n\t\t\t\t\t(!cohortValuestr.length || cohortValuestr === t.cohortValues.slice().sort.join(','))\n\t\t\t)\n\t\t}\n\t}\n\n\t// from termdb/plot\n\tasync getNestedChartSeriesData(opts) {\n\t\tconst q = {\n\t\t\tterm1: opts.term ? opts.term.term : {},\n\t\t\tterm1_q: opts.term ? opts.term.q : undefined,\n\t\t\tterm0: opts.term0 ? opts.term0.term : undefined,\n\t\t\tterm0_q: opts.term0 ? opts.term0.q : undefined,\n\t\t\tterm2: opts.term2 ? opts.term2.term : undefined,\n\t\t\tterm2_q: opts.term2 ? opts.term2.q : undefined,\n\t\t\tfilter: this.state.termfilter && this.state.termfilter.filter\n\t\t}\n\t\treturn getBarchartData(q, this.datarows)\n\t}\n\n\t/*\n May override certain term-related configuration (like bins),\n from the server response data to the corresponding term's \n current state.\n\n Arguments\n config\n - chart configuration object with termwrappers of\n term (required), term0 (optional) and term2 (optional)\n\n - data\n server response data in the format of \n {\n charts: [{\n chartId: '...',\n serieses: [{\n seriesId: '...',\n data: [{\n dataId: '...',\n total: *samplecount*\n }, ...],\n total: *samplecount*\n }, ...],\n total: *samplecount*\n }, ...],\n\n refs: {...}\n }\n */\n\tsyncTermData(config, data, prevConfig = {}) {\n\t\tif (!data || !data.refs) return\n\t\tfor (const [i, key] of ['term0', 'term', 'term2'].entries()) {\n\t\t\tconst term = config[key]\n\t\t\tif (term == 'genotype') return\n\t\t\tif (!term) {\n\t\t\t\tif (key == 'term') throw `missing plot.term{}`\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (data.refs.bins) {\n\t\t\t\tterm.bins = data.refs.bins[i]\n\t\t\t\tif (data.refs.q && data.refs.q[i]) {\n\t\t\t\t\tif (!term.q) term.q = {}\n\t\t\t\t\tconst q = data.refs.q[i]\n\t\t\t\t\tif (q !== term.q) {\n\t\t\t\t\t\tfor (const key in term.q) delete term.q[key]\n\t\t\t\t\t\tObject.assign(term.q, q)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!term.q) term.q = {}\n\t\t}\n\t}\n\n\t// from termdb/search\n\tasync findTerm(str, cohortStr, usecase = null) {\n\t\treturn {\n\t\t\tlst: this.vocab.terms.filter(\n\t\t\t\tt => t.name.includes(str) && (!cohortStr || cohortStr === t.cohortValues.slice().sort.join(','))\n\t\t\t)\n\t\t}\n\t}\n\n\t// from termdb/terminfo\n\tasync getTermInfo(id) {\n\t\tconst term = this.vocab.find(t => t.id === id)\n\t\tif (!term) return undefined\n\t\treturn { terminfo: t.info }\n\t}\n\n\t// from termdb/nav\n\tasync getCohortSampleCount(cohortName) {\n\t\tif (!cohortName) return\n\t\tconst term = this.vocab.find(t => t.id === id)\n\t\tif (!term || !term.cohortValues.includes(cohortName)) return\n\t\tif (!term.samplecount) term.samplecount = {}\n\t\tif (!(cohortName in term.samplecount)) {\n\t\t\tterm.samplecount[cohortName] = Object.keys(this.vocab.sampleannotation).length\n\t\t}\n\t\treturn { samplecount: term.samplecount[cohortName] }\n\t}\n\n\t/*** To-Do ***/\n\n\tasync getCohortsData(opts) {\n\t\treturn null\n\t}\n\n\tasync getFilteredSampleCount(filterJSON) {\n\t\t/*\n\t\tif (!cohortName) return\n\t\tconst term = this.vocab.find(t => t.id === id)\n\t\tif (!term || !term.cohortValues.includes(cohortName)) return\n\t\tif (!term.samplecount) term.samplecount = {}\n\t\tif (!(cohortName in term.samplecount)) {\n\t\t\tterm.samplecount[cohortName] = Object.keys(this.vocab.sampleannotation).length\n\t\t}\n\t\t*/\n\t\treturn 'TBD'\n\t}\n\n\tasync getDensityPlotData(term_id, num_obj, filter) {\n\t\tif (!this.datarows || !this.datarows.length) {\n\t\t\t// support adhoc dictionary or vocab terms without sample annotations\n\t\t\tconst term = this.vocab.terms.find(t => t.id === term_id)\n\t\t\tconst minvalue = term.range && term.range\n\t\t\treturn {\n\t\t\t\tminvalue: term.range && term.range.start,\n\t\t\t\tmaxvalue: term.range && term.range.stop\n\t\t\t}\n\t\t}\n\n\t\tconst values = []\n\t\tconst distinctValues = new Set()\n\t\tlet minvalue,\n\t\t\tmaxvalue,\n\t\t\tsamplecount = 0\n\t\tlet samples = {}\n\t\tfor (const anno of this.datarows) {\n\t\t\tif (samples[anno.sample]) continue\n\t\t\tconst data = anno.s || anno.data\n\t\t\tif (data && sample_match_termvaluesetting(data, filter)) {\n\t\t\t\tsamples[anno.sample] = this.vocab.sampleannotation[anno.sample]\n\t\t\t}\n\t\t}\n\n\t\tfor (const sample in samples) {\n\t\t\tif (!(term_id in this.vocab.sampleannotation[sample])) continue\n\t\t\tconst _v = this.vocab.sampleannotation[sample][term_id]\n\t\t\tif (isNumeric(_v)) {\n\t\t\t\tconst v = +_v\n\t\t\t\tsamplecount += 1\n\t\t\t\tif (minvalue === undefined || v < minvalue) minvalue = v\n\t\t\t\tif (maxvalue === undefined || v > maxvalue) maxvalue = v\n\t\t\t\tvalues.push(v)\n\t\t\t\tdistinctValues.add(v)\n\t\t\t}\n\t\t}\n\n\t\tconst term = this.vocab.terms.find(t => t.id == term_id)\n\t\tconst default_ticks_n = 40\n\t\tconst ticks_n =\n\t\t\tterm.type == 'integer' && maxvalue - minvalue < default_ticks_n\n\t\t\t\t? maxvalue - minvalue\n\t\t\t\t: term.type == 'float' && distinctValues.size < default_ticks_n\n\t\t\t\t? distinctValues\n\t\t\t\t: default_ticks_n\n\t\tconst xscale = scaleLinear()\n\t\t\t.domain([minvalue, maxvalue])\n\t\t\t.range([num_obj.plot_size.xpad, num_obj.plot_size.width - num_obj.plot_size.xpad])\n\t\tconst density = get_histogram(xscale.ticks(ticks_n))(values)\n\n\t\treturn {\n\t\t\tdensity,\n\t\t\tdensitymax: density.reduce((maxv, v, i) => (i === 0 || v[1] > maxv ? v[1] : maxv), 0),\n\t\t\tminvalue,\n\t\t\tmaxvalue,\n\t\t\tsamplecount\n\t\t}\n\t}\n\n\tasync getPercentile(term, percentile_lst, filter) {\n\t\t// for a numeric term, convert a percentile to an actual value, with respect to a given filter\n\t\tif (percentile_lst.find(p => !Number.isInteger(p))) throw 'non-integer percentiles found'\n\t\tif (Math.max(...percentile_lst) > 99 || Math.min(...percentile_lst) < 1) throw 'percentiles must be between 1-99'\n\t\tconst perc_values = []\n\t\tconst values = []\n\t\tconst samples = {}\n\t\tfor (const anno of this.datarows) {\n\t\t\tif (samples[anno.sample]) continue\n\t\t\tconst data = anno.s || anno.data\n\t\t\tif (data && sample_match_termvaluesetting(data, filter)) {\n\t\t\t\tsamples[anno.sample] = this.vocab.sampleannotation[anno.sample]\n\t\t\t}\n\t\t}\n\t\tfor (const sample in samples) {\n\t\t\tif (!(term.id in this.vocab.sampleannotation[sample])) continue\n\t\t\tconst _v = Number(this.vocab.sampleannotation[sample][term.id])\n\t\t\tif (!Number.isFinite(_v)) throw 'non-numeric value'\n\t\t\tvalues.push(_v)\n\t\t}\n\n\t\tvalues.sort((a, b) => a - b)\n\t\tfor (const percentile of percentile_lst) {\n\t\t\tconst perc_value = computePercentile(values, percentile, true)\n\t\t\tperc_values.push(perc_value)\n\t\t}\n\n\t\treturn { values: perc_values }\n\t}\n\n\tasync getDescrStats(term_id, filter, settings) {\n\t\t//TODO add in case for settings?\n\t\t// for a numeric term, get descriptive statistics\n\t\t// mean, median, standard deviation, min, max\n\n\t\tconst values = []\n\t\tconst samples = {}\n\n\t\tfor (const anno of this.datarows) {\n\t\t\tif (samples[anno.sample]) continue\n\t\t\tconst data = anno.s || anno.data\n\t\t\tif (data && sample_match_termvaluesetting(data, filter)) {\n\t\t\t\tsamples[anno.sample] = this.vocab.sampleannotation[anno.sample]\n\t\t\t}\n\t\t}\n\n\t\tfor (const sample in samples) {\n\t\t\tif (!(term_id in this.vocab.sampleannotation[sample])) continue\n\t\t\tconst _v = Number(this.vocab.sampleannotation[sample][term_id])\n\t\t\tif (!Number.isFinite(_v)) throw 'non-numeric value'\n\t\t\tvalues.push(_v)\n\t\t}\n\n\t\treturn computeDescrStats(values)\n\t}\n\n\tasync getTerms(ids, _dslabel = null, _genome = null) {\n\t\tif (!ids) throw 'getTerms: ids missing'\n\t\tif (!Array.isArray(ids)) throw `invalid ids` // should use typescript\n\t\tconst terms = {}\n\t\tfor (const id of ids) {\n\t\t\tconst term = this.vocab.terms.find(t => t.id === id)\n\t\t\tif (term) terms[id] = term\n\t\t}\n\t\treturn terms\n\t}\n\n\tasync getterm(termid) {\n\t\tif (!termid) throw 'getterm: termid missing'\n\t\treturn this.vocab.terms.find(d => d.id == termid)\n\t}\n\n\tasync getCategories(term, filter, lst = null) {\n\t\tconst q = { term, filter }\n\t\tconst data = getCategoryData(q, this.datarows)\n\t\treturn data\n\t}\n\tgetNumericUncomputableCategories(term, filter) {\n\t\tthrow 'to be implemented!! getNumericUncomputableCategories'\n\t}\n\n\tgraphable(term) {\n\t\tif (!term) throw 'graphable: term is missing'\n\t\treturn isUsableTerm(term).has('plot')\n\t}\n\n\tq_to_param(q) {\n\t\t// exclude certain attributes of q from dataName\n\t\tconst q2 = JSON.parse(JSON.stringify(q))\n\t\tdelete q2.hiddenValues\n\t\treturn encodeURIComponent(JSON.stringify(q2))\n\t}\n}\n\nfunction get_histogram(ticks) {\n\treturn values => {\n\t\t// array of {value}\n\t\tconst bins = []\n\t\tfor (let i = 0; i < ticks.length; i++) bins.push([ticks[i], 0])\n\t\tfor (const v of values) {\n\t\t\tfor (let i = 1; i < ticks.length; i++) {\n\t\t\t\tif (v <= ticks[i]) {\n\t\t\t\t\tbins[i - 1][1]++\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn bins\n\t}\n}\n\n// function to compute descriptive statistics for an\n// array of numeric values\nfunction computeDescrStats(values, showOutlierRange = false) {\n\tif (!values.length) {\n\t\t// no values, do not get stats as it breaks code\n\t\t// set result to blank obj to avoid \"missing response.header['content-type']\" err on client\n\t\treturn {}\n\t}\n\n\tif (values.some(v => !Number.isFinite(v))) throw new Error('non-numeric values found')\n\n\t//compute total\n\tconst sorted_arr = values.sort((a, b) => a - b)\n\tconst n = sorted_arr.length\n\n\t//compute median\n\tconst median = computePercentile(sorted_arr, 50, true)\n\t//compute mean\n\tconst mean = getMean(sorted_arr)\n\t// compute variance\n\tconst variance = getVariance(sorted_arr)\n\t// compute standard deviation\n\tconst stdDev = Math.sqrt(variance)\n\n\t//compute percentile ranges\n\tconst p25 = computePercentile(sorted_arr, 25, true)\n\tconst p75 = computePercentile(sorted_arr, 75, true)\n\n\t//compute IQR\n\tconst IQR = p75 - p25\n\tconst min = sorted_arr[0]\n\tconst max = sorted_arr[sorted_arr.length - 1]\n\n\t// Calculate outlier boundaries\n\tconst outlierMin = p25 - 1.5 * IQR //p25 is same as q1\n\tconst outlierMax = p75 + 1.5 * IQR //p75 is same as q3\n\n\tconst stats = {\n\t\ttotal: { label: 'Total', value: n },\n\t\tmin: { label: 'Minimum', value: min },\n\t\tp25: { label: '1st quartile', value: p25 },\n\t\tmedian: { label: 'Median', value: median },\n\t\tp75: { label: '3rd quartile', value: p75 },\n\t\tmax: { label: 'Maximum', value: max },\n\t\tmean: { label: 'Mean', value: mean },\n\t\tstdDev: { label: 'Standard deviation', value: stdDev }\n\t\t//variance: { label: 'Variance', value: variance }, // not necessary to report, as it is just stdDev^2\n\t\t//iqr: { label: 'Inter-quartile range', value: IQR } // not necessary to report, as it is just p75-p25\n\t}\n\n\tif (showOutlierRange) {\n\t\tstats.outlierMin = { label: 'Outlier minimum', value: outlierMin }\n\t\tstats.outlierMax = { label: 'Outlier maximum', value: outlierMax }\n\t}\n\n\tfor (const v of Object.values(stats)) {\n\t\tconst rounded = roundValueAuto(v.value)\n\t\tv.value = rounded\n\t}\n\n\treturn stats\n}\n\nfunction getMean(data) {\n\treturn data.reduce((sum, value) => sum + value, 0) / data.length\n}\n\nfunction getVariance(data) {\n\tconst meanValue = getMean(data)\n\tconst squaredDifferences = data.map(value => Math.pow(value - meanValue, 2))\n\t//Using n\u22121 compensates for the fact that we're basing variance on a sample mean,\n\t// which tends to underestimate true variability. The correction is especially important with small sample sizes,\n\t// where dividing by n would significantly distort the variance estimate.\n\t// For more details see https://en.wikipedia.org/wiki/Bessel%27s_correction\n\treturn squaredDifferences.reduce((sum, value) => sum + value, 0) / (data.length - 1)\n}\n", "import initBinConfig from '#shared/termdb.initbinconfig.js'\nimport { TermdbVocab } from './TermdbVocab'\nimport { FrontendVocab } from './FrontendVocab'\nimport { isNumeric } from '#shared/helpers.js'\nimport { SINGLECELL_GENE_EXPRESSION } from '#shared/terms.js'\n\nexport function vocabInit(opts) {\n\t/*** start legacy support for state.genome, .dslabel ***/\n\tif (opts.vocab && !opts.state) {\n\t\topts.state = { vocab: opts.vocab }\n\t}\n\tif (!opts.state) throw 'missing opts.state'\n\tif (!opts.state.vocab) {\n\t\topts.state.vocab = opts.vocab ? opts.vocab : {}\n\t}\n\tconst vocab = opts.state.vocab\n\tif (opts.state.genome) {\n\t\tvocab.genome = opts.state.genome\n\t\tdelete opts.state.genome\n\t}\n\tif (opts.state.dslabel) {\n\t\tvocab.dslabel = opts.state.dslabel\n\t\tdelete opts.state.dslabel\n\t}\n\t/*** end legacy support ***/\n\n\tif (vocab.dslabel) {\n\t\t//const { TermdbVocab } = await import('./TermdbVocab')\n\t\treturn new TermdbVocab(opts)\n\t} else if (vocab.terms) {\n\t\t//const { FrontendVocab } = await import('./FrontendVocab')\n\t\tconst vocabApi = new FrontendVocab(opts)\n\t\treturn vocabApi\n\t} else {\n\t\tthrow `unable to initialize vocabApi`\n\t}\n}\n\nexport function q_to_param(q) {\n\t// exclude certain attributes of q from dataName\n\tconst q2 = JSON.parse(JSON.stringify(q))\n\tdelete q2.hiddenValues\n\treturn encodeURIComponent(JSON.stringify(q2))\n}\n\n// to-do\n// class Mds3Vocab {}\n\nexport function getVocabFromSamplesArray({ samples, sample_attributes }) {\n\tconst terms = {\n\t\t__root: {\n\t\t\tid: 'root',\n\t\t\tname: 'root',\n\t\t\t__tree_isroot: true\n\t\t}\n\t}\n\tconst sanno = {}\n\tfor (const a of samples) {\n\t\tconst s = a.sample\n\t\tif (!sanno[s]) sanno[s] = {}\n\t\t// in case a sample has more than one annotation object in the array\n\t\tObject.assign(sanno[s], a.s)\n\n\t\t// generate term definitions from\n\t\tfor (const key in a.s) {\n\t\t\tif (!terms[key]) {\n\t\t\t\tconst name = sample_attributes[key] && sample_attributes[key].label ? sample_attributes[key].label : key\n\t\t\t\tterms[key] = {\n\t\t\t\t\tid: key,\n\t\t\t\t\tname,\n\t\t\t\t\tparent_id: null,\n\t\t\t\t\ttype:\n\t\t\t\t\t\tsample_attributes[key].type == 'float'\n\t\t\t\t\t\t\t? 'float'\n\t\t\t\t\t\t\t: sample_attributes[key].type == 'integer'\n\t\t\t\t\t\t\t? 'integer'\n\t\t\t\t\t\t\t: // need to work with the cloud/PROPEL team to define type for legacy scatterplot usage\n\t\t\t\t\t\t\t 'categorical',\n\t\t\t\t\tvalues: {},\n\t\t\t\t\tisleaf: true\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst t = terms[key]\n\t\t\tif (!('id' in t)) t.id = key\n\t\t\tif (!('parent_id' in t)) t.parent_id = null\n\t\t\tif (!('values' in t)) t.values = {}\n\t\t\tif (!('isleaf' in t)) t.isleaf = true\n\t\t\tif (!t.computableVals && (t.type == 'float' || t.type == 'integer')) {\n\t\t\t\tt.computableVals = [] // will be used to initialize binconfig for numeric terms\n\t\t\t}\n\n\t\t\tconst value = a.s[key]\n\t\t\tif (t.type == 'categorical') {\n\t\t\t\tt.groupsetting = { disabled: true }\n\t\t\t\tif (!(value in t.values)) {\n\t\t\t\t\tt.values[value] = { key: value, label: value }\n\t\t\t\t}\n\t\t\t} else if (t.type == 'integer' || t.type == 'float') {\n\t\t\t\t// may need to auto-detect more string values that\n\t\t\t\t// can be assumed to be non-numeric here, like \"N/A\"\n\t\t\t\tif (value === 'Not Available' && !(value in t.values)) {\n\t\t\t\t\tt.values[value] = { label: value, uncomputable: true }\n\t\t\t\t}\n\t\t\t\tif (!(value in t.values)) {\n\t\t\t\t\tif (!isNumeric(a.s[key])) throw `non-numeric term value='${value}' for term='${key}'`\n\t\t\t\t\ta.s[key] = Number(a.s[key])\n\t\t\t\t\tconst val = a.s[key]\n\t\t\t\t\tt.computableVals.push(val)\n\t\t\t\t}\n\t\t\t} else if (t.type == 'condition') {\n\t\t\t\t//TODO: add logic for conditional terms\n\t\t\t} else if (t.type == SINGLECELL_GENE_EXPRESSION) {\n\t\t\t\t//TODO: add logic for conditional terms\n\t\t\t} else {\n\t\t\t\tthrow 'Term type not supported:' + t.type\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const key in terms) {\n\t\tconst t = terms[key]\n\t\tif ((t.type == 'integer' || t.type == 'float') && !t.bins) {\n\t\t\tt.bins = {\n\t\t\t\tdefault: initBinConfig(t.computableVals)\n\t\t\t}\n\t\t\tdelete t.computableVals\n\t\t}\n\t}\n\n\treturn {\n\t\tsampleannotation: sanno,\n\t\tterms: Object.values(terms)\n\t}\n}\n", "import { setRenderers } from './filter.renderer'\nimport { setInteractivity } from './filter.interactivity'\nimport { findItem, findParent, getFilterItemByTag, getNormalRoot, filterJoin } from './filter.utils'\nimport { vocabInit } from '#termdb/vocabulary'\nimport { Menu } from '#dom/menu'\nimport { deepEqual, deepFreeze } from '#rx'\n\nconst defaults = deepFreeze({\n\tjoinWith: ['and', 'or']\n})\n\n/*\n\topts{}\n\t.holder\n\t\n\t.callback()\n\t\tWhen a filter change (add, edit, remove) is made,\n\t\tthe callback will receive the updated visible filter\n\t\tas argument\n\t\n\t.emptyLabel \"+NEW\"\n\t\toptions to use a different label for the\n\t\tbutton or prompt to add the \n\t\tfirst user-configurable filter item\n\n\t.header_mode (e.g. 'hide_search')\n\t\toptional setting for header of tree menu\n\t\twill be supplied to termdb app state in filter.interactivity.js\n\n\t.isMafFilter (boolean)\n\t\twhether the filter is a MAF filter, in which case the tvs UI will\n\t\tinclude an additional input for allelic depth (see \"tvs.numeric.js\")\n\n\tCoding convenience:\n\t- use $id for data binding to match \n\t existing DOM elements with the corresponding\n\t data update\n\t- use ':scope > .cls' to limit a selection\n\t\tto immediate children -- important since the data\n\t\tat the current nesting level must not be bound to \n\t\tnon-child elements with the same classnames\n*/\n\n// filter it should increment across all filter instances\n// let id=0\n\nexport class Filter {\n\tconstructor(opts) {\n\t\tthis.opts = this.validateOpts(opts)\n\n\t\tconst parent_menu = this.opts.holder.node()?.closest('.sja_menu_div')\n\n\t\tconst controlsTip = new Menu({\n\t\t\tpadding: '0px',\n\t\t\tparent_menu\n\t\t})\n\n\t\tthis.dom = {\n\t\t\tholder: opts.holder,\n\t\t\tcontrolsTip,\n\t\t\ttreeTip: new Menu({\n\t\t\t\tpadding: '5px',\n\t\t\t\toffsetX: 20,\n\t\t\t\toffsetY: -34,\n\t\t\t\tclearSelector: '.sja_term_src_body',\n\t\t\t\tparent_menu: controlsTip.d.node(),\n\t\t\t\tancestor_menus: [parent_menu]\n\t\t\t})\n\t\t}\n\t\tthis.durations = { exit: 500 }\n\t\tthis.lastId = 0 //id++\n\t\tthis.categoryData = {}\n\t\tthis.pills = {}\n\t\tsetInteractivity(this)\n\t\tsetRenderers(this)\n\t\tthis.initUI()\n\n\t\t// default empty filter, in case this.api.main() is not called\n\t\t// in app-less initialization\n\t\tthis.filter = {\n\t\t\ttype: 'tvslst',\n\t\t\ttag: 'filterUiRoot',\n\t\t\tjoin: 'and',\n\t\t\tin: true,\n\t\t\tlst: []\n\t\t}\n\t\tthis.promises = {}\n\t}\n\n\tvalidateOpts(opts) {\n\t\tconst o = Object.assign({}, defaults, opts)\n\t\tif (!o.holder) throw '.holder missing'\n\n\t\tif (o.vocabApi) {\n\t\t\tthis.vocabApi = o.vocabApi\n\t\t} else {\n\t\t\tif (!o.vocab) throw '.vocab missing'\n\n\t\t\tif (o.vocab.dslabel) {\n\t\t\t\tif (!o.vocab.genome) throw 'vocab.genome missing'\n\t\t\t} else {\n\t\t\t\tif (!o.vocab.terms) throw 'vocab.terms missing'\n\t\t\t}\n\t\t}\n\n\t\tif (typeof o.callback != 'function') throw '.callback() is not a function'\n\t\tif (o.getVisibleRoot && typeof o.getVisibleRoot != 'function')\n\t\t\tthrow '.getVisibleRoot() must be a function if set as an option'\n\t\tif (!o.emptyLabel) o.emptyLabel = '+NEW'\n\t\t// o.getCategoriesArguments is not validated and simply passed to tree UI then tvs\n\t\treturn o\n\t}\n\n\t/*\n\t\trawCopy'' JSON-stringified rawFilter object\n\t\topts{}\n\t\t.activeCohort\n\t*/\n\tasync main(rawCopy, opts = {}) {\n\t\t// replace the postRender promise ASAP to ensure that listeners\n\t\t// will not get a stale promise from a previous render\n\t\t// TODO: can move setting a postRender promise to rx?\n\t\tthis.promises.postRender = new Promise((resolve, reject) => {\n\t\t\tthis.mainResolve = resolve\n\t\t\tthis.mainReject = reject\n\t\t})\n\t\tthis.numProcessedItems = 0\n\t\tthis.numExpectedItems = 0\n\n\t\tthis.opts = Object.assign({}, this.opts, opts)\n\t\tthis.activeCohort = this.opts.activeCohort\n\t\tthis.rawCopy = rawCopy\n\t\tthis.rawFilter = JSON.parse(this.rawCopy)\n\t\tthis.validateFilter(this.rawFilter)\n\t\tthis.filter = getFilterItemByTag(this.rawFilter, 'filterUiRoot')\n\t\tif (!this.filter) {\n\t\t\tthis.filter = this.rawFilter\n\t\t\tthis.filter.tag = 'filterUiRoot'\n\t\t}\n\t\tawait this.resetActiveData(this.filter)\n\n\t\t// reset interaction-related styling\n\t\tthis.removeBlankPill()\n\t\tthis.dom.newBtn.style('display', this.opts.newBtn ? '' : this.filter.lst.length == 0 ? 'inline-block' : 'none')\n\t\tthis.dom.holder.selectAll('.sja_filter_add_transformer').style('display', this.getAddTransformerBtnDisplay)\n\t\t//this.dom.filterContainer.selectAll('.sja_filter_grp').style('background-color', 'transparent')\n\t\tthis.setVocabApi()\n\t\tthis.updateUI(this.dom.filterContainer, this.filter)\n\t\treturn this.promises.postRender\n\t}\n\n\tvalidateFilter(item) {\n\t\t// for reliably binding data to DOM elements\n\t\t// and associating updated data copy to\n\t\t// the currently bound data\n\t\tif (!('$id' in item)) item.$id = this.lastId++\n\t\telse if (this.lastId <= item.$id) this.lastId = item.$id + 1\n\n\t\tif (!('type' in item)) throw 'missing filter.type'\n\t\tif (item.type != 'tvs' && item.type != 'tvslst') throw 'invalid filter.type'\n\t\t//if (!('visibility' in item)) item.visibility = 'default'\n\t\t//if (!['default', 'collapsed', 'hidden'].includes(item.visibility)) throw 'invalid filter.visibility value'\n\n\t\tif (item.type != 'tvslst') return\n\t\tif (!Array.isArray(item.lst)) throw 'invalid or missing filter.lst[]'\n\t\tif (item.lst.length > 1) {\n\t\t\tif (item.join != 'and' && item.join != 'or') throw 'invalid filter.join value for lst.length > 1'\n\t\t} else if (item.join !== '') {\n\t\t\tthrow 'filter.join must be an empty string when lst.length < 2'\n\t\t}\n\t\tif (!item.lst.length) item.in = true\n\t\tfor (const [i, subitem] of item.lst.entries()) {\n\t\t\tthis.validateFilter(subitem)\n\t\t}\n\t}\n\tresetActiveData(filter) {\n\t\t// clear menu click\n\t\tif (this.dom.controlsTip.d.style('display') == 'none') {\n\t\t\tthis.activeData = { item: {}, filter: {} }\n\t\t} else {\n\t\t\tthis.activeData = {\n\t\t\t\titem: findItem(filter, this.activeData.item.$id),\n\t\t\t\tfilter: findItem(filter, this.activeData.filter.$id),\n\t\t\t\tmenuOpt: this.activeData.menuOpt\n\t\t\t}\n\t\t}\n\t}\n\trefresh(filterUiRoot) {\n\t\tthis.dom.controlsTip.hide()\n\t\tthis.dom.treeTip.hide()\n\t\tconst rootCopy = JSON.parse(JSON.stringify(this.rawFilter))\n\t\tdelete rootCopy.tag\n\t\tfilterUiRoot.tag = 'filterUiRoot'\n\t\tconst rawParent = findParent(rootCopy, this.filter.$id)\n\t\tif (!rawParent || this.rawFilter.$id === this.filter.$id) {\n\t\t\tthis.api.main(filterUiRoot)\n\t\t\tthis.opts.callback(filterUiRoot)\n\t\t} else {\n\t\t\tconst i = rawParent.lst.findIndex(f => f.$id == this.filter.$id)\n\t\t\trawParent.lst[i] = filterUiRoot\n\t\t\tthis.api.main(rootCopy)\n\t\t\tthis.opts.callback(filterUiRoot)\n\t\t}\n\t}\n\tgetId(item) {\n\t\treturn item.$id\n\t}\n\t// The method below is used to get correct categories + sample counts in the pill edit menu,\n\t// so that all values of the pill term, including filtered-out values, will still show up\n\t// as checkbox inputs/range option. The other filter data entries will still be applied.\n\tgetFilterExcludingPill($id) {\n\t\tconst rootCopy = JSON.parse(JSON.stringify(this.rawFilter))\n\t\tconst parentCopy = findParent(rootCopy, $id)\n\t\tconst i = parentCopy.lst.findIndex(f => f.$id === $id)\n\t\tif (i == -1) return null\n\t\tparentCopy.lst.splice(i, 1)\n\t\tif (parentCopy.lst.length < 2) parentCopy.join = ''\n\t\tconst globalFilter = this.state?.globalFilter || this.app?.getState().termfilter?.filter\n\t\tif (!globalFilter) return rootCopy\n\t\t// detect if the rawFilter is equivalent to the global filter\n\t\tif (deepEqual(getNormalRoot(this.rawFilter), getNormalRoot(globalFilter))) return rootCopy\n\t\t// the rawFilter must be a local (plot) filter\n\t\treturn getNormalRoot(filterJoin([rootCopy, globalFilter]))\n\t\t/*\n\t\t!!! \n\t\t\tThe logic below incorectly assumes that there are at most 2 root tvslst.lst entries,\n\t\t\ta cohortFilter, ONE OTHER, or both\n\t\t\t- this is mostly true for a global filter\n\t\t\t- however, a local chart filter may have 3+ entries in its root tvslst: \n\t\t\t a cohortFilter tvs, aterm filter tvslst, AND the local filter tvslst\n\t\t!!!\n\t\tconst cohortFilter = getFilterItemByTag(rootCopy, 'cohortFilter')\n\t\tif (cohortFilter && !parentCopy.lst.find(d => d === cohortFilter)) {\n\t\t\treturn getNormalRoot({\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tjoin: 'and',\n\t\t\t\tlst: [cohortFilter, parentCopy]\n\t\t\t})\n\t\t} else {\n\t\t\treturn getNormalRoot(parentCopy)\n\t\t}\n\t\t*/\n\t}\n\n\tgetAdjustedRoot($id, join) {\n\t\tconst rootCopy = JSON.parse(JSON.stringify(this.rawFilter))\n\n\t\tif (join == 'and') return rootCopy\n\n\t\t// join should be \"or\"\n\n\t\t// first find the optional cohortFilter, as it's used at multiple placed below\n\t\tconst cohortFilter = getFilterItemByTag(rootCopy, 'cohortFilter')\n\n\t\tconst parentCopy = findParent(rootCopy, $id)\n\t\tif (!parentCopy) {\n\t\t\t// if cohortFilter is present, must return it; otherwise return blank filter\n\t\t\treturn { type: 'tvslst', in: true, join: 'and', lst: cohortFilter ? [cohortFilter] : [] }\n\t\t}\n\n\t\tconst i = parentCopy.lst.findIndex(f => f.$id === parentCopy.$id)\n\t\tif (i == -1) return { type: 'tvslst', in: true, join: 'and', lst: cohortFilter ? [cohortFilter] : [] }\n\n\t\tparentCopy.lst.splice(i, 1)\n\t\tif (cohortFilter && !parentCopy.lst.find(d => d === cohortFilter)) {\n\t\t\treturn getNormalRoot({\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tjoin: 'and',\n\t\t\t\tlst: [cohortFilter, parentCopy]\n\t\t\t})\n\t\t}\n\n\t\treturn getNormalRoot(parentCopy)\n\t}\n\n\tsetVocabApi() {\n\t\tif (!this.vocabApi) {\n\t\t\tconst app = {\n\t\t\t\tgetState: () => {\n\t\t\t\t\tconst filter = JSON.parse(this.rawCopy)\n\t\t\t\t\tconst cohortFilter = getFilterItemByTag(filter, 'cohortFilter')\n\t\t\t\t\tif (cohortFilter && this.opts.termdbConfig) {\n\t\t\t\t\t\tcohortFilter.tvs.values =\n\t\t\t\t\t\t\tthis.activeCohort == -1 || this.activeCohort === undefined\n\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t: this.opts.termdbConfig.selectCohort.values[this.activeCohort].keys.map(key => {\n\t\t\t\t\t\t\t\t\t\treturn { key, label: key }\n\t\t\t\t\t\t\t\t })\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvocab: this.opts.vocab,\n\t\t\t\t\t\ttermfilter: { filter },\n\t\t\t\t\t\ttree: { plots: {} }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst state = app.getState()\n\t\t\tconst vocab = state.vocab || {\n\t\t\t\tgenome: state.genome,\n\t\t\t\tdslabel: state.dslabel\n\t\t\t}\n\t\t\tif (!this.vocabApi) {\n\t\t\t\tthis.vocabApi = vocabInit({\n\t\t\t\t\tapp,\n\t\t\t\t\tstate: { vocab }\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tthis.vocabApi.main()\n\t}\n\tupdatePromise = function (incr = 1) {\n\t\tif (!this.mainResolve) return\n\t\tthis.numProcessedItems += incr\n\t\tif (this.numExpectedItems == this.numProcessedItems) {\n\t\t\tthis.mainResolve()\n\t\t\tif (this.bus) this.bus.emit('postRender')\n\t\t\tdelete this.mainResolve\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tthis.dom.holder.remove()\n\t\tthis.dom.controlsTip.destroy()\n\t\tthis.dom.treeTip.destroy()\n\t}\n}\n", "import { getInitFxn, Bus } from '#rx'\nimport { Filter } from './FilterClass'\nimport { getNormalRoot } from './filter.utils'\n\n// use this in a non-rx-based apps,\n// and for simple filter data shapes where there are no tags like filterUiRoot\nclass FilterStateless extends Filter {\n\tconstructor(opts) {\n\t\tsuper(opts)\n\t\tthis.api = {\n\t\t\t// make sure to bind the 'this' context to the filter instance\n\t\t\t// instead of to the this.api object\n\t\t\tmain: this.main.bind(this),\n\t\t\t/*\n\t\t\t\tWARNING!!!\n\t\t\t\tWhen using this filter.api.getNormalRoot(),\n\t\t\t\tmake sure this instance has been updated before the caller,\n\t\t\t\totherwise the normalized root will be stale\n\n\t\t\t\tor for reliability, import getNormalRoot() directly \n\t\t\t\tfrom the common/filter.js component and supply the \n\t\t\t\tcaller's known raw filter state\n\t\t\t*/\n\t\t\tgetNormalRoot: () => getNormalRoot(this.rawFilter),\n\t\t\tgetPromise: name => this.promises[name],\n\t\t\tdestroy: () => this.destroy()\n\t\t}\n\n\t\tif (opts.callbacks) {\n\t\t\tthis.events = ['postInit', 'postRender', 'firstRender']\n\t\t\tthis.bus = new Bus(this.api, this.events, opts.callbacks)\n\t\t}\n\t}\n\n\tasync main(rawFilter, opts = {}) {\n\t\tthis.dom.controlsTip.hide()\n\t\tthis.dom.treeTip.hide()\n\t\tconst activeCohort = 'activeCohort' in opts ? opts.activeCohort : this.activeCohort\n\t\tconst rawCopy = JSON.stringify(rawFilter)\n\t\t// if the filter data and active cohort has not changed, do not trigger a re-render\n\t\tif (this.rawCopy == rawCopy && JSON.stringify(this.activeCohort) == JSON.stringify(activeCohort)) return\n\t\tawait super.main(rawCopy, opts)\n\t}\n}\n\nexport const filterInit = getInitFxn(FilterStateless)\n", "import type { Options } from './types'\n\nexport function resolveUrl(url: string, baseUrl: string | null): string {\n // url is absolute already\n if (url.match(/^[a-z]+:\\/\\//i)) {\n return url\n }\n\n // url is absolute already, without protocol\n if (url.match(/^\\/\\//)) {\n return window.location.protocol + url\n }\n\n // dataURI, mailto:, tel:, etc.\n if (url.match(/^[a-z]+:/i)) {\n return url\n }\n\n const doc = document.implementation.createHTMLDocument()\n const base = doc.createElement('base')\n const a = doc.createElement('a')\n\n doc.head.appendChild(base)\n doc.body.appendChild(a)\n\n if (baseUrl) {\n base.href = baseUrl\n }\n\n a.href = url\n\n return a.href\n}\n\nexport const uuid = (() => {\n // generate uuid for className of pseudo elements.\n // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.\n let counter = 0\n\n // ref: http://stackoverflow.com/a/6248722/2519373\n const random = () =>\n // eslint-disable-next-line no-bitwise\n `0000${((Math.random() * 36 ** 4) << 0).toString(36)}`.slice(-4)\n\n return () => {\n counter += 1\n return `u${random()}${counter}`\n }\n})()\n\nexport function delay<T>(ms: number) {\n return (args: T) =>\n new Promise<T>((resolve) => {\n setTimeout(() => resolve(args), ms)\n })\n}\n\nexport function toArray<T>(arrayLike: any): T[] {\n const arr: T[] = []\n\n for (let i = 0, l = arrayLike.length; i < l; i++) {\n arr.push(arrayLike[i])\n }\n\n return arr\n}\n\nlet styleProps: string[] | null = null\nexport function getStyleProperties(options: Options = {}): string[] {\n if (styleProps) {\n return styleProps\n }\n\n if (options.includeStyleProperties) {\n styleProps = options.includeStyleProperties\n return styleProps\n }\n\n styleProps = toArray(window.getComputedStyle(document.documentElement))\n\n return styleProps\n}\n\nfunction px(node: HTMLElement, styleProperty: string) {\n const win = node.ownerDocument.defaultView || window\n const val = win.getComputedStyle(node).getPropertyValue(styleProperty)\n return val ? parseFloat(val.replace('px', '')) : 0\n}\n\nfunction getNodeWidth(node: HTMLElement) {\n const leftBorder = px(node, 'border-left-width')\n const rightBorder = px(node, 'border-right-width')\n return node.clientWidth + leftBorder + rightBorder\n}\n\nfunction getNodeHeight(node: HTMLElement) {\n const topBorder = px(node, 'border-top-width')\n const bottomBorder = px(node, 'border-bottom-width')\n return node.clientHeight + topBorder + bottomBorder\n}\n\nexport function getImageSize(targetNode: HTMLElement, options: Options = {}) {\n const width = options.width || getNodeWidth(targetNode)\n const height = options.height || getNodeHeight(targetNode)\n\n return { width, height }\n}\n\nexport function getPixelRatio() {\n let ratio\n\n let FINAL_PROCESS\n try {\n FINAL_PROCESS = process\n } catch (e) {\n // pass\n }\n\n const val =\n FINAL_PROCESS && FINAL_PROCESS.env\n ? FINAL_PROCESS.env.devicePixelRatio\n : null\n if (val) {\n ratio = parseInt(val, 10)\n if (Number.isNaN(ratio)) {\n ratio = 1\n }\n }\n return ratio || window.devicePixelRatio || 1\n}\n\n// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size\nconst canvasDimensionLimit = 16384\n\nexport function checkCanvasDimensions(canvas: HTMLCanvasElement) {\n if (\n canvas.width > canvasDimensionLimit ||\n canvas.height > canvasDimensionLimit\n ) {\n if (\n canvas.width > canvasDimensionLimit &&\n canvas.height > canvasDimensionLimit\n ) {\n if (canvas.width > canvas.height) {\n canvas.height *= canvasDimensionLimit / canvas.width\n canvas.width = canvasDimensionLimit\n } else {\n canvas.width *= canvasDimensionLimit / canvas.height\n canvas.height = canvasDimensionLimit\n }\n } else if (canvas.width > canvasDimensionLimit) {\n canvas.height *= canvasDimensionLimit / canvas.width\n canvas.width = canvasDimensionLimit\n } else {\n canvas.width *= canvasDimensionLimit / canvas.height\n canvas.height = canvasDimensionLimit\n }\n }\n}\n\nexport function canvasToBlob(\n canvas: HTMLCanvasElement,\n options: Options = {},\n): Promise<Blob | null> {\n if (canvas.toBlob) {\n return new Promise((resolve) => {\n canvas.toBlob(\n resolve,\n options.type ? options.type : 'image/png',\n options.quality ? options.quality : 1,\n )\n })\n }\n\n return new Promise((resolve) => {\n const binaryString = window.atob(\n canvas\n .toDataURL(\n options.type ? options.type : undefined,\n options.quality ? options.quality : undefined,\n )\n .split(',')[1],\n )\n const len = binaryString.length\n const binaryArray = new Uint8Array(len)\n\n for (let i = 0; i < len; i += 1) {\n binaryArray[i] = binaryString.charCodeAt(i)\n }\n\n resolve(\n new Blob([binaryArray], {\n type: options.type ? options.type : 'image/png',\n }),\n )\n })\n}\n\nexport function createImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n img.onload = () => {\n img.decode().then(() => {\n requestAnimationFrame(() => resolve(img))\n })\n }\n img.onerror = reject\n img.crossOrigin = 'anonymous'\n img.decoding = 'async'\n img.src = url\n })\n}\n\nexport async function svgToDataURL(svg: SVGElement): Promise<string> {\n return Promise.resolve()\n .then(() => new XMLSerializer().serializeToString(svg))\n .then(encodeURIComponent)\n .then((html) => `data:image/svg+xml;charset=utf-8,${html}`)\n}\n\nexport async function nodeToDataURL(\n node: HTMLElement,\n width: number,\n height: number,\n): Promise<string> {\n const xmlns = 'http://www.w3.org/2000/svg'\n const svg = document.createElementNS(xmlns, 'svg')\n const foreignObject = document.createElementNS(xmlns, 'foreignObject')\n\n svg.setAttribute('width', `${width}`)\n svg.setAttribute('height', `${height}`)\n svg.setAttribute('viewBox', `0 0 ${width} ${height}`)\n\n foreignObject.setAttribute('width', '100%')\n foreignObject.setAttribute('height', '100%')\n foreignObject.setAttribute('x', '0')\n foreignObject.setAttribute('y', '0')\n foreignObject.setAttribute('externalResourcesRequired', 'true')\n\n svg.appendChild(foreignObject)\n foreignObject.appendChild(node)\n return svgToDataURL(svg)\n}\n\nexport const isInstanceOfElement = <\n T extends typeof Element | typeof HTMLElement | typeof SVGImageElement,\n>(\n node: Element | HTMLElement | SVGImageElement,\n instance: T,\n): node is T['prototype'] => {\n if (node instanceof instance) return true\n\n const nodePrototype = Object.getPrototypeOf(node)\n\n if (nodePrototype === null) return false\n\n return (\n nodePrototype.constructor.name === instance.name ||\n isInstanceOfElement(nodePrototype, instance)\n )\n}\n", "import type { Options } from './types'\nimport { uuid, getStyleProperties } from './util'\n\ntype Pseudo = ':before' | ':after'\n\nfunction formatCSSText(style: CSSStyleDeclaration) {\n const content = style.getPropertyValue('content')\n return `${style.cssText} content: '${content.replace(/'|\"/g, '')}';`\n}\n\nfunction formatCSSProperties(style: CSSStyleDeclaration, options: Options) {\n return getStyleProperties(options)\n .map((name) => {\n const value = style.getPropertyValue(name)\n const priority = style.getPropertyPriority(name)\n\n return `${name}: ${value}${priority ? ' !important' : ''};`\n })\n .join(' ')\n}\n\nfunction getPseudoElementStyle(\n className: string,\n pseudo: Pseudo,\n style: CSSStyleDeclaration,\n options: Options,\n): Text {\n const selector = `.${className}:${pseudo}`\n const cssText = style.cssText\n ? formatCSSText(style)\n : formatCSSProperties(style, options)\n\n return document.createTextNode(`${selector}{${cssText}}`)\n}\n\nfunction clonePseudoElement<T extends HTMLElement>(\n nativeNode: T,\n clonedNode: T,\n pseudo: Pseudo,\n options: Options,\n) {\n const style = window.getComputedStyle(nativeNode, pseudo)\n const content = style.getPropertyValue('content')\n if (content === '' || content === 'none') {\n return\n }\n\n const className = uuid()\n try {\n clonedNode.className = `${clonedNode.className} ${className}`\n } catch (err) {\n return\n }\n\n const styleElement = document.createElement('style')\n styleElement.appendChild(\n getPseudoElementStyle(className, pseudo, style, options),\n )\n clonedNode.appendChild(styleElement)\n}\n\nexport function clonePseudoElements<T extends HTMLElement>(\n nativeNode: T,\n clonedNode: T,\n options: Options,\n) {\n clonePseudoElement(nativeNode, clonedNode, ':before', options)\n clonePseudoElement(nativeNode, clonedNode, ':after', options)\n}\n", "const WOFF = 'application/font-woff'\nconst JPEG = 'image/jpeg'\nconst mimes: { [key: string]: string } = {\n woff: WOFF,\n woff2: WOFF,\n ttf: 'application/font-truetype',\n eot: 'application/vnd.ms-fontobject',\n png: 'image/png',\n jpg: JPEG,\n jpeg: JPEG,\n gif: 'image/gif',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n}\n\nfunction getExtension(url: string): string {\n const match = /\\.([^./]*?)$/g.exec(url)\n return match ? match[1] : ''\n}\n\nexport function getMimeType(url: string): string {\n const extension = getExtension(url).toLowerCase()\n return mimes[extension] || ''\n}\n", "import { Options } from './types'\n\nfunction getContentFromDataUrl(dataURL: string) {\n return dataURL.split(/,/)[1]\n}\n\nexport function isDataUrl(url: string) {\n return url.search(/^(data:)/) !== -1\n}\n\nexport function makeDataUrl(content: string, mimeType: string) {\n return `data:${mimeType};base64,${content}`\n}\n\nexport async function fetchAsDataURL<T>(\n url: string,\n init: RequestInit | undefined,\n process: (data: { result: string; res: Response }) => T,\n): Promise<T> {\n const res = await fetch(url, init)\n if (res.status === 404) {\n throw new Error(`Resource \"${res.url}\" not found`)\n }\n const blob = await res.blob()\n return new Promise<T>((resolve, reject) => {\n const reader = new FileReader()\n reader.onerror = reject\n reader.onloadend = () => {\n try {\n resolve(process({ res, result: reader.result as string }))\n } catch (error) {\n reject(error)\n }\n }\n\n reader.readAsDataURL(blob)\n })\n}\n\nconst cache: { [url: string]: string } = {}\n\nfunction getCacheKey(\n url: string,\n contentType: string | undefined,\n includeQueryParams: boolean | undefined,\n) {\n let key = url.replace(/\\?.*/, '')\n\n if (includeQueryParams) {\n key = url\n }\n\n // font resource\n if (/ttf|otf|eot|woff2?/i.test(key)) {\n key = key.replace(/.*\\//, '')\n }\n\n return contentType ? `[${contentType}]${key}` : key\n}\n\nexport async function resourceToDataURL(\n resourceUrl: string,\n contentType: string | undefined,\n options: Options,\n) {\n const cacheKey = getCacheKey(\n resourceUrl,\n contentType,\n options.includeQueryParams,\n )\n\n if (cache[cacheKey] != null) {\n return cache[cacheKey]\n }\n\n // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n if (options.cacheBust) {\n // eslint-disable-next-line no-param-reassign\n resourceUrl += (/\\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime()\n }\n\n let dataURL: string\n try {\n const content = await fetchAsDataURL(\n resourceUrl,\n options.fetchRequestInit,\n ({ res, result }) => {\n if (!contentType) {\n // eslint-disable-next-line no-param-reassign\n contentType = res.headers.get('Content-Type') || ''\n }\n return getContentFromDataUrl(result)\n },\n )\n dataURL = makeDataUrl(content, contentType!)\n } catch (error) {\n dataURL = options.imagePlaceholder || ''\n\n let msg = `Failed to fetch resource: ${resourceUrl}`\n if (error) {\n msg = typeof error === 'string' ? error : error.message\n }\n\n if (msg) {\n console.warn(msg)\n }\n }\n\n cache[cacheKey] = dataURL\n return dataURL\n}\n", "import type { Options } from './types'\nimport { clonePseudoElements } from './clone-pseudos'\nimport {\n createImage,\n toArray,\n isInstanceOfElement,\n getStyleProperties,\n} from './util'\nimport { getMimeType } from './mimes'\nimport { resourceToDataURL } from './dataurl'\n\nasync function cloneCanvasElement(canvas: HTMLCanvasElement) {\n const dataURL = canvas.toDataURL()\n if (dataURL === 'data:,') {\n return canvas.cloneNode(false) as HTMLCanvasElement\n }\n return createImage(dataURL)\n}\n\nasync function cloneVideoElement(video: HTMLVideoElement, options: Options) {\n if (video.currentSrc) {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n canvas.width = video.clientWidth\n canvas.height = video.clientHeight\n ctx?.drawImage(video, 0, 0, canvas.width, canvas.height)\n const dataURL = canvas.toDataURL()\n return createImage(dataURL)\n }\n\n const poster = video.poster\n const contentType = getMimeType(poster)\n const dataURL = await resourceToDataURL(poster, contentType, options)\n return createImage(dataURL)\n}\n\nasync function cloneIFrameElement(iframe: HTMLIFrameElement, options: Options) {\n try {\n if (iframe?.contentDocument?.body) {\n return (await cloneNode(\n iframe.contentDocument.body,\n options,\n true,\n )) as HTMLBodyElement\n }\n } catch {\n // Failed to clone iframe\n }\n\n return iframe.cloneNode(false) as HTMLIFrameElement\n}\n\nasync function cloneSingleNode<T extends HTMLElement>(\n node: T,\n options: Options,\n): Promise<HTMLElement> {\n if (isInstanceOfElement(node, HTMLCanvasElement)) {\n return cloneCanvasElement(node)\n }\n\n if (isInstanceOfElement(node, HTMLVideoElement)) {\n return cloneVideoElement(node, options)\n }\n\n if (isInstanceOfElement(node, HTMLIFrameElement)) {\n return cloneIFrameElement(node, options)\n }\n\n return node.cloneNode(isSVGElement(node)) as T\n}\n\nconst isSlotElement = (node: HTMLElement): node is HTMLSlotElement =>\n node.tagName != null && node.tagName.toUpperCase() === 'SLOT'\n\nconst isSVGElement = (node: HTMLElement): node is HTMLSlotElement =>\n node.tagName != null && node.tagName.toUpperCase() === 'SVG'\n\nasync function cloneChildren<T extends HTMLElement>(\n nativeNode: T,\n clonedNode: T,\n options: Options,\n): Promise<T> {\n if (isSVGElement(clonedNode)) {\n return clonedNode\n }\n\n let children: T[] = []\n\n if (isSlotElement(nativeNode) && nativeNode.assignedNodes) {\n children = toArray<T>(nativeNode.assignedNodes())\n } else if (\n isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n nativeNode.contentDocument?.body\n ) {\n children = toArray<T>(nativeNode.contentDocument.body.childNodes)\n } else {\n children = toArray<T>((nativeNode.shadowRoot ?? nativeNode).childNodes)\n }\n\n if (\n children.length === 0 ||\n isInstanceOfElement(nativeNode, HTMLVideoElement)\n ) {\n return clonedNode\n }\n\n await children.reduce(\n (deferred, child) =>\n deferred\n .then(() => cloneNode(child, options))\n .then((clonedChild: HTMLElement | null) => {\n if (clonedChild) {\n clonedNode.appendChild(clonedChild)\n }\n }),\n Promise.resolve(),\n )\n\n return clonedNode\n}\n\nfunction cloneCSSStyle<T extends HTMLElement>(\n nativeNode: T,\n clonedNode: T,\n options: Options,\n) {\n const targetStyle = clonedNode.style\n if (!targetStyle) {\n return\n }\n\n const sourceStyle = window.getComputedStyle(nativeNode)\n if (sourceStyle.cssText) {\n targetStyle.cssText = sourceStyle.cssText\n targetStyle.transformOrigin = sourceStyle.transformOrigin\n } else {\n getStyleProperties(options).forEach((name) => {\n let value = sourceStyle.getPropertyValue(name)\n if (name === 'font-size' && value.endsWith('px')) {\n const reducedFont =\n Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1\n value = `${reducedFont}px`\n }\n\n if (\n isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n name === 'display' &&\n value === 'inline'\n ) {\n value = 'block'\n }\n\n if (name === 'd' && clonedNode.getAttribute('d')) {\n value = `path(${clonedNode.getAttribute('d')})`\n }\n\n targetStyle.setProperty(\n name,\n value,\n sourceStyle.getPropertyPriority(name),\n )\n })\n }\n}\n\nfunction cloneInputValue<T extends HTMLElement>(nativeNode: T, clonedNode: T) {\n if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) {\n clonedNode.innerHTML = nativeNode.value\n }\n\n if (isInstanceOfElement(nativeNode, HTMLInputElement)) {\n clonedNode.setAttribute('value', nativeNode.value)\n }\n}\n\nfunction cloneSelectValue<T extends HTMLElement>(nativeNode: T, clonedNode: T) {\n if (isInstanceOfElement(nativeNode, HTMLSelectElement)) {\n const clonedSelect = clonedNode as any as HTMLSelectElement\n const selectedOption = Array.from(clonedSelect.children).find(\n (child) => nativeNode.value === child.getAttribute('value'),\n )\n\n if (selectedOption) {\n selectedOption.setAttribute('selected', '')\n }\n }\n}\n\nfunction decorate<T extends HTMLElement>(\n nativeNode: T,\n clonedNode: T,\n options: Options,\n): T {\n if (isInstanceOfElement(clonedNode, Element)) {\n cloneCSSStyle(nativeNode, clonedNode, options)\n clonePseudoElements(nativeNode, clonedNode, options)\n cloneInputValue(nativeNode, clonedNode)\n cloneSelectValue(nativeNode, clonedNode)\n }\n\n return clonedNode\n}\n\nasync function ensureSVGSymbols<T extends HTMLElement>(\n clone: T,\n options: Options,\n) {\n const uses = clone.querySelectorAll ? clone.querySelectorAll('use') : []\n if (uses.length === 0) {\n return clone\n }\n\n const processedDefs: { [key: string]: HTMLElement } = {}\n for (let i = 0; i < uses.length; i++) {\n const use = uses[i]\n const id = use.getAttribute('xlink:href')\n if (id) {\n const exist = clone.querySelector(id)\n const definition = document.querySelector(id) as HTMLElement\n if (!exist && definition && !processedDefs[id]) {\n // eslint-disable-next-line no-await-in-loop\n processedDefs[id] = (await cloneNode(definition, options, true))!\n }\n }\n }\n\n const nodes = Object.values(processedDefs)\n if (nodes.length) {\n const ns = 'http://www.w3.org/1999/xhtml'\n const svg = document.createElementNS(ns, 'svg')\n svg.setAttribute('xmlns', ns)\n svg.style.position = 'absolute'\n svg.style.width = '0'\n svg.style.height = '0'\n svg.style.overflow = 'hidden'\n svg.style.display = 'none'\n\n const defs = document.createElementNS(ns, 'defs')\n svg.appendChild(defs)\n\n for (let i = 0; i < nodes.length; i++) {\n defs.appendChild(nodes[i])\n }\n\n clone.appendChild(svg)\n }\n\n return clone\n}\n\nexport async function cloneNode<T extends HTMLElement>(\n node: T,\n options: Options,\n isRoot?: boolean,\n): Promise<T | null> {\n if (!isRoot && options.filter && !options.filter(node)) {\n return null\n }\n\n return Promise.resolve(node)\n .then((clonedNode) => cloneSingleNode(clonedNode, options) as Promise<T>)\n .then((clonedNode) => cloneChildren(node, clonedNode, options))\n .then((clonedNode) => decorate(node, clonedNode, options))\n .then((clonedNode) => ensureSVGSymbols(clonedNode, options))\n}\n", "import { Options } from './types'\nimport { resolveUrl } from './util'\nimport { getMimeType } from './mimes'\nimport { isDataUrl, makeDataUrl, resourceToDataURL } from './dataurl'\n\nconst URL_REGEX = /url\\((['\"]?)([^'\"]+?)\\1\\)/g\nconst URL_WITH_FORMAT_REGEX = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g\nconst FONT_SRC_REGEX = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g\n\nfunction toRegex(url: string): RegExp {\n // eslint-disable-next-line no-useless-escape\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, '\\\\$1')\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, 'g')\n}\n\nexport function parseURLs(cssText: string): string[] {\n const urls: string[] = []\n\n cssText.replace(URL_REGEX, (raw, quotation, url) => {\n urls.push(url)\n return raw\n })\n\n return urls.filter((url) => !isDataUrl(url))\n}\n\nexport async function embed(\n cssText: string,\n resourceURL: string,\n baseURL: string | null,\n options: Options,\n getContentFromUrl?: (url: string) => Promise<string>,\n): Promise<string> {\n try {\n const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL\n const contentType = getMimeType(resourceURL)\n let dataURL: string\n if (getContentFromUrl) {\n const content = await getContentFromUrl(resolvedURL)\n dataURL = makeDataUrl(content, contentType)\n } else {\n dataURL = await resourceToDataURL(resolvedURL, contentType, options)\n }\n return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`)\n } catch (error) {\n // pass\n }\n return cssText\n}\n\nfunction filterPreferredFontFormat(\n str: string,\n { preferredFontFormat }: Options,\n): string {\n return !preferredFontFormat\n ? str\n : str.replace(FONT_SRC_REGEX, (match: string) => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || []\n if (!format) {\n return ''\n }\n\n if (format === preferredFontFormat) {\n return `src: ${src};`\n }\n }\n })\n}\n\nexport function shouldEmbed(url: string): boolean {\n return url.search(URL_REGEX) !== -1\n}\n\nexport async function embedResources(\n cssText: string,\n baseUrl: string | null,\n options: Options,\n): Promise<string> {\n if (!shouldEmbed(cssText)) {\n return cssText\n }\n\n const filteredCSSText = filterPreferredFontFormat(cssText, options)\n const urls = parseURLs(filteredCSSText)\n return urls.reduce(\n (deferred, url) =>\n deferred.then((css) => embed(css, url, baseUrl, options)),\n Promise.resolve(filteredCSSText),\n )\n}\n", "import { Options } from './types'\nimport { embedResources } from './embed-resources'\nimport { toArray, isInstanceOfElement } from './util'\nimport { isDataUrl, resourceToDataURL } from './dataurl'\nimport { getMimeType } from './mimes'\n\nasync function embedProp(\n propName: string,\n node: HTMLElement,\n options: Options,\n) {\n const propValue = node.style?.getPropertyValue(propName)\n if (propValue) {\n const cssString = await embedResources(propValue, null, options)\n node.style.setProperty(\n propName,\n cssString,\n node.style.getPropertyPriority(propName),\n )\n return true\n }\n return false\n}\n\nasync function embedBackground<T extends HTMLElement>(\n clonedNode: T,\n options: Options,\n) {\n ;(await embedProp('background', clonedNode, options)) ||\n (await embedProp('background-image', clonedNode, options))\n ;(await embedProp('mask', clonedNode, options)) ||\n (await embedProp('-webkit-mask', clonedNode, options)) ||\n (await embedProp('mask-image', clonedNode, options)) ||\n (await embedProp('-webkit-mask-image', clonedNode, options))\n}\n\nasync function embedImageNode<T extends HTMLElement | SVGImageElement>(\n clonedNode: T,\n options: Options,\n) {\n const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement)\n\n if (\n !(isImageElement && !isDataUrl(clonedNode.src)) &&\n !(\n isInstanceOfElement(clonedNode, SVGImageElement) &&\n !isDataUrl(clonedNode.href.baseVal)\n )\n ) {\n return\n }\n\n const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal\n\n const dataURL = await resourceToDataURL(url, getMimeType(url), options)\n await new Promise((resolve, reject) => {\n clonedNode.onload = resolve\n clonedNode.onerror = options.onImageErrorHandler\n ? (...attributes) => {\n try {\n resolve(options.onImageErrorHandler!(...attributes))\n } catch (error) {\n reject(error)\n }\n }\n : reject\n\n const image = clonedNode as HTMLImageElement\n if (image.decode) {\n image.decode = resolve as any\n }\n\n if (image.loading === 'lazy') {\n image.loading = 'eager'\n }\n\n if (isImageElement) {\n clonedNode.srcset = ''\n clonedNode.src = dataURL\n } else {\n clonedNode.href.baseVal = dataURL\n }\n })\n}\n\nasync function embedChildren<T extends HTMLElement>(\n clonedNode: T,\n options: Options,\n) {\n const children = toArray<HTMLElement>(clonedNode.childNodes)\n const deferreds = children.map((child) => embedImages(child, options))\n await Promise.all(deferreds).then(() => clonedNode)\n}\n\nexport async function embedImages<T extends HTMLElement>(\n clonedNode: T,\n options: Options,\n) {\n if (isInstanceOfElement(clonedNode, Element)) {\n await embedBackground(clonedNode, options)\n await embedImageNode(clonedNode, options)\n await embedChildren(clonedNode, options)\n }\n}\n", "import type { Options } from './types'\n\nexport function applyStyle<T extends HTMLElement>(\n node: T,\n options: Options,\n): T {\n const { style } = node\n\n if (options.backgroundColor) {\n style.backgroundColor = options.backgroundColor\n }\n\n if (options.width) {\n style.width = `${options.width}px`\n }\n\n if (options.height) {\n style.height = `${options.height}px`\n }\n\n const manual = options.style\n if (manual != null) {\n Object.keys(manual).forEach((key: any) => {\n style[key] = manual[key] as string\n })\n }\n\n return node\n}\n", "import type { Options } from './types'\nimport { toArray } from './util'\nimport { fetchAsDataURL } from './dataurl'\nimport { shouldEmbed, embedResources } from './embed-resources'\n\ninterface Metadata {\n url: string\n cssText: string\n}\n\nconst cssFetchCache: { [href: string]: Metadata } = {}\n\nasync function fetchCSS(url: string) {\n let cache = cssFetchCache[url]\n if (cache != null) {\n return cache\n }\n\n const res = await fetch(url)\n const cssText = await res.text()\n cache = { url, cssText }\n\n cssFetchCache[url] = cache\n\n return cache\n}\n\nasync function embedFonts(data: Metadata, options: Options): Promise<string> {\n let cssText = data.cssText\n const regexUrl = /url\\([\"']?([^\"')]+)[\"']?\\)/g\n const fontLocs = cssText.match(/url\\([^)]+\\)/g) || []\n const loadFonts = fontLocs.map(async (loc: string) => {\n let url = loc.replace(regexUrl, '$1')\n if (!url.startsWith('https://')) {\n url = new URL(url, data.url).href\n }\n\n return fetchAsDataURL<[string, string]>(\n url,\n options.fetchRequestInit,\n ({ result }) => {\n cssText = cssText.replace(loc, `url(${result})`)\n return [loc, result]\n },\n )\n })\n\n return Promise.all(loadFonts).then(() => cssText)\n}\n\nfunction parseCSS(source: string) {\n if (source == null) {\n return []\n }\n\n const result: string[] = []\n const commentsRegex = /(\\/\\*[\\s\\S]*?\\*\\/)/gi\n // strip out comments\n let cssText = source.replace(commentsRegex, '')\n\n // eslint-disable-next-line prefer-regex-literals\n const keyframesRegex = new RegExp(\n '((@.*?keyframes [\\\\s\\\\S]*?){([\\\\s\\\\S]*?}\\\\s*?)})',\n 'gi',\n )\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const matches = keyframesRegex.exec(cssText)\n if (matches === null) {\n break\n }\n result.push(matches[0])\n }\n cssText = cssText.replace(keyframesRegex, '')\n\n const importRegex = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi\n // to match css & media queries together\n const combinedCSSRegex =\n '((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]' +\n '*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})'\n // unified regex\n const unifiedRegex = new RegExp(combinedCSSRegex, 'gi')\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let matches = importRegex.exec(cssText)\n if (matches === null) {\n matches = unifiedRegex.exec(cssText)\n if (matches === null) {\n break\n } else {\n importRegex.lastIndex = unifiedRegex.lastIndex\n }\n } else {\n unifiedRegex.lastIndex = importRegex.lastIndex\n }\n result.push(matches[0])\n }\n\n return result\n}\n\nasync function getCSSRules(\n styleSheets: CSSStyleSheet[],\n options: Options,\n): Promise<CSSStyleRule[]> {\n const ret: CSSStyleRule[] = []\n const deferreds: Promise<number | void>[] = []\n\n // First loop inlines imports\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray<CSSRule>(sheet.cssRules || []).forEach((item, index) => {\n if (item.type === CSSRule.IMPORT_RULE) {\n let importIndex = index + 1\n const url = (item as CSSImportRule).href\n const deferred = fetchCSS(url)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) =>\n parseCSS(cssText).forEach((rule) => {\n try {\n sheet.insertRule(\n rule,\n rule.startsWith('@import')\n ? (importIndex += 1)\n : sheet.cssRules.length,\n )\n } catch (error) {\n console.error('Error inserting rule from remote css', {\n rule,\n error,\n })\n }\n }),\n )\n .catch((e) => {\n console.error('Error loading remote css', e.toString())\n })\n\n deferreds.push(deferred)\n }\n })\n } catch (e) {\n const inline =\n styleSheets.find((a) => a.href == null) || document.styleSheets[0]\n if (sheet.href != null) {\n deferreds.push(\n fetchCSS(sheet.href)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) =>\n parseCSS(cssText).forEach((rule) => {\n inline.insertRule(rule, inline.cssRules.length)\n }),\n )\n .catch((err: unknown) => {\n console.error('Error loading remote stylesheet', err)\n }),\n )\n }\n console.error('Error inlining remote css file', e)\n }\n }\n })\n\n return Promise.all(deferreds).then(() => {\n // Second loop parses rules\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray<CSSStyleRule>(sheet.cssRules || []).forEach((item) => {\n ret.push(item)\n })\n } catch (e) {\n console.error(`Error while reading CSS rules from ${sheet.href}`, e)\n }\n }\n })\n\n return ret\n })\n}\n\nfunction getWebFontRules(cssRules: CSSStyleRule[]): CSSStyleRule[] {\n return cssRules\n .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE)\n .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src')))\n}\n\nasync function parseWebFontRules<T extends HTMLElement>(\n node: T,\n options: Options,\n) {\n if (node.ownerDocument == null) {\n throw new Error('Provided element is not within a Document')\n }\n\n const styleSheets = toArray<CSSStyleSheet>(node.ownerDocument.styleSheets)\n const cssRules = await getCSSRules(styleSheets, options)\n\n return getWebFontRules(cssRules)\n}\n\nfunction normalizeFontFamily(font: string) {\n return font.trim().replace(/[\"']/g, '')\n}\n\nfunction getUsedFonts(node: HTMLElement) {\n const fonts = new Set<string>()\n function traverse(node: HTMLElement) {\n const fontFamily =\n node.style.fontFamily || getComputedStyle(node).fontFamily\n fontFamily.split(',').forEach((font) => {\n fonts.add(normalizeFontFamily(font))\n })\n\n Array.from(node.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n traverse(child)\n }\n })\n }\n traverse(node)\n return fonts\n}\n\nexport async function getWebFontCSS<T extends HTMLElement>(\n node: T,\n options: Options,\n): Promise<string> {\n const rules = await parseWebFontRules(node, options)\n const usedFonts = getUsedFonts(node)\n const cssTexts = await Promise.all(\n rules\n .filter((rule) =>\n usedFonts.has(normalizeFontFamily(rule.style.fontFamily)),\n )\n .map((rule) => {\n const baseUrl = rule.parentStyleSheet\n ? rule.parentStyleSheet.href\n : null\n return embedResources(rule.cssText, baseUrl, options)\n }),\n )\n\n return cssTexts.join('\\n')\n}\n\nexport async function embedWebFonts<T extends HTMLElement>(\n clonedNode: T,\n options: Options,\n) {\n const cssText =\n options.fontEmbedCSS != null\n ? options.fontEmbedCSS\n : options.skipFonts\n ? null\n : await getWebFontCSS(clonedNode, options)\n\n if (cssText) {\n const styleNode = document.createElement('style')\n const sytleContent = document.createTextNode(cssText)\n\n styleNode.appendChild(sytleContent)\n\n if (clonedNode.firstChild) {\n clonedNode.insertBefore(styleNode, clonedNode.firstChild)\n } else {\n clonedNode.appendChild(styleNode)\n }\n }\n}\n", "import { Options } from './types'\nimport { cloneNode } from './clone-node'\nimport { embedImages } from './embed-images'\nimport { applyStyle } from './apply-style'\nimport { embedWebFonts, getWebFontCSS } from './embed-webfonts'\nimport {\n getImageSize,\n getPixelRatio,\n createImage,\n canvasToBlob,\n nodeToDataURL,\n checkCanvasDimensions,\n} from './util'\n\nexport async function toSvg<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<string> {\n const { width, height } = getImageSize(node, options)\n const clonedNode = (await cloneNode(node, options, true)) as HTMLElement\n await embedWebFonts(clonedNode, options)\n await embedImages(clonedNode, options)\n applyStyle(clonedNode, options)\n const datauri = await nodeToDataURL(clonedNode, width, height)\n return datauri\n}\n\nexport async function toCanvas<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<HTMLCanvasElement> {\n const { width, height } = getImageSize(node, options)\n const svg = await toSvg(node, options)\n const img = await createImage(svg)\n\n const canvas = document.createElement('canvas')\n const context = canvas.getContext('2d')!\n const ratio = options.pixelRatio || getPixelRatio()\n const canvasWidth = options.canvasWidth || width\n const canvasHeight = options.canvasHeight || height\n\n canvas.width = canvasWidth * ratio\n canvas.height = canvasHeight * ratio\n\n if (!options.skipAutoScale) {\n checkCanvasDimensions(canvas)\n }\n canvas.style.width = `${canvasWidth}`\n canvas.style.height = `${canvasHeight}`\n\n if (options.backgroundColor) {\n context.fillStyle = options.backgroundColor\n context.fillRect(0, 0, canvas.width, canvas.height)\n }\n\n context.drawImage(img, 0, 0, canvas.width, canvas.height)\n\n return canvas\n}\n\nexport async function toPixelData<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<Uint8ClampedArray> {\n const { width, height } = getImageSize(node, options)\n const canvas = await toCanvas(node, options)\n const ctx = canvas.getContext('2d')!\n return ctx.getImageData(0, 0, width, height).data\n}\n\nexport async function toPng<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<string> {\n const canvas = await toCanvas(node, options)\n return canvas.toDataURL()\n}\n\nexport async function toJpeg<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<string> {\n const canvas = await toCanvas(node, options)\n return canvas.toDataURL('image/jpeg', options.quality || 1)\n}\n\nexport async function toBlob<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<Blob | null> {\n const canvas = await toCanvas(node, options)\n const blob = await canvasToBlob(canvas)\n return blob\n}\n\nexport async function getFontEmbedCSS<T extends HTMLElement>(\n node: T,\n options: Options = {},\n): Promise<string> {\n return getWebFontCSS(node, options)\n}\n", "import { getCompInit } from '#rx'\nimport { Filter } from './FilterClass'\nimport { getNormalRoot } from './filter.utils'\nimport * as htmlToImage from 'html-to-image'\n\n// use this in rx-based apps\nclass FilterRxComp extends Filter {\n\tstatic type = 'filter'\n\n\tconstructor(opts) {\n\t\tsuper(opts)\n\t\tthis.type = FilterRxComp.type\n\t\tthis.parentId = opts.parentId\n\t\tthis.initHolder()\n\t\t// rx.getCompInit() will create this.opts, this.api\n\t}\n\n\tasync preApiFreeze(api) {\n\t\tapi.main = this.main.bind(this)\n\t\tapi.getNormalRoot = () => getNormalRoot(this.rawFilter)\n\t\tapi.getFilterImage = async () => {\n\t\t\t//clone node and append to body temporarily to ensure that the node is rendered properly. Otherwise if the filter is not visible on screen, the image will be blank.\n\t\t\tconst node = this.dom.filterContainer.node().cloneNode(true)\n\t\t\tdocument.body.appendChild(node)\n\n\t\t\tconst dataUrl = await htmlToImage.toPng(node, {\n\t\t\t\tquality: 0.95,\n\t\t\t\tstyle: {\n\t\t\t\t\tbackground: 'white'\n\t\t\t\t}\n\t\t\t})\n\t\t\tdocument.body.removeChild(node)\n\t\t\tif (dataUrl === 'data:,')\n\t\t\t\t//empty filter\n\t\t\t\treturn null\n\t\t\treturn dataUrl\n\t\t}\n\t}\n\n\tgetState(appState) {\n\t\tconst parentConfig = this.parentId && appState.plots.find(p => p.id === this.parentId)\n\t\tconst defaultFilter = { type: 'tvslst', join: '', lst: [] }\n\t\treturn {\n\t\t\t// if there is parentConfig, assume this is UI for a local filter,\n\t\t\t// otherwise this UI is for global app filter\n\t\t\ttermfilter: parentConfig ? { filter: parentConfig.filter || defaultFilter } : appState.termfilter,\n\t\t\t// make all nested plot pill edit menus react to global filter changes\n\t\t\tglobalFilter: parentConfig ? appState.termfilter.filter : undefined,\n\t\t\tactiveCohort: appState.activeCohort\n\t\t}\n\t}\n\n\tasync main(rawFilter = null) {\n\t\tthis.dom.controlsTip.hide()\n\t\tthis.dom.treeTip.hide()\n\t\tconst f = this.state && this.state.termfilter\n\t\tif (!f) {\n\t\t\tthis.dom.holder.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tthis.dom.holder.style('display', 'inline-block')\n\t\tconst filter = structuredClone(rawFilter || f?.filter)\n\t\tif (filter.lst.length < 2) filter.join = ''\n\t\tthis.rawCopy = JSON.stringify(filter)\n\t\tsuper.main(this.rawCopy, { activeCohort: this.state.activeCohort })\n\t}\n\n\tinitHolder() {\n\t\tconst div = this.dom.holder\n\t\t\t.attr('class', 'sjpp_filter_div')\n\t\t\t.style('position', 'relative')\n\t\t\t.style('width', 'fit-content')\n\t\t\t.style('display', 'table')\n\t\t\t.style('border', this.opts.hideLabel ? 'none' : 'solid 1px #ddd')\n\n\t\tif (this.opts.hideLabel) {\n\t\t\tthis.dom.filterDiv = div.style('display', 'inline-block').style('padding', '5px 10px')\n\t\t} else {\n\t\t\tdiv.append('span').text('Filter').style('padding', '0 10px')\n\n\t\t\tthis.dom.filterDiv = div.append('div').style('display', 'inline-block').style('padding', '5px 10px')\n\t\t}\n\t}\n}\n\nexport const filterRxCompInit = getCompInit(FilterRxComp)\n", "import { getInitFxn, Bus } from '#rx'\nimport { Filter } from './FilterClass'\nimport { getNormalRoot, getFilterItemByTag, findParent } from './filter.utils'\n\n// use this as a non-rx, stateless component\n// BUT where a filterUiRoot tag is used and would need to be handled\n// correctly when refreshing the filter data and UI\nclass FilterPrompt extends Filter {\n\tconstructor(opts) {\n\t\tsuper(opts)\n\t\tthis.api = {\n\t\t\t// make sure to bind the 'this' context to the filter instance\n\t\t\t// instead of to the this.api object\n\t\t\tmain: this.main.bind(this),\n\t\t\t/*\n\t\t\t\tWARNING!!!\n\t\t\t\tWhen using this filter.api.getNormalRoot(),\n\t\t\t\tmake sure this instance has been updated before the caller,\n\t\t\t\totherwise the normalized root will be stale\n\n\t\t\t\tor for reliability, import getNormalRoot() directly \n\t\t\t\tfrom the common/filter.js component and supply the \n\t\t\t\tcaller's known raw filter state\n\t\t\t*/\n\t\t\tgetNormalRoot: () => getNormalRoot(this.rawFilter),\n\t\t\tgetPromise: name => this.promises[name],\n\t\t\tdestroy: () => this.destroy()\n\t\t}\n\n\t\tif (opts.debug) this.api.Inner = this\n\t}\n\n\tasync main(rawFilter, opts = {}) {\n\t\tthis.dom.controlsTip.hide()\n\t\tthis.dom.treeTip.hide()\n\t\tconst activeCohort = 'activeCohort' in opts ? opts.activeCohort : this.activeCohort\n\t\tconst filterUiRoot = getFilterItemByTag(rawFilter, 'filterUiRoot')\n\t\t// always replace the filterUiRoot with a tvslst object that has an empty lst,\n\t\t// so that the prompt will always be displayed\n\t\tif (filterUiRoot) delete filterUiRoot.tag\n\t\trawFilter.lst.push({\n\t\t\ttag: 'filterUiRoot',\n\t\t\ttype: 'tvslst',\n\t\t\tjoin: '',\n\t\t\tlst: []\n\t\t})\n\t\trawFilter.join = rawFilter.lst.length > 1 ? 'and' : ''\n\t\tconst rawCopy = JSON.stringify(rawFilter)\n\t\t// if the filter data and active cohort has not changed, do not trigger a re-render\n\t\tif (this.rawCopy == rawCopy && JSON.stringify(this.activeCohort) == JSON.stringify(activeCohort)) return\n\t\t// call the parent's main() method\n\t\tawait super.main(rawCopy, opts)\n\t}\n\n\trefresh(filterUiRoot) {\n\t\tthis.dom.controlsTip.hide()\n\t\tthis.dom.treeTip.hide()\n\t\tconst rootCopy = JSON.parse(JSON.stringify(this.rawFilter))\n\t\tconst rawParent = findParent(rootCopy, this.filter.$id)\n\t\tif (!rawParent || this.rawFilter.$id === this.filter.$id) {\n\t\t\tthis.opts.callback(rootCopy)\n\t\t} else {\n\t\t\tconst i = rawParent.lst.findIndex(f => f.$id == this.filter.$id)\n\t\t\trawParent.lst[i] = filterUiRoot\n\t\t\tthis.opts.callback(rootCopy)\n\t\t}\n\t\t// remove the filled-in filterUiRoot from this filter prompt,\n\t\t// so that the selected filter data does not get carried over\n\t\t// to future selections from this prompt\n\t\tconst i = rootCopy.lst.findIndex(f => f.$id === filterUiRoot.$id)\n\t\trootCopy.lst.splice(i, 1)\n\t\tthis.main(rootCopy)\n\t}\n}\n\nexport const filterPromptInit = getInitFxn(FilterPrompt)\n", "import { make_radios, renderTable } from '#dom'\nimport type { TermValues, BaseValue } from '#types'\nimport { filterInit } from '#filter'\nimport { dt2label, dtsnvindel } from '#shared/common.js'\n\ntype Config = {\n\tgenotype: 'variant' | 'wt' | 'nt'\n\tvalues: BaseValue[]\n\tmcount?: 'any' | 'single' | 'multiple' | 'all'\n\tmafFilter?: any\n}\n\ntype Arg = {\n\tholder: any // D3 holder where UI is rendered\n\theader?: string // UI header\n\tvalues: TermValues // mutation classes of term\n\tselectedValues?: BaseValue[] // selected mutation classes, when missing will default to all classes of term\n\tgenotype?: 'variant' | 'wt' | 'nt' // genotype (variant, wildtype, not tested)\n\tdt: number // dt value, rendering of some elements are based on this value\n\tmcount?: 'any' | 'single' | 'multiple' | 'all' // mutation count, when missing will default to 'any'\n\tmafFilter?: any // maf filter\n\tcallback: (config: Config) => void\n}\n\nexport function renderVariantConfig(arg: Arg) {\n\tconst { holder, dt, mafFilter } = arg\n\tconst genotype = arg.genotype || 'variant'\n\tif (!['variant', 'wt', 'nt'].includes(genotype)) throw 'invalid genotype'\n\tconst values: BaseValue[] = Object.entries(arg.values).map(([k, v]) => {\n\t\treturn { key: k, label: v.label, value: k }\n\t})\n\tconst selectedValues = arg.selectedValues?.length ? arg.selectedValues : values\n\tif (!Number.isInteger(dt)) throw 'unexpected dt value'\n\tconst mcount = arg.mcount || 'any'\n\tif (!['any', 'single', 'multiple', 'all'].includes(mcount)) throw 'invalid mcount'\n\n\tholder.style('margin', '10px')\n\n\t// header\n\tif (arg.header) {\n\t\tholder.append('div').style('font-weight', 'bold').style('font-size', '.9em').text(arg.header)\n\t}\n\n\t// mutant vs. wildtype radio buttons\n\tconst genotypeDiv = holder\n\t\t.append('div')\n\t\t.attr('data-testid', 'sjpp-variantConfig-genotype')\n\t\t.style('margin-top', '10px')\n\tgenotypeDiv\n\t\t.append('div')\n\t\t.style('display', 'inline-block')\n\t\t.style('margin-right', '5px')\n\t\t.style('opacity', 0.7)\n\t\t.text('Genotype')\n\tconst genotypeRadio = make_radios({\n\t\tholder: genotypeDiv,\n\t\tstyles: { display: 'inline-block' },\n\t\toptions: [\n\t\t\t{ label: dt2label[dt], value: 'variant', checked: genotype == 'variant' },\n\t\t\t{ label: 'Wildtype', value: 'wt', checked: genotype == 'wt' },\n\t\t\t{ label: 'Not tested', value: 'nt', checked: genotype == 'nt' }\n\t\t],\n\t\tcallback: value => {\n\t\t\tvariantsDiv.style('display', value == 'variant' ? 'block' : 'none')\n\t\t\tapplyBtn.property('disabled', value == 'variant' && !values.length)\n\t\t}\n\t})\n\n\t// variants\n\tconst variantsDiv = holder\n\t\t.append('div')\n\t\t.attr('data-testid', 'sjpp-variantConfig-variant')\n\t\t.style('display', genotype == 'variant' ? 'block' : 'none')\n\t\t.style('margin-top', '10px')\n\n\tlet countRadio\n\tif (values.length) {\n\t\t// variant data present, display as table\n\t\tvariantsDiv.append('div').style('opacity', 0.7).style('margin-bottom', '5px').text(dt2label[dt])\n\t\tconst tableDiv = variantsDiv.append('div').style('margin-left', '5px').style('font-size', '0.8rem')\n\t\tconst rows: any[] = []\n\t\tconst selectedIdxs: number[] = []\n\t\tfor (const [i, m] of values.entries()) {\n\t\t\tconst label = m.label || m.key\n\t\t\trows.push([{ value: label }])\n\t\t\tif (selectedValues.find(s => s.key == m.key)) selectedIdxs.push(i)\n\t\t}\n\t\tconst columns: any[] = [{ label: 'tvs' }]\n\t\trenderTable({\n\t\t\trows,\n\t\t\tcolumns,\n\t\t\tdiv: tableDiv,\n\t\t\tmaxWidth: '40vw',\n\t\t\tmaxHeight: '40vh',\n\t\t\tbuttons: [],\n\t\t\tshowHeader: false,\n\t\t\tstriped: false,\n\t\t\tshowLines: false,\n\t\t\tselectedRows: selectedIdxs\n\t\t})\n\t\tif (dt == dtsnvindel) {\n\t\t\t// snvindel\n\t\t\t// render mutation count radios\n\t\t\tconst countDiv = variantsDiv.append('div').style('margin-top', '5px')\n\t\t\tcountDiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin-right', '5px')\n\t\t\t\t.style('opacity', 0.7)\n\t\t\t\t.text('Occurrence')\n\t\t\tconst countOpts: any = [\n\t\t\t\t{ label: 'Any', value: 'any' },\n\t\t\t\t{ label: 'Single', value: 'single' },\n\t\t\t\t{ label: 'Multiple', value: 'multiple' }\n\t\t\t]\n\t\t\tcountOpts.forEach((opt: any) => {\n\t\t\t\tif (opt.value == mcount) opt.checked = true\n\t\t\t})\n\t\t\t// not displaying the 'all' option by default because its usecase\n\t\t\t// is currently limited (e.g. for tvs in biallelic/monoallelic groupset)\n\t\t\t// can display the option by default if needed more broadly\n\t\t\tif (!countOpts.some((opt: any) => opt.checked)) {\n\t\t\t\tif (mcount == 'all') countOpts.push({ label: 'All', value: 'all', checked: true })\n\t\t\t}\n\t\t\tcountRadio = make_radios({\n\t\t\t\tholder: countDiv,\n\t\t\t\tstyles: { display: 'inline-block' },\n\t\t\t\toptions: countOpts,\n\t\t\t\tcallback: () => {}\n\t\t\t})\n\t\t\t// render maf filter, if defined\n\t\t\tif (mafFilter) {\n\t\t\t\tconst mafDiv = variantsDiv.append('div').style('margin-top', '5px')\n\t\t\t\tmafDiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin-right', '5px')\n\t\t\t\t\t.style('opacity', 0.7)\n\t\t\t\t\t.text('MAF filter')\n\t\t\t\tfilterInit({\n\t\t\t\t\temptyLabel: '+',\n\t\t\t\t\tholder: mafDiv,\n\t\t\t\t\theader_mode: 'hide_search',\n\t\t\t\t\tisMafFilter: true, // will be handled by \"client/filter/tvs.numeric.js\"\n\t\t\t\t\tvocab: { terms: mafFilter.terms },\n\t\t\t\t\tcallback: async filter => {\n\t\t\t\t\t\tmafFilter.active = filter\n\t\t\t\t\t}\n\t\t\t\t}).main(mafFilter.active)\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// no variant data\n\t\tvariantsDiv\n\t\t\t.append('div')\n\t\t\t.style('display', values.length ? 'none' : 'block')\n\t\t\t.text(`No ${dt2label[dt]} found`)\n\t}\n\n\t// Apply button\n\tconst applyBtn = holder\n\t\t.append('div')\n\t\t.append('button')\n\t\t.attr('class', 'sja_filter_tag_btn sjpp_apply_btn')\n\t\t.style('border-radius', '13px')\n\t\t.style('margin-top', '15px')\n\t\t.style('font-size', '.8em')\n\t\t.property('disabled', genotype == 'variant' && !values.length)\n\t\t.text('APPLY')\n\t\t.on('click', () => {\n\t\t\t// get genotype\n\t\t\tconst selectedGenotype: any = genotypeRadio.inputs.nodes().find(r => r.checked)\n\t\t\tif (!selectedGenotype) throw 'no genotype selected'\n\t\t\tconst config: Config = { values: [], genotype: selectedGenotype.value }\n\t\t\tif (config.genotype == 'variant') {\n\t\t\t\t// variant genotype\n\t\t\t\t// get selected mutation classes\n\t\t\t\tconst checkboxes = variantsDiv.select('tbody').selectAll('input').nodes()\n\t\t\t\tconst checkedIdxs: number[] = []\n\t\t\t\tfor (const [i, c] of checkboxes.entries()) {\n\t\t\t\t\tif (c.checked) checkedIdxs.push(i)\n\t\t\t\t}\n\t\t\t\tconfig.values = values.filter((v, i) => checkedIdxs.includes(i))\n\t\t\t\tif (dt == dtsnvindel) {\n\t\t\t\t\t// get mutation count\n\t\t\t\t\tconst selectedCount: any = countRadio.inputs.nodes().find(r => r.checked)\n\t\t\t\t\tif (!selectedCount) throw 'no mutation count selected'\n\t\t\t\t\tconfig.mcount = selectedCount.value\n\t\t\t\t\t// get maf filter\n\t\t\t\t\tif (mafFilter) config.mafFilter = mafFilter.active\n\t\t\t\t} else {\n\t\t\t\t\tconfig.mcount = 'any'\n\t\t\t\t}\n\t\t\t}\n\t\t\targ.callback(config)\n\t\t})\n}\n", "import { select } from 'd3-selection'\nimport { to_svg } from '../src/client'\n\nexport function downloadSingleSVG(svg, filename, parent, name = '') {\n\tconst svgParent = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\n\tif (parent) {\n\t\tconst svgStyles = window.getComputedStyle(parent)\n\t\tfor (const [prop, value] of Object.entries(svgStyles)) {\n\t\t\tif (prop.startsWith('font')) svgParent.style[prop] = value\n\t\t}\n\t}\n\tconst svgNode = svg.node().cloneNode(true)\n\tconst g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n\tif (name) {\n\t\tg.setAttribute('transform', `translate(0, ${50})`)\n\t\tconst title = document.createElementNS('http://www.w3.org/2000/svg', 'text')\n\t\ttitle.textContent = name\n\t\tg.appendChild(title)\n\t\tsvgNode.setAttribute('transform', `translate(${0}, ${80})`)\n\t}\n\tg.appendChild(svgNode)\n\tsvgParent.appendChild(g)\n\n\tconst link = document.createElement('a')\n\t// If you don't know the name or want to use\n\t// the webserver default set name = ''\n\tlink.setAttribute('download', filename)\n\tdocument.body.appendChild(link)\n\tlink.click()\n\tlink.remove()\n\tconst serializer = new XMLSerializer()\n\tconst svg_blob = new Blob([serializer.serializeToString(svgParent)], {\n\t\ttype: 'image/svg+xml'\n\t})\n\tlink.href = URL.createObjectURL(svg_blob)\n\tlink.click()\n\tlink.remove()\n}\n\n/*\n\tmainGsel a d3 selection of root g element(s) of svg(s), expected to contain all\n\t\t the rendered plot elements that can be copied into one svg\n\t\n\tsvgName the filename to use for the downloaded svg file\n\n\tstyleParent optional, the div or svg element to use for computing styles to apply to\n\t the svg, so that the standlone image file would preseve the browser-displayed\n\t svg look/appearance\n*/\nexport function downloadChart(mainGsel, svgName, styleParent = null) {\n\t// has to be able to handle multichart view\n\tconst mainGs = []\n\tconst translate = { x: undefined, y: undefined }\n\tconst titles = []\n\tlet maxw = 0,\n\t\tmaxh = 0,\n\t\ttboxh = 0\n\tlet prevY = 0,\n\t\tnumChartsPerRow = 0\n\n\tmainGsel.each(function () {\n\t\tmainGs.push(this)\n\t\tconst bbox = this.getBBox()\n\t\tif (bbox.width > maxw) maxw = bbox.width\n\t\tif (bbox.height > maxh) maxh = bbox.height\n\t\tconst divY = Math.round(this.parentNode.parentNode.getBoundingClientRect().y)\n\t\tif (!numChartsPerRow) {\n\t\t\tprevY = divY\n\t\t\tnumChartsPerRow++\n\t\t} else if (Math.abs(divY - prevY) < 5) {\n\t\t\tnumChartsPerRow++\n\t\t}\n\t\tconst xy = select(this)\n\t\t\t.attr('transform')\n\t\t\t.split('translate(')[1]\n\t\t\t.split(')')[0]\n\t\t\t.split(',')\n\t\t\t.map(d => +d.trim())\n\n\t\tif (translate.x === undefined || xy[0] > translate.x) translate.x = +xy[0]\n\t\tif (translate.y === undefined || xy[1] > translate.y) translate.y = +xy[1]\n\n\t\tconst title = this.parentNode.parentNode.firstChild\n\t\tconst tbox = title.getBoundingClientRect()\n\t\tif (tbox.width > maxw) maxw = tbox.width\n\t\tif (tbox.height > tboxh) tboxh = tbox.height\n\t\ttitles.push({ text: title.innerText, styles: window.getComputedStyle(title), tbox })\n\t})\n\n\t// add padding between charts\n\tmaxw += 80\n\tmaxh += 80\n\n\tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\n\tconst svgSel = select(svg)\n\t\t.style('display', 'block')\n\t\t.style('opacity', 1)\n\t\t.attr('width', numChartsPerRow * maxw)\n\t\t.attr('height', Math.floor(mainGs.length / numChartsPerRow) * maxh)\n\n\tif (styleParent) {\n\t\tconst svgStyles = window.getComputedStyle(styleParent)\n\t\tfor (const prop of svgStyles) {\n\t\t\tif (prop.startsWith('font')) svgSel.style(prop, svgStyles.getPropertyValue(prop))\n\t\t}\n\t}\n\n\tmainGs.forEach((g, i) => {\n\t\tconst mainG = g.cloneNode(true)\n\t\tconst colNum = i % numChartsPerRow\n\t\tconst rowNum = Math.floor(i / numChartsPerRow)\n\t\tconst corner = { x: colNum * maxw + translate.x + 80, y: rowNum * maxh + translate.y }\n\t\tconst title = select(svg)\n\t\t\t.append('text')\n\t\t\t.attr('transform', 'translate(' + (corner.x + titles[i].tbox.width / 2 - 100) + ',' + corner.y + ')')\n\t\t\t.text(titles[i].text)\n\t\tfor (const prop of titles[i].styles) {\n\t\t\tif (prop.startsWith('font')) title.style(prop, titles[i].styles.getPropertyValue(prop))\n\t\t}\n\n\t\t//select(mainG).attr('transform', 'translate(' + corner.x + ',' + (corner.y + tboxh) + ')')\n\t\tsvg.appendChild(mainG)\n\t})\n\n\tto_svg(svg, svgName, { apply_dom_styles: true })\n}\n\nexport function downloadAggregatedSVG(chartImages, svgName) {\n\tconst x = 50\n\tconst svgParent = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\tconst styles = []\n\n\tlet y = 20\n\tfor (const chart of chartImages) {\n\t\tconst parent = chart.parent || chart.svg.node()\n\t\tconst svg = chart.svg.clone(true)\n\t\tconst g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n\t\tg.setAttribute('transform', `translate(${x}, ${y})`)\n\t\tconst svgStyles = window.getComputedStyle(parent)\n\t\tfor (const [prop, value] of Object.entries(svgStyles)) {\n\t\t\tif (prop.startsWith('font')) g.style[prop] = value\n\t\t}\n\t\tconst title = document.createElementNS('http://www.w3.org/2000/svg', 'text')\n\t\ttitle.textContent = chart.name\n\t\tg.appendChild(title)\n\n\t\tconst svgNode = svg.node()\n\t\tconst bbox = svgNode.getBoundingClientRect()\n\t\tsvgNode.setAttribute('transform', `translate(${x}, ${50})`)\n\n\t\tg.appendChild(svgNode)\n\t\tsvgParent.appendChild(g)\n\t\ty += bbox.height + 70 //30 from the shift for the label, 40 to add space for new plot\n\t}\n\tsvgParent.setAttribute('height', `${y + 20}`)\n\n\tto_svg(svgParent, svgName, { apply_dom_styles: true })\n}\n", "import { Menu, to_textfile } from '#dom'\nimport { downloadSingleSVG, downloadAggregatedSVG } from '../common/svg.download.js'\n\n/* if a callback is provided for the 3rd argument, \nit displays \"Text\" option, call callback to generate text data and save to text file\nas the svg/pdf download only relies on <svg> element and no way to access text data\n */\nexport class DownloadMenu {\n\tmenu: Menu\n\tchartImages: any[]\n\tholder: any\n\tmultipleSVGs: boolean\n\tfilename: string\n\ttextCallback?: any\n\n\tconstructor(chartImages, filename = 'charts', textCallback?: () => string) {\n\t\tthis.menu = new Menu({ padding: '0px' })\n\t\tthis.chartImages = chartImages\n\t\tthis.multipleSVGs = chartImages.length > 1\n\t\tthis.filename = filename.replace(/\\s/g, '_')\n\t\tif (textCallback) {\n\t\t\tif (typeof textCallback != 'function') throw new Error('textCallback not function')\n\t\t\tthis.textCallback = textCallback\n\t\t}\n\t}\n\n\tshow(x, y, elem = null) {\n\t\tthis.menu.clear()\n\t\tconst menuDiv = this.menu.d.append('div')\n\t\tmenuDiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-download-pdf-portrait')\n\t\t\t.attr('tabindex', 0)\n\t\t\t.text('PDF Portrait')\n\t\t\t.on('click', () => {\n\t\t\t\tdownloadSVGsAsPdf(this.chartImages, this.filename, 'portrait')\n\t\t\t\tthis.menu.hide()\n\t\t\t})\n\t\tmenuDiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-download-pdf-landscape')\n\t\t\t.text('PDF Landscape')\n\t\t\t.on('click', () => {\n\t\t\t\tdownloadSVGsAsPdf(this.chartImages, this.filename, 'landscape')\n\t\t\t\tthis.menu.hide()\n\t\t\t})\n\t\tmenuDiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-download-svg')\n\t\t\t.text('SVG')\n\t\t\t.on('click', () => {\n\t\t\t\tdownloadAggregatedSVG(this.chartImages, this.filename)\n\t\t\t\tthis.menu.hide()\n\t\t\t})\n\n\t\tif (this.multipleSVGs) {\n\t\t\tmenuDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t\t.attr('data-testid', 'sjpp-download-multiple-svgs')\n\t\t\t\t.text('Multiple SVG')\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tfor (const chart of this.chartImages)\n\t\t\t\t\t\tdownloadSingleSVG(chart.svg, chart.name.replace(/[^a-zA-Z0-9]/g, '_'), chart.svg.node(), chart.name)\n\t\t\t\t\tthis.menu.hide()\n\t\t\t\t})\n\t\t}\n\n\t\tif (this.textCallback) {\n\t\t\tmenuDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t\t.attr('data-testid', 'sjpp-download-text')\n\t\t\t\t.text('Text')\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tto_textfile(this.filename + '.txt', this.textCallback())\n\t\t\t\t\tthis.menu.hide()\n\t\t\t\t})\n\t\t}\n\t\tthis.menu.show(x - 20, y - 10, true, true, true, elem)\n\t}\n}\n\nexport async function downloadSVGsAsPdf(chartImages, filename, orientation, filterImgs: any[] = []) {\n\tconst JSPDF = await import('jspdf')\n\tconst { jsPDF } = JSPDF\n\t/*\n\tWhen imported, the svg2pdf.js module modifies or extends the jsPDF library (which we already imported).\n\tThe code inside svg2pdf.js adds a new method (.svg()) to the jsPDF object prototype, making that functionality available on all jsPDF instances.\n\tTherefore, a simple import 'svg2pdf.js' without curly braces is all that is needed to apply its functionality. \n\t */\n\tawait import('svg2pdf.js') // This import extends jsPDF with SVG functionality\n\tconst doc = new jsPDF(orientation, 'pt', 'a4') // p for portrait, l for landscape, points, A4 size\n\tdoc.setFontSize(12)\n\tconst pageWidth = doc.internal.pageSize.getWidth()\n\tconst pageHeight = doc.internal.pageSize.getHeight()\n\n\tlet y = 50\n\tconst x = 0.05 * pageWidth\n\n\tfor (const filterImgUrl of filterImgs) {\n\t\tdoc.addImage(filterImgUrl, 'PNG', x, y, 0, 30)\n\t\ty += 30\n\t}\n\tif (filterImgs.length > 0) y += 50\n\n\tfor (const chartImage of chartImages) {\n\t\tconst name = chartImage.name\n\t\tconst svg = chartImage.svg.node().cloneNode(true) //clone to avoid modifying the original\n\t\tconst parent = chartImage.parent || chartImage.svg.node()\n\n\t\tconst svgStyles = window.getComputedStyle(parent)\n\t\tfor (const [prop, value] of Object.entries(svgStyles)) {\n\t\t\tif (prop.startsWith('font')) svg.style[prop] = value\n\t\t}\n\t\tparent.appendChild(svg) //Added otherwise does not print, will remove later\n\t\tconst svgWidth = svg.getAttribute('width')\n\t\tconst svgHeight = svg.getAttribute('height')\n\t\tconst scale = getPdfScale(pageWidth, pageHeight, svgWidth, svgHeight)\n\t\tconst width = svgWidth * scale //convert to pt and fit to page size\n\t\tconst height = svgHeight * scale //convert to pt and fit to page size\n\n\t\tif (y != 50 && y + height > pageHeight - 20) {\n\t\t\tdoc.addPage()\n\t\t\ty = 50\n\t\t}\n\t\tif (name.trim()) doc.text(name.length > 90 ? name.slice(0, 90) + '...' : name, x + 10, y - 20)\n\t\telse y -= 20\n\t\tsvg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`)\n\n\t\tawait doc.svg(svg, { x, y, width, height })\n\t\ty = y + height + 50\n\n\t\tparent.removeChild(svg)\n\t}\n\tdoc.save(filename + '.pdf')\n}\n\nexport function getPdfScale(pageWidth, pageHeight, svgWidth, svgHeight) {\n\tconst ratio = 72 / 96 //convert px to pt\n\tconst width = svgWidth * ratio //convert to pt\n\tconst height = svgHeight * ratio //convert to pt\n\tlet scaleWidth = 1,\n\t\tscaleHeight = 1\n\tif (width > pageWidth) {\n\t\tscaleWidth = pageWidth / width\n\t}\n\tif (height > pageHeight) {\n\t\tscaleHeight = pageHeight / height\n\t}\n\tconst scale = Math.min(scaleWidth, scaleHeight) * 0.9 //leave padding\n\treturn scale * ratio\n}\n", "export function to_textfile(filename, text) {\n\tconst a = document.createElement('a')\n\ta.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))\n\ta.setAttribute('download', filename)\n\ta.style.display = 'none'\n\tdocument.body.appendChild(a)\n\ta.click()\n\tdocument.body.removeChild(a)\n}\n", "import { select } from 'd3-selection'\n/*\ndraw a horizontal bar with bg and fg to show percentage\n\ntd: holder\n\toptional, if missing, will return svg html\nv: \n\t.f fraction\n\t.v1 numerator, optional\n\t.v2 denominator\nat:\n\toptional\n\t.width\n\t.height\n\t.fillbg\n\t.fill\n\t.readcountcredible\n*/\n\nexport function fillbar(td, v, at) {\n\tif (!at) at = {}\n\tconst w = at.width || 40\n\tconst h = at.height || 12\n\n\tlet g\n\n\tif (td) {\n\t\ttd.attr('aria-label', (v.f * 100).toFixed(0) + '%' + (v.v1 != undefined ? ' (' + v.v1 + '/' + v.v2 + ')' : ''))\n\t\tg = td.append('svg').attr('width', w).attr('height', h)\n\t} else {\n\t\tg = select(document.body).append('svg')\n\t}\n\n\tlet y = 0\n\t// fill bg\n\tg.append('rect')\n\t\t.attr('y', y)\n\t\t.attr('width', w)\n\t\t.attr('height', h)\n\t\t.attr('fill', at.fillbg || '#CBE2F5')\n\t// fill fg\n\tg.append('rect')\n\t\t.attr('y', y)\n\t\t.attr('width', w * v.f)\n\t\t.attr('height', h)\n\t\t.attr('fill', at.fill || '#69A1D1')\n\n\tif (at.readcountcredible && v.v2 < at.readcountcredible) {\n\t\t// wash with gray\n\t\tconst smudge = '#545454'\n\t\tconst smudge2 = 0.3\n\t\tg.append('rect').attr('y', y).attr('width', w).attr('height', h).attr('fill', smudge).attr('fill-opacity', smudge2)\n\t}\n\n\tif (td) return g\n\n\tg.remove()\n\treturn '<svg width=' + w + ' height=' + h + '>' + g.node().innerHTML + '</svg>'\n}\n", "import { type TwOpts } from './TwBase.ts'\nimport type { RawGeneExpTerm } from '#types'\n\nconst termType = 'geneExpression'\n\nexport class GeneExpBase {\n\tgene: string\n\tname: string\n\tunit: string\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic async fill(term: RawGeneExpTerm, opts: TwOpts) {\n\t\tGeneExpBase.validate(term)\n\t\tif (!term.name) {\n\t\t\tterm.unit = getGEunit(opts.vocabApi)\n\t\t\tconst name = `${term.gene} ${term.unit}`\n\t\t\tterm.name = name\n\t\t}\n\t}\n\n\tstatic validate(term: RawGeneExpTerm) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != termType) throw `incorrect term.type='${term?.type}', expecting '${termType}'`\n\t\tif (term.type != 'geneExpression') throw 'unexpected term.type'\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (!term.gene && !term.name) throw 'no gene or name present'\n\t\tif (!term.gene || typeof term.gene != 'string') throw 'geneExpression term.gene must be non-empty string'\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of term literal object\n\tconstructor(term: RawGeneExpTerm, opts: TwOpts) {\n\t\tGeneExpBase.validate(term)\n\t\tthis.gene = term.gene || term.name\n\t\tthis.unit = term.unit || getGEunit(opts.vocabApi)\n\t\tthis.name = term.name || `${term.gene} ${this.unit}`\n\t}\n}\n\nexport function getGEunit(vocabApi) {\n\treturn vocabApi.termdbConfig.queries.geneExpression?.unit || 'Gene Expression'\n}\n", "import type { RawSingleCellGeneExpTerm, SingleCellGeneExpressionTerm } from '#types'\nimport type { TwOpts } from './TwBase.ts'\nimport { SINGLECELL_GENE_EXPRESSION } from '#shared/terms.js'\n\nconst termType = SINGLECELL_GENE_EXPRESSION\n\nexport class SingleCellGeneExpressionBase {\n\ttype = termType\n\tgene: string\n\tsample: string\n\tunit: string\n\n\tstatic fill(term: RawSingleCellGeneExpTerm, opts: TwOpts) {\n\t\tif (term instanceof SingleCellGeneExpressionBase) return\n\t\tSingleCellGeneExpressionBase.validate(term)\n\t\tif (!term.name) {\n\t\t\tterm.unit = getSCGEunit(opts.vocabApi)\n\t\t\tterm.name = `${term.gene} ${term.unit}`\n\t\t}\n\t}\n\n\tstatic validate(term: RawSingleCellGeneExpTerm) {\n\t\tif (!term || typeof term !== 'object') throw new Error('term is not an object')\n\t\tif (term.type != termType) throw new Error(`incorrect term.type='${term?.type}', expecting '${termType}'`)\n\t\tif (!term.gene && !term.name) throw new Error('no gene or name present')\n\t\tif (!term.gene || typeof term.gene != 'string') throw new Error(`${termType} term.gene must be non-empty string`)\n\t\tif (!term.sample) throw new Error('missing sample name')\n\t}\n\n\tconstructor(term: RawSingleCellGeneExpTerm | SingleCellGeneExpressionTerm, opts: TwOpts) {\n\t\tSingleCellGeneExpressionBase.validate(term)\n\t\tthis.gene = term.gene\n\t\tthis.sample = term.sample\n\t\tthis.unit = term.unit || getSCGEunit(opts.vocabApi)\n\t}\n}\n\nexport function getSCGEunit(vocabApi) {\n\treturn vocabApi.termdbConfig.queries.singleCell.geneExpression?.unit || 'Gene Expression'\n}\n", "import { keyupEnter, gmlst2loci } from '#src/client'\nimport { debounce } from 'debounce'\nimport { dofetch3 } from '#common/dofetch'\nimport { invalidcoord, string2pos } from '#src/coord'\nimport type { ClientGenome } from '../types/clientGenome'\n\n/*\nexports:\n\naddGeneSearchbox()\nstring2variant()\n\ntypical usage:\n\n\tconst arg={\n\t\tgenome: <>,\n\t\trow: <>,\n\t\tcallback: async ()=>{\n\t\t\tdoAction(result)\n\t\t}\n\t}\n\tconst result=addGeneSearchbox(arg)\n\n\n\nTODO\n-- allow to hide searchStat dom\n-- dedup code with block.js\n-- dedup code with app header\n-- unify help message from gdc bam slicing ui and termsetting.snplst\n*/\n\ntype GeneSearchBoxArg = {\n\t/** menu instance to show list of matching genes */\n\ttip: any // applying Menu & Div types here gives many tsc err\n\t/** d3 element in which <input> is created */\n\trow: any\n\t/** if not provided, auto compute to show in <input> */\n\tplaceholder?: string\n\t/** overrides default testid assigned to <input> */\n\ttestid?: string\n\t/** \n\tif 'gene':\n\t\tinput can be symbol or alias\n\t\tresult is {geneSymbol:str}, will not map to coord\n\t\tcannot map isoform to gene name!\n\t\t(later may need geneOrIsoform flag to query both) \n\tif 'genes':\n\t\tinput can be multiple gene symbols or aliases separated by comma, space, tab, or newline\n\t\tuseful for copy-pasting gene lists from spreadsheets\n\t\tif entered single gene, result is same as searchOnly=gene\n if entered multiple, result is {genes: [{geneSymbol:str},...]}\n\tif 'snp':\n\t\tuser must select a single snp\n\t\tinput can be dbSNP id, position, or variant format (chr.pos.ref.alt)\n\t\tallow to enter chr.pos.ref.alt or hgvs (see next section)\n\t\totherwise, only allow chr:start-stop\n\tif missing:\n support gene, region, snp (if available), variant (if allowed). resolves to region\n\t*/\n\tsearchOnly?: 'gene' | 'snp' | 'genes'\n\t/** If true, user must click on search box and enter instead of automatically \n focusing on search box. Use to render d3 animations smoothly. */\n\tfocusOff?: boolean\n\t/**\n\tif no callback():\n\t\tany match is silently written to RESULT\n\t\twith repeated search the latest match is written to RESULT\n\t\tcommon pattern is that user will press a button to launch some logic that will check RESULT\n\t\tit's up to the calling code to decide when to access RESULT (e.g. pressing some button in caller's ui)\n\t\tusecase: block.tk.bam.gdc.js\n\tif has callback():\n\t\tupon a match, RESULT is updated and callback is triggered\n\t\tas a way to notify caller to do subsequent steps\n\t\tusecase: geneSearch4GDCmds3.js\n\t\tno parameter is supplied\n\t*/\n\tcallback?: () => void\n\t/** optional\n triggered when the <input> is emptied and hitting Enter. allows an app to de-select a gene in this way */\n\temptyInputCallback?: () => void\n\t/** if true, hide the text msg on the right of <input> */\n\thideHelp?: boolean\n\t/** optional\n read-only; this script should not try to modify it\n if allowVariant is false, value can only be {chr, start, stop}\n if allowVariant is true, value can also be {chr, pos, ref, alt, isVariant:true}\n set to {chr, start, stop} to fill default position into <input>\n when missing, just show placeholder */\n\tdefaultCoord?: ResultArg\n\t/** client-side genome obj */\n\tgenome: ClientGenome\n\t/** default gene name to fill into search box */\n\tgeneSymbol?: string\n\t/** option to automatically trigger a search when a geneSymbol is specified */\n\ttriggerSearch?: boolean\n\t/** option to hide the search input after search results are generated */\n\thideInputBeforeCallback?: boolean\n\t/** option to disable the input, useful in demo mode */\n\tdisableInput?: boolean\n\t/** if true, allow user to type in a sequence mutation\n\tpartial support of hgvs https://varnomen.hgvs.org/recommendations/DNA/\n\tlimited to substitution/insertion/deletion on \"g.\"\n\tother references (o. m. c. n.) are not supported\n\n\tentered positions are 1-based, parse to 0-based (TODO: this needs to be verified)\n\n\tsnv\n\t\tgiven chr14:g.104780214C>T\n\t\tparse to chr14.104780214.C.T\n\n\tmnv\n\t\tgiven chr2:g.119955155_119955159delinsTTTTT\n\t\tparse to chr2.119955155.AGCTG.TTTTT\n\t\tmust query ref allele\n\n\tdeletion\n\t\tchr17:g.7673802delCGCACCTCAAAGCTGTTC\n\t\tparse to chr17.7673802.CGCACCTCAAAGCTGTTC.-\n\n\t\tchr?:g.33344591del\n\t\tparse to chr?.33344591.A.-\n\t\tmust query ref allele\n\n\t\tif allele is present after \"del\", will use the allele\n\t\totherwise decide by position/range\n\t\thttps://varnomen.hgvs.org/recommendations/DNA/variant/deletion/\n\n\tinsertion\n\t\tchr5:g.171410539_171410540insTCTG\n\t\tparse to chr5.171410539.-.TCTG\n\t*/\n\tallowVariant?: boolean\n}\n\n/** \"start/stop\" are included when entered a coordinate or the coord is mapped from a gene/snp */\ntype GeneOrSNPResult = { start: number; stop: number; ref?: string; alt?: string[] | string }\n/** \"pos/ref/alt\" are included when entered a variant */\ntype VariantResult = { pos: number; ref: string; alt: string; isVariant: boolean }\ntype ResultArg = (GeneOrSNPResult | VariantResult) & {\n\t/** is always included */\n\tchr: string\n}\n\ntype Result = Partial<GeneOrSNPResult> &\n\tPartial<VariantResult> & {\n\t\tgeneSymbol?: string\n\t\tfromWhat?: string\n\t\tchr?: string\n\t\tsearchbox?: any\n\t\tgenes?: { geneSymbol: string }[]\n\t\t/** Original position and length from string2pos(). Present for any\n\t\t * coordinate input (position is the start, len is stop - start).\n\t\t * Useful for recovering exact coordinates when string2pos() expands\n\t\t * small ranges to a 400bp minimum span for the genome browser. */\n\t\tactualposition?: { position: number; len: number }\n\t}\n\nexport const debounceDelay = 500\n\n/*************************************\nby calling addGeneSearchbox(), it redirectly returns a RESULT object detailed below without await\n*/\nexport function addGeneSearchbox(arg: GeneSearchBoxArg) {\n\tconst tip = arg.tip,\n\t\trow = arg.row\n\tconst result: Result = {}\n\n\t// validate arg\n\ttry {\n\t\tif (typeof arg.genome != 'object') throw 'genome not object'\n\t\tif (arg.searchOnly) {\n\t\t\tif (arg.searchOnly != 'gene' && arg.searchOnly != 'genes' && arg.searchOnly != 'snp')\n\t\t\t\tthrow 'searchOnly not gene/genes/snp'\n\t\t\tif (arg.searchOnly == 'snp' && !arg.genome.hasSNP) throw 'Cannot support .searchOnly = \"snp\". Genome lacks SNP'\n\t\t}\n\t\tif (arg.allowVariant) {\n\t\t\tif (arg.searchOnly == 'gene' || arg.searchOnly == 'genes')\n\t\t\t\tthrow 'when allowVariant is true, searchOnly cannot be gene/genes'\n\t\t}\n\t} catch (e) {\n\t\trow.append('span').text(e)\n\t\treturn result\n\t}\n\n\tlet placeholder: string,\n\t\twidth = 150\n\n\tif ('placeholder' in arg) {\n\t\tplaceholder = arg.placeholder!\n\t} else if (arg?.searchOnly == 'gene') {\n\t\tplaceholder = 'Gene'\n\t\twidth = 100 // use shorter width for inputting only one gene name\n\t} else if (arg?.searchOnly == 'genes') {\n\t\tplaceholder = 'Gene names'\n\t\twidth = 200\n\t} else {\n\t\tplaceholder = arg?.searchOnly == 'snp' ? 'Position' : 'Gene, position'\n\t\tif (arg.genome.hasSNP) {\n\t\t\tplaceholder += ', dbSNP'\n\t\t\twidth += 40\n\t\t}\n\t\tif (arg.allowVariant) {\n\t\t\tplaceholder += ', variant'\n\t\t\twidth += 40\n\t\t}\n\t}\n\n\tconst searchbox = row\n\t\t.append('input')\n\t\t.attr('type', 'search')\n\t\t.attr('placeholder', placeholder)\n\t\t.attr('aria-label', 'Gene symbol, position, or alias')\n\t\t.property('disabled', arg.disableInput || false)\n\t\t.attr('class', 'sja_genesearchinput')\n\t\t.attr('data-testid', arg.testid || 'sja_genesearchinput')\n\t\t.style('width', width + 'px')\n\n\tresult.searchbox = searchbox\n\n\tsearchbox\n\t\t.on('focus', event => {\n\t\t\tevent.target.select()\n\t\t})\n\t\t.on('keyup', async event => {\n\t\t\tconst input = event.target\n\t\t\tconst v = input.value.trim()\n\n\t\t\tif (arg.emptyInputCallback && v.length == 0 && keyupEnter(event)) {\n\t\t\t\ttip.hide()\n\t\t\t\targ.emptyInputCallback()\n\t\t\t\tsearchStat.word.text('')\n\t\t\t\tsearchStat.mark.html('')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (v.length <= 1) return tip.hide()\n\n\t\t\t// typed 2 or more chars, prompt user to press enter to search\n\t\t\tsearchStat.mark.html('')\n\t\t\tsearchStat.word.style('font-size', '0.7em')\n\t\t\tif (arg.hideHelp) {\n\t\t\t\t// won't show prompt. must clear any old contents in word\n\t\t\t\tsearchStat.word.text('')\n\t\t\t} else {\n\t\t\t\t// will show prompt and old contents are cleared\n\t\t\t\tsearchStat.word.text('Press ENTER to search, ESC to cancel')\n\t\t\t}\n\n\t\t\tif (keyupEnter(event)) {\n\t\t\t\tsearchbox.property('disabled', true)\n\t\t\t\t// pressed enter\n\n\t\t\t\t// this call may repeat the last debounced checkInput using debouncer(),\n\t\t\t\t// but it's safer to call it again in case the Enter key was pressed after the debounceDelay\n\t\t\t\t// to ensure that the applicable /genelookup has finished before detecting/displaying errors.\n\t\t\t\t// In contrast, the previous Promise + setInterval + resolve detection is not reliable,\n\t\t\t\t// because there might not be a pending checkInput() call to reset the emptied currLookupValue.\n\t\t\t\tawait checkInput()\n\n\t\t\t\t// try to parse as gene\n\t\t\t\t// get first gene match from menu\n\t\t\t\tif (arg?.searchOnly != 'snp') {\n\t\t\t\t\tconst hitgene = tip.d.select(\".sja_menuoption[isgene='1']\")\n\t\t\t\t\tif (hitgene.size()) {\n\t\t\t\t\t\t// showing a matched gene in tip\n\t\t\t\t\t\tconst geneSymbol = hitgene.datum()\n\t\t\t\t\t\tif (arg.searchOnly == 'gene' || arg.searchOnly == 'genes') {\n\t\t\t\t\t\t\tgetResult({ geneSymbol }, geneSymbol)\n\t\t\t\t\t\t\t// hit is found. hide gene tip and blur input\n\t\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\t\tinput.blur()\n\t\t\t\t\t\t\t// cancel debouncer to prevent repeating gene search and tip from showing up again\n\t\t\t\t\t\t\tdebouncer.clear()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tawait geneCoordSearch(geneSymbol)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\t\t// must not clear tip, genes on multiple loci will show as further options\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// no matched gene in tip\n\t\t\t\t\tif (arg.searchOnly == 'genes') {\n\t\t\t\t\t\tconst validGenes = await parseMultiGenes(v)\n\t\t\t\t\t\tif (validGenes?.length) {\n\t\t\t\t\t\t\tgetResult({ genes: validGenes }, `${validGenes.length} gene${validGenes.length > 1 ? 's' : ''}`)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tgetResult(null, 'Gene not found')\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\tinput.blur()\n\t\t\t\t\t\tdebouncer.clear()\n\t\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (arg?.searchOnly == 'gene') {\n\t\t\t\t\tgetResult(null, 'Gene not found')\n\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// try to parse as variant format (chr.pos.ref.alt)\n\t\t\t\tif (arg.allowVariant) {\n\t\t\t\t\tconst variant = await string2variant(v, arg.genome)\n\t\t\t\t\tif (variant) {\n\t\t\t\t\t\tgetResult(variant, v)\n\t\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// try to parse as snp (i.e., dbsnp entry)\n\t\t\t\t// get first snp match from menu\n\t\t\t\tconst hitsnp = tip.d.select(\".sja_menuoption[issnp='1']\")\n\t\t\t\tif (hitsnp.size()) {\n\t\t\t\t\t// snp match\n\t\t\t\t\tconst hit = hitsnp.datum()\n\t\t\t\t\tgetResult(\n\t\t\t\t\t\t{ chr: hit.chrom, start: hit.chromStart, stop: hit.chromEnd, ref: hit.ref, alt: hit.alt },\n\t\t\t\t\t\thit.name || v\n\t\t\t\t\t)\n\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\ttip.hide()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (arg?.searchOnly == 'snp') {\n\t\t\t\t\tgetResult(null, 'Variant not found')\n\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// try to parse as coord\n\t\t\t\tconst pos = string2pos(v, arg.genome)\n\t\t\t\tif (pos) {\n\t\t\t\t\tgetResult(pos, 'Valid coordinate')\n\t\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// no match\n\t\t\t\tgetResult(null, 'No match')\n\t\t\t\tsearchbox.property('disabled', false)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (event.code == 'Escape') {\n\t\t\t\t// abandon changes to <input>\n\t\t\t\ttip.hide()\n\t\t\t\tif (result.chr) {\n\t\t\t\t\tgetResult(result, result.fromWhat!)\n\t\t\t\t} else if (arg.defaultCoord) {\n\t\t\t\t\tconst d = arg.defaultCoord as Result\n\t\t\t\t\tinput.value = d.chr + (d.isVariant ? '.' + d.pos + '.' + d.ref + '.' + d.alt : ':' + d.start + '-' + d.stop)\n\t\t\t\t}\n\t\t\t\tinput.blur()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (event.key == 'ArrowDown') {\n\t\t\t\ttip.d\n\t\t\t\t\t.selectAll('.sja_menuoption')\n\t\t\t\t\t.attr('tabindex', 0)\n\t\t\t\t\t.on('keyup', event => {\n\t\t\t\t\t\tif (event.key == 'Enter') {\n\t\t\t\t\t\t\tevent.target.click()\n\t\t\t\t\t\t} else if (event.key == 'ArrowDown') {\n\t\t\t\t\t\t\tif (event.target.nextSibling) event.target.nextSibling.focus()\n\t\t\t\t\t\t} else if (event.key == 'ArrowUp') {\n\t\t\t\t\t\t\tif (event.target.previousSibling) event.target.previousSibling.focus()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\ttip.d.select('.sja_menuoption').node().focus()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdebouncer()\n\t\t})\n\n\t// focusOff fix for jerky (unsmooth) app drawer sliding.\n\t// App drawer slide animation very jerky when .focus() is applied to any\n\t// input box. Set focusOff: true to smoothly execute animations.\n\tif (!arg.focusOff) searchbox.node().focus()\n\tconst searchStat = {\n\t\tmark: row.append('span').style('margin-left', '5px'),\n\t\tword: row.append('span').style('margin-left', '5px').style('font-size', '.8em').style('opacity', 0.6)\n\t}\n\n\tasync function checkInput() {\n\t\t// checking input format\n\t\tconst v = searchbox.property('value').trim()\n\t\tif (!v) return\n\n\t\ttip.showunder(searchbox.node()).clear()\n\n\t\t// Handle multiple gene search mode\n\t\tif (arg?.searchOnly == 'genes') {\n\t\t\tconst lst = v\n\t\t\t\t.split(/[,\\s\\t\\n]+/)\n\t\t\t\t.map(name => name.trim())\n\t\t\t\t.filter(name => name.length > 0)\n\n\t\t\tif (lst.length === 0) return\n\t\t\tif (lst.length == 1) {\n\t\t\t\t// just one name. pass through to single gene handling\n\t\t\t} else {\n\t\t\t\t// multiple strings from input, won't verify them now. only verify on hitting Enter\n\t\t\t\ttip.hide()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// see if input is gene\n\t\tif (arg?.searchOnly != 'snp') {\n\t\t\tconst gene = await dofetch3('genelookup', { body: { genome: arg.genome.name, input: v } })\n\t\t\tif (gene.error) {\n\t\t\t\ttip.d.append('div').style('margin', '5px').text(gene.error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (gene.hits?.length) {\n\t\t\t\ttip.d\n\t\t\t\t\t.selectAll('div')\n\t\t\t\t\t.data(gene.hits)\n\t\t\t\t\t.join('div')\n\t\t\t\t\t.text(d => d)\n\t\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t\t.attr('data-testid', d => `sjpp-genesearch-gene-hit-${d.toLowerCase().replace(/\\s/g, '-')}`)\n\t\t\t\t\t.style('border-radius', '0px')\n\t\t\t\t\t.attr('isgene', 1)\n\t\t\t\t\t.on('click', async (event, d) => {\n\t\t\t\t\t\tif (arg?.searchOnly == 'gene' || arg.searchOnly == 'genes') {\n\t\t\t\t\t\t\t// finding gene only, got result\n\t\t\t\t\t\t\tgetResult({ geneSymbol: d }, d)\n\t\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// convert gene symbol to coord\n\t\t\t\t\t\t\tawait geneCoordSearch(d)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\treturn // found gene hits and shown in tip. done\n\t\t\t}\n\t\t\t// no gene hit; continue for coordinate, variant, snp FIXME unclear logic..\n\t\t}\n\n\t\t// see if input is in variant format (chr.pos.ref.alt)\n\t\tif (arg.allowVariant) {\n\t\t\tconst variant = await string2variant(v, arg.genome)\n\t\t\tif (variant) return\n\t\t}\n\n\t\tif (arg.genome.hasSNP) {\n\t\t\t// has snp; test if input is dbsnp id\n\t\t\tconst dbsnp = await dofetch3('snp', { body: { byName: true, genome: arg.genome.name, lst: [v] } }) // FIXME expensive! only search when searchOnly=snp\n\t\t\tif (dbsnp.error) throw dbsnp.error\n\t\t\tif (dbsnp?.results?.length) {\n\t\t\t\t// display hits in menu\n\t\t\t\tdisplayVariantHits(tip, dbsnp.results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// see if input is coord\n\t\tconst pos = string2pos(v, arg.genome, true)\n\t\tif (pos) {\n\t\t\tif (arg?.searchOnly == 'snp') {\n\t\t\t\t// only search for snps\n\t\t\t\t// query dbsnp for snps with matching positions\n\t\t\t\t// TODO: querying a position query where start=stop (e.g.,\n\t\t\t\t// chr1:3-3) is currently not supported, but it should be.\n\t\t\t\t// This should be supported when string2pos() is changed\n\t\t\t\t// to always output 0-based position/coordinate (see the\n\t\t\t\t// TODO below)\n\t\t\t\tif (!pos.actualposition?.len) return\n\t\t\t\tconst chr = pos.chr\n\t\t\t\tconst start = pos.actualposition.position - 1 // convert to 0-based // TODO: should change string2pos() to always output 0-based position/coordinate\n\t\t\t\tconst stop = start + pos.actualposition.len\n\t\t\t\tconst ranges = [{ start, stop }]\n\t\t\t\tconst dbsnp = await dofetch3('snp', { body: { byCoord: true, genome: arg.genome.name, chr, ranges } })\n\t\t\t\tif (dbsnp.error) throw dbsnp.error\n\t\t\t\tif (dbsnp.results.length) {\n\t\t\t\t\t/* dbsnp hits found\n\t\t\t\t\t- hits will include variants whose coordinates overlap\n\t\t\t\t\twith, but may not match the query coordinates (e.g.,\n\t\t\t\t\tan indel will overlap with query coordinates, but its start coordinate may not match query start coordinate)\n\t\t\t\t\t- if query is for multiple bases (e.g., chr1:1-5), then\n\t\t\t\t\tdisplay all hits\n\t\t\t\t\t- if query is for a single base (e.g., chr1:3 or\n\t\t\t\t\tchr1:3-4), then display hits whose start coordinate matches the query start coordinate*/\n\t\t\t\t\tconst variants =\n\t\t\t\t\t\tpos.actualposition.len == 1 ? dbsnp.results.filter(hit => hit.chromStart == start) : dbsnp.results\n\t\t\t\t\t// display variants in menu\n\t\t\t\t\tdisplayVariantHits(tip, variants)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tconst debouncer = debounce(checkInput, debounceDelay)\n\n\tasync function parseMultiGenes(v) {\n\t\tconst lst = v\n\t\t\t.split(/[,\\s\\t\\n]+/)\n\t\t\t.map(name => name.trim())\n\t\t\t.filter(name => name.length > 0)\n\n\t\t// Validate each gene name\n\t\tconst validGenes: { geneSymbol: string }[] = []\n\t\t//let invalidCount = 0 // may report later\n\n\t\tfor (const s of lst) {\n\t\t\tconst gene = await dofetch3('genelookup', { body: { genome: arg.genome.name, input: s } })\n\t\t\tif (!gene || gene.error || !gene.hits?.length) {\n\t\t\t\t//invalidCount++\n\t\t\t} else {\n\t\t\t\t// Use the first hit as the validated gene symbol\n\t\t\t\tvalidGenes.push({ geneSymbol: gene.hits[0] })\n\t\t\t}\n\t\t}\n\t\treturn validGenes\n\t}\n\n\tfunction displayVariantHits(tip, data) {\n\t\ttip.d\n\t\t\t.selectAll('div')\n\t\t\t.data(data)\n\t\t\t.join('div')\n\t\t\t.text(d => {\n\t\t\t\tconst pos = `${d.chrom}:${d.chromStart + 1}`\n\t\t\t\tconst alleles = `${d.ref}>${d.alt.join(',')}`\n\t\t\t\treturn `${d.name} (${pos} ${alleles})`\n\t\t\t})\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('data-testid', d => `sjpp-genesearch-snp-hit-${d.name.toLowerCase().replace(/\\s/g, '-')}`)\n\t\t\t.style('border-radius', '0px')\n\t\t\t.attr('issnp', 1)\n\t\t\t.on('click', (event, d) => {\n\t\t\t\tgetResult({ chr: d.chrom, start: d.chromStart, stop: d.chromEnd, ref: d.ref, alt: d.alt }, d.name)\n\t\t\t\ttip.hide()\n\t\t\t})\n\t}\n\n\tasync function geneCoordSearch(geneSymbol: string) {\n\t\t// geneSymbol is a valid gene symbol\n\t\t// retrieve its coordinates\n\t\ttip.hide()\n\t\tconst data = await dofetch3('genelookup', { body: { genome: arg.genome.name, input: geneSymbol, deep: 1 } })\n\t\tif (data.error) throw data.error\n\t\tif (!data.gmlst?.length) throw 'cannot retrieve gene coordinates'\n\t\tconst loci = gmlst2loci(data.gmlst)\n\t\tif (loci.length == 1) {\n\t\t\t// all isoforms are at the same locus\n\t\t\tgetResult(loci[0], geneSymbol, geneSymbol)\n\t\t\treturn\n\t\t}\n\t\t// isoforms are spread across multiple discontinuous loci\n\t\ttip.showunder(searchbox.node()).clear()\n\t\ttip.d\n\t\t\t.selectAll('div')\n\t\t\t.data(loci)\n\t\t\t.join('div')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('data-testid', d => `sjpp-genesearch-isoform-hit-${d.name.toLowerCase().replace(/\\s/g, '-')}`)\n\t\t\t.style('border-radius', '0px')\n\t\t\t.text(d => d.name + ' ' + d.chr + ':' + d.start + '-' + d.stop)\n\t\t\t.on('click', (event, d) => {\n\t\t\t\ttip.hide()\n\t\t\t\tgetResult(d, geneSymbol + ', ' + d.name, d.name)\n\t\t\t})\n\t}\n\n\tif (arg.defaultCoord) {\n\t\tconst d = arg.defaultCoord as Result\n\t\tif (d.isVariant) {\n\t\t\tsearchbox.property('value', d.chr + '.' + d.pos + '.' + d.ref + '.' + d.alt)\n\t\t\tresult.pos = d.pos\n\t\t\tresult.ref = d.ref\n\t\t\tresult.alt = d.alt\n\t\t} else {\n\t\t\tsearchbox.property('value', d.chr + ':' + d.start + '-' + d.stop)\n\t\t\tresult.start = d.start\n\t\t\tresult.stop = d.stop\n\t\t}\n\t\tresult.chr = d.chr\n\t}\n\n\t/* call to show a valid result, or error\n if result is valid, provide r: {chr,start,stop} to show coord in <input>, also show ✓\n if result is invalid, r is null, show ✗\n fromWhat is optional gene or snp name to show in search stat\n */\n\tasync function getResult(r: Partial<Result> | null, fromWhat: string, geneSymbol?: string) {\n\t\tif (r) {\n\t\t\t// got hit (coord or variant), clear result{}\n\t\t\tfor (const k in result) delete result[k]\n\t\t\tif (r.isVariant) {\n\t\t\t\t// do not update searchbox\n\t\t\t\tresult.chr = r.chr\n\t\t\t\tresult.pos = r.pos\n\t\t\t\tresult.ref = r.ref\n\t\t\t\tresult.alt = r.alt\n\t\t\t} else if (r.chr) {\n\t\t\t\t// is coord\n\t\t\t\tsearchbox.property('value', r.chr + ':' + r.start + '-' + r.stop)\n\t\t\t\tresult.chr = r.chr\n\t\t\t\tresult.start = r.start\n\t\t\t\tresult.stop = r.stop\n\t\t\t\tif (r.actualposition) result.actualposition = r.actualposition\n\t\t\t\tif (r.ref) result.ref = r.ref\n\t\t\t\tif (r.alt) result.alt = r.alt\n\t\t\t} else if (r.geneSymbol) {\n\t\t\t\t// is only a gene symbol\n\t\t\t\tsearchbox.property('value', r.geneSymbol)\n\t\t\t\tresult.geneSymbol = r.geneSymbol\n\t\t\t} else if (r.genes) {\n\t\t\t\tresult.genes = r.genes\n\t\t\t}\n\n\t\t\tsearchStat.mark.style('color', 'green').html('✓')\n\n\t\t\tif (geneSymbol) {\n\t\t\t\t// tell caller they found a gene\n\t\t\t\tresult.geneSymbol = geneSymbol\n\t\t\t}\n\t\t} else {\n\t\t\t// no hit\n\t\t\tsearchStat.mark.style('color', 'red').html('✗')\n\t\t}\n\t\tsearchStat.word.text(fromWhat || '')\n\n\t\t// fromWhat is the original search string. pass it to caller as extra piece of info\n\t\t// useful when user enters isoform accession and matches to genesymbol,\n\t\t// and wants to be able to refer back to which isoform was entered\n\t\tresult.fromWhat = fromWhat\n\n\t\tif (r && arg.callback) {\n\t\t\tif (arg.hideInputBeforeCallback) {\n\t\t\t\t// hide this search box after getting the results\n\t\t\t\tsearchbox.style('display', 'none') // hide input\n\t\t\t\targ.row.selectAll(':scope>span').style('display', 'none') // hide input label, checkbox\n\t\t\t}\n\t\t\t// has valid result, trigger callback (no need to await?)\n\t\t\tawait arg.callback()\n\t\t}\n\t}\n\n\t// need to capture arg.geneSymbol into another variable,\n\t// to pass type check and to have it is a \"static\" value when the timeout callback is called,\n\t// since using arg.geneSymbol directly is not guaranteed to have the same value after the timeout\n\tconst geneSymbol = arg.geneSymbol || ''\n\tif (geneSymbol) {\n\t\tsearchbox.property('value', geneSymbol)\n\t\tif (arg.triggerSearch)\n\t\t\tsearchbox.node().dispatchEvent(\n\t\t\t\tnew KeyboardEvent('keyup', {\n\t\t\t\t\tkey: 'Enter',\n\t\t\t\t\tcode: 'Enter',\n\t\t\t\t\tkeyCode: 13, // deprecated but still widely used\n\t\t\t\t\twhich: 13, // deprecated but still widely used\n\t\t\t\t\tbubbles: true, // important to allow the event to bubble up\n\t\t\t\t\tcancelable: true\n\t\t\t\t})\n\t\t\t)\n\t\telse setTimeout(() => getResult({ geneSymbol: arg.geneSymbol }, geneSymbol), 10)\n\t}\n\n\treturn result\n}\n\nexport async function string2variant(v: string, genome: ClientGenome) {\n\t// try to parse as simple variant\n\tconst variant = string2simpleVariant(v, genome)\n\tif (variant) {\n\t\t// is a simple variant, return\n\t\treturn variant\n\t}\n\t// try to parse hgvs; if successful, return variant; otherwise return null as not a variant\n\treturn await string2hgvs(v, genome)\n}\n\nfunction string2simpleVariant(v: string, genome: ClientGenome) {\n\t// format: chr.pos.ref.alt\n\t// this format has conflict with hgvs e.g. NG_012232.1(NM_004006.2):c.93+1G>T\n\t// which is in fact not currently supported by this code\n\t// if it fails, return false and parse as hgvs next\n\tconst tmp = v.split('.')\n\tif (tmp.length != 4) return\n\tconst chr = tmp[0]\n\tconst pos = Number(tmp[1])\n\tconst e = invalidcoord(genome, chr, pos, pos)\n\tif (e) return\n\treturn {\n\t\tisVariant: true,\n\t\tchr,\n\t\tpos,\n\t\tref: tmp[2],\n\t\talt: tmp[3]\n\t}\n}\n\nasync function string2hgvs(v: string, genome: ClientGenome) {\n\tconst tmp = v.split(':g.')\n\tif (tmp.length != 2) {\n\t\t// only supports \"g.\" linear genomic reference. other ref types are not supported for now\n\t\treturn\n\t}\n\tconst chr = tmp[0]\n\n\t// if 'delins' is present, it can only be parsed as mnv (substitution)\n\tif (tmp[1].includes('delins')) {\n\t\treturn await hgvs_delins(chr, tmp[1], genome)\n\t}\n\t// if 'delins' is absent but 'del' is found, can only be parsed as deletion\n\tif (tmp[1].includes('del')) {\n\t\treturn await hgvs_del(chr, tmp[1], genome)\n\t}\n\t// if 'delins, del' are absent and 'ins' is found, can only be parsed as insertion\n\tif (tmp[1].includes('ins')) {\n\t\treturn hgvs_ins(chr, tmp[1])\n\t}\n\t// 'delins, del, ins' are all absent. can only be parsed as snv\n\treturn hgvs_snv(chr, tmp[1])\n}\n\nfunction hgvs_snv(chr: string, v: string) {\n\t// v: 104780214C>T\n\tconst tmp = v.match(/^(\\d+)([ATCG])>([ATCG])$/)\n\tif (!tmp || tmp.length != 4) {\n\t\t// not matching the required snv pattern\n\t\treturn\n\t}\n\t// tmp: ['104780214C>T', '104780214', 'C', 'T']\n\tconst pos = Number(tmp[1])\n\tif (!Number.isInteger(pos)) return\n\treturn {\n\t\tisVariant: true,\n\t\tchr,\n\t\tpos,\n\t\tref: tmp[2],\n\t\talt: tmp[3]\n\t}\n}\n\nfunction hgvs_ins(chr: string, v: string) {\n\t// chr5:g.171410539_171410540insTCTG\n\tconst [tmppos, altAllele] = v.split('ins')\n\tif (!altAllele) return\n\tconst pos = Number(tmppos.split('_')[0])\n\tif (!Number.isInteger(pos)) return\n\treturn {\n\t\tisVariant: true,\n\t\tchr,\n\t\tpos: pos + 1, // \"pos1_pos2\" from hgvs string means insertion between the two nucleotides\n\t\t// should use pos2 when ref allele is missing\n\t\tref: '-',\n\t\talt: altAllele\n\t}\n}\n\nasync function hgvs_del(chr: string, v: string, genome: ClientGenome) {\n\t//chr17:g.7673802delCGCACCTCAAAGCTGTTC\n\tconst [tmppos, refAllele] = v.split('del')\n\tif (refAllele) {\n\t\t// deleted ref nt is given, simply parse position and done\n\t\tconst pos = Number(tmppos.split('_')[0])\n\t\tif (!Number.isInteger(pos)) return\n\t\treturn {\n\t\t\tisVariant: true,\n\t\t\tchr,\n\t\t\tpos,\n\t\t\tref: refAllele,\n\t\t\talt: '-'\n\t\t}\n\t}\n\t// deleted ref nt is not given. this info is coded in tmppos, either \"333\" or \"333_334\"\n\t//e.g. chr2:g.119955155_119955159del\n\tconst [t1, t2] = tmppos.split('_')\n\tconst start = Number(t1)\n\tconst stop = t2 ? Number(t2) : start + 1\n\tif (!Number.isInteger(start) || !Number.isInteger(stop)) return\n\tconst refAllele2 = await getRefAllele(chr, start, stop, genome)\n\treturn {\n\t\tisVariant: true,\n\t\tchr,\n\t\t// pos, No variable to access??\n\t\tref: refAllele2,\n\t\talt: '-'\n\t}\n}\n\nasync function hgvs_delins(chr: string, v: string, genome: ClientGenome) {\n\t// chr2:g.119955155_119955159delinsTTTTT\n\tconst tmp = v.match(/^(\\d+)_(\\d+)delins([ATCG]+)$/)\n\tif (!tmp || tmp.length != 4) {\n\t\t// does not match with expected format\n\t\treturn\n\t}\n\tconst p1 = Number(tmp[1]),\n\t\tp2 = Number(tmp[2]),\n\t\taltAllele = tmp[3]\n\tif (!Number.isInteger(p1) || !Number.isInteger(p2)) return\n\tconst refAllele = await getRefAllele(chr, p1, p2, genome)\n\treturn {\n\t\tisVariant: true,\n\t\tchr,\n\t\tpos: p1,\n\t\tref: refAllele,\n\t\talt: altAllele\n\t}\n}\n\nasync function getRefAllele(chr: string, start: number, stop: number, genome: ClientGenome) {\n\tconst body = {\n\t\tcoord: chr + ':' + start + '-' + stop,\n\t\tgenome: genome.name\n\t}\n\tconst d = await dofetch3('ntseq', { body })\n\treturn d.seq\n}\n", "import type { Button, Div } from '../../types/d3'\n\ntype AddBtnOpts = {\n\t/** div to append the button */\n\tdiv: Div\n\t/** text to display on button */\n\ttext: string\n\t/** callback on click */\n\tcallback: () => void\n\t/** Optional: default is false */\n\tdisabled?: boolean\n\t/** Change button display based on caller logic */\n\tgetDisplayStyle?: () => string\n\ttestid?: string\n}\n/**\n * Creates a button uniform in style for the entire UI\n */\nexport function addButton(opts: AddBtnOpts): Button {\n\tif (!opts.div || !opts.text || !opts.callback) throw new Error('Missing required parameters')\n\tconst btn = opts.div\n\t\t.append('button')\n\t\t.property('disabled', opts.disabled || false)\n\t\t.style('display', opts.getDisplayStyle ? opts.getDisplayStyle() : '')\n\t\t.style('border', 'none')\n\t\t.style('border-radius', '20px')\n\t\t.style('padding', '10px 15px')\n\t\t.text(opts.text)\n\t\t.on('click', () => {\n\t\t\topts.callback()\n\t\t})\n\tif (opts.testid) btn.attr('data-testid', opts.testid)\n\treturn btn\n}\n", "import { select as d3select } from 'd3-selection'\nimport type { Elem } from '../../types/d3'\n\nexport function makeRadiosWithContentDivs(options: any, div: Elem) {\n\tconst divs = div\n\t\t.selectAll()\n\t\t.data(options, (d: any) => d.value)\n\t\t.enter()\n\t\t.append('div')\n\t\t.style('margin', '5px')\n\n\tconst labels = divs.append('label').on('mousedown', (event: Event) => {\n\t\tevent.stopPropagation()\n\t})\n\n\tconst inputs = labels\n\t\t.append('input')\n\t\t.attr('type', 'radio')\n\t\t.attr('name', (d: any) => d.label)\n\t\t.attr('value', (d: any) => d.value)\n\t\t.property('checked', (d: any) => d.checked)\n\t\t.on('input', async function (this: any, event: Event, d: any) {\n\t\t\tevent.stopPropagation()\n\t\t\tinputs.property('disabled', true)\n\t\t\tinputs.property('checked', false)\n\t\t\tdiv.selectAll('.contentDiv').style('display', 'none')\n\n\t\t\tconst contentDiv = d3select(this.parentNode)\n\t\t\t\t.append('div')\n\t\t\t\t.classed('contentDiv', true)\n\t\t\t\t.style('padding-left', '25px')\n\t\t\t\t.style('display', 'block')\n\n\t\t\tawait d.callback(contentDiv)\n\t\t\td3select(this).property('checked', true)\n\t\t\tinputs.property('disabled', false)\n\t\t})\n\n\tinputs.filter((d: any) => d.checked).property('checked', true)\n\n\tlabels.append('span').html((d: any) => ' ' + d.label)\n\n\t// Using an if statement to add the sublabel here\n\t// causes the linter to fuss\n\tlabels\n\t\t.append('span')\n\t\t.style('display', 'block')\n\t\t.style('padding-left', '25px')\n\t\t.style('font-size', '0.75em')\n\t\t.html((d: any) => d.sublabel || '')\n}\n", "import type { Menu } from '#dom'\nimport type { Div, Elem } from '../../types/d3'\nimport type { GeneArgumentEntry } from '#types'\nimport { addButton } from './addButton.ts'\nimport { make_one_checkbox } from '../checkbox.js'\nimport { makeRadiosWithContentDivs } from './radioWithContent.ts'\nimport { debounce } from 'debounce'\nimport type { ClientGenome } from '../../types/clientGenome'\n\ntype GenesMenuArgs = {\n\t/** tip holder for displaying the Menu */\n\ttip: Menu\n\tgenome: ClientGenome\n\t/** object sent from the view model\n\t * .param is the defined arg from the dataset\n\t * .input is the element created in addParameter and returned\n\t * to the view model\n\t */\n\tparams: { param: GeneArgumentEntry; input?: Elem }[]\n\t/** Called when 'Calculate genes' is clicked */\n\tcallback: (f?: number) => void\n\t/** Adds nested .options: [] for parameters back to opts\n\t * after rendering to avoid duplicate elements\n\t */\n\taddOptionalParams: ({ param, input }) => void\n}\n\nexport class GenesMenu {\n\ttip: Menu\n\tgenome: ClientGenome\n\tparams: { param: GeneArgumentEntry; input?: Elem }[]\n\tcallback: (f?: number) => void\n\taddOptionalParams: ({ param, input }) => void\n\t/** Collects nested param .options:[] for submenus. See 'boolean' type. */\n\treadonly params2Add: { param: GeneArgumentEntry; input: Elem }[] = []\n\n\tconstructor(opts: GenesMenuArgs) {\n\t\tthis.tip = opts.tip\n\t\tthis.genome = opts.genome\n\t\tthis.params = opts.params\n\t\tthis.callback = opts.callback\n\t\tthis.addOptionalParams = opts.addOptionalParams\n\n\t\tthis.tip.d.style('padding', '15px')\n\t\tthis.render()\n\n\t\tfor (const param of this.params2Add) this.addOptionalParams(param)\n\t}\n\n\trender() {\n\t\tfor (const param of this.params) {\n\t\t\tconst input = this.addParameter(param.param, this.tip.d.append('div'))\n\t\t\tparam.input = input\n\t\t}\n\t\t/** Prevents the gene set edit ui disappearing when clicking \n\t\twithin this menu. User can still click the gene set edit ui\n\t\tto close this menu. */\n\t\tthis.tip.d.on('mousedown', (event: Event) => {\n\t\t\tevent.stopPropagation()\n\t\t})\n\t\t//Submits all the inputs from the menu to the callback\n\t\tconst calGenesBtn = addButton({\n\t\t\tdiv: this.tip.d.append('div').style('padding', '20px').style('display', 'inline-block'),\n\t\t\ttext: 'Calculate genes',\n\t\t\tcallback: async () => {\n\t\t\t\tcalGenesBtn.property('disabled', true).text('Loading...')\n\t\t\t\tawait this.callback()\n\t\t\t\tthis.tip.hide()\n\t\t\t}\n\t\t})\n\t}\n\n\taddParameter(param, div: Div) {\n\t\tlet input\n\t\tif (param.type == 'boolean') {\n\t\t\tif (param?.options?.length) {\n\t\t\t\t/* ** Submenu ** \n\t\t\t\tUse checkbox to expand div for additional options when checked. */\n\t\t\t\tconst holder = div.append('div').attr('data-testid', 'sjpp-submenu-checkbox').style('padding', '2px')\n\t\t\t\tconst contentDiv = div.append('div').style('padding-left', '20px')\n\t\t\t\tinput = make_one_checkbox({\n\t\t\t\t\tholder: holder,\n\t\t\t\t\tid: param.id,\n\t\t\t\t\tchecked: param.checked,\n\t\t\t\t\tlabeltext: param.label,\n\t\t\t\t\tcallback: () => {\n\t\t\t\t\t\tcontentDiv.style('display', input.property('checked') ? 'block' : 'none')\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tinput.on('mousedown', (event: Event) => {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t})\n\t\t\t\tfor (const option of param.options) {\n\t\t\t\t\tconst optionInput = this.addParameter(option, contentDiv.append('div'))\n\t\t\t\t\toption.parentId = param.id\n\t\t\t\t\tthis.params2Add.push({ param: option, input: optionInput })\n\t\t\t\t}\n\t\t\t\tcontentDiv.style('display', input.property('checked') ? 'block' : 'none')\n\t\t\t} else {\n\t\t\t\tinput = div.append('input').style('padding', '2px').attr('type', 'checkbox').attr('id', param.id)\n\t\t\t\tif (param.value) input.property('checked', param.value)\n\t\t\t\tthis.addLabels(div, 'label', param)\n\t\t\t}\n\t\t}\n\t\t//The parameter value will be used as the input value if the option is checked\n\t\telse if (param.type == 'string' && param.value) {\n\t\t\tinput = make_one_checkbox({\n\t\t\t\tholder: div,\n\t\t\t\tid: param.id,\n\t\t\t\tchecked: true,\n\t\t\t\tlabeltext: param.label,\n\t\t\t\tcallback: event => {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t}\n\t\t\t})\n\t\t} else if (param.type == 'number') {\n\t\t\tinput = div\n\t\t\t\t.append('input')\n\t\t\t\t.attr('type', 'number')\n\t\t\t\t.style('width', '50px')\n\t\t\t\t.style('padding', '5px')\n\t\t\t\t.attr('id', param.id)\n\t\t\tif (param.value) input.attr('value', param.value)\n\t\t\tthis.addLabels(div, 'span', param)\n\t\t} else if (param.type == 'radio') {\n\t\t\tconst hasChecked = param.options.find((d: any) => d.checked)\n\t\t\tif (!hasChecked) param.options[0].checked = true\n\t\t\tinput = div.append('div').attr('id', param.id)\n\t\t\tinput.append('p').style('font-size', '0.8em').style('opacity', 0.75).text(param.label)\n\t\t\tthis.addRadioValue(param)\n\t\t\tthis.addRadioCallbacks(param, this.genome)\n\t\t\tmakeRadiosWithContentDivs(param.options, input as any)\n\t\t}\n\t\treturn input\n\t}\n\n\taddLabels(div: Div, elem: string, param: GeneArgumentEntry) {\n\t\tif (!param.sublabel) div.append(elem).html(param.label!).attr('for', param.id)\n\t\telse {\n\t\t\tconst labelDiv = div.append('div').style('display', 'inline-block').style('vertical-align', 'middle')\n\t\t\tlabelDiv\n\t\t\t\t.append(elem)\n\t\t\t\t.style('display', 'block')\n\t\t\t\t.style('padding-top', '3px')\n\t\t\t\t.html(param.label!)\n\t\t\t\t.attr('for', param.id)\n\t\t\tlabelDiv.append('span').style('display', 'block').style('font-size', '0.75em').html(param.sublabel)\n\t\t}\n\t}\n\n\taddRadioValue(param) {\n\t\tif (param.value) return\n\t\tconst checked = param.options.find((d: any) => d.checked)\n\t\tif (checked) {\n\t\t\tparam.value = {\n\t\t\t\ttype: checked.value,\n\t\t\t\tgeneList: null\n\t\t\t}\n\t\t}\n\t}\n\n\taddRadioCallbacks(param, genome) {\n\t\tfor (const opt of param.options) {\n\t\t\tif (!opt.type) opt.type = 'boolean'\n\t\t\tif (opt.type == 'tree') {\n\t\t\t\topt.callback = async (holder: Elem) => {\n\t\t\t\t\tconst termdb = await import('../../termdb/app.js')\n\t\t\t\t\tconst treeDiv = holder.append('div')\n\t\t\t\t\tawait termdb.appInit({\n\t\t\t\t\t\tholder: treeDiv,\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\tdslabel: opt.value,\n\t\t\t\t\t\t\tgenome: genome.name,\n\t\t\t\t\t\t\tnav: {\n\t\t\t\t\t\t\t\theader_mode: 'search_only'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttree: {\n\t\t\t\t\t\t\tclick_term: (term: any) => {\n\t\t\t\t\t\t\t\tholder\n\t\t\t\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t\t\t\t.classed('ts_pill sja_filter_tag_btn sja_tree_click_term termlabel', true)\n\t\t\t\t\t\t\t\t\t.style('margin', '5px')\n\t\t\t\t\t\t\t\t\t.text(`${term.id}`)\n\t\t\t\t\t\t\t\tparam.value = {\n\t\t\t\t\t\t\t\t\ttype: opt.value,\n\t\t\t\t\t\t\t\t\tgeneList: term._geneset.map((t: any) => t.symbol)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttreeDiv.selectAll('*').remove()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (opt.type == 'text') {\n\t\t\t\topt.callback = async (holder: Elem) => {\n\t\t\t\t\tholder\n\t\t\t\t\t\t.append('span')\n\t\t\t\t\t\t.style('display', 'block')\n\t\t\t\t\t\t.style('font-size', '0.8em')\n\t\t\t\t\t\t.style('opacity', 0.75)\n\t\t\t\t\t\t.text('Enter genes separated by spaces or commas')\n\t\t\t\t\tholder\n\t\t\t\t\t\t.append('textarea')\n\t\t\t\t\t\t.style('display', 'block')\n\t\t\t\t\t\t.on(\n\t\t\t\t\t\t\t'keyup',\n\t\t\t\t\t\t\tdebounce(function (this: any) {\n\t\t\t\t\t\t\t\tconst geneList = this.value\n\t\t\t\t\t\t\t\t\t.split(/[\\s,]+/)\n\t\t\t\t\t\t\t\t\t.map((t: string) => t.trim())\n\t\t\t\t\t\t\t\t\t.filter((t: string) => t !== '')\n\t\t\t\t\t\t\t\tparam.value = {\n\t\t\t\t\t\t\t\t\ttype: opt.value,\n\t\t\t\t\t\t\t\t\tgeneList\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t500\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (opt.type == 'boolean') {\n\t\t\t\topt.callback = () => {\n\t\t\t\t\tparam.value = {\n\t\t\t\t\t\ttype: opt.value,\n\t\t\t\t\t\tgeneList: null\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { addGeneSearchbox } from '../genesearch.ts'\nimport { Menu } from '#dom'\nimport { select } from 'd3-selection'\nimport { mclass, dt2color, dt2label } from '#shared/common.js'\nimport { TermTypes } from '#shared/terms.js'\nimport type { Button, Div, Elem } from '../../types/d3'\nimport type { ClientGenome } from '../../types/clientGenome'\nimport type { GeneArgumentEntry } from '#types'\nimport { GenesMenu } from './GenesMenu'\nimport { addButton } from './addButton.ts'\nimport { dofetch3 } from '#common/dofetch'\nimport { getNormalRoot } from '#filter/filter'\n\ntype API = {\n\tdom: {\n\t\tholder: Div\n\t\t/** text links above the gene holding div\n\t\t * Opens a menu to select genes from different datasets\n\t\t */\n\t\ttextControlDiv: Div\n\t\t/** on click clears the gene holding div */\n\t\tclearBtn: Button\n\t\t/** on click populates the geneHoldingDiv with original gene list */\n\t\trestoreBtn: Button | null\n\t\t/** gene holding area, shows bunch of gene buttons pending submission */\n\t\tgeneHoldingDiv: Div\n\t\t/** legend area, to show available stats legend on genes */\n\t\tstatLegendDiv: Div\n\t\t/** Submit button */\n\t\tsubmitBtn: Button\n\t}\n\t/** originally .params and split into two\n\t * Derived from termdbConfig.queries.topMutatedGenes.arguments\n\t * input for the param is add in the gene set menu\n\t */\n\ttopMutatedGenesParams: { param: GeneArgumentEntry; input?: any }[]\n\t/** Derived from termdbConfig.queries.topVariablyExpressedGenes.arguments\n\t * input for the param is add in the gene set menu\n\t */\n\ttopVariablyExpressedGenesParams: { param: GeneArgumentEntry; input?: any }[]\n\t/** while rendering each gene button, if gene stat is available,\n\t * it records color and labels for each color,\n\t * to be shown in statLegendDiv */\n\tstatColor2label: Map<string, any>\n\t/** destory the original menu (i.e. tip == opts.holder) */\n\tdestroy: () => void\n}\n\ntype Gene = {\n\tgene: string\n\tmutationStat?: { class: string; count: number; dt?: number }[]\n}\n\nexport type CallbackArg = {\n\tgeneList: Gene[]\n\t/** optional, gene set name */\n\tname?: string\n}\n\n/** optional instruction to add new button(s) and pull in gene sets by custom-designed means.\n * used by gdc oncomatrix react wrapper to call the GFF gene set modal */\ntype CustomInputs = {\n\t/** button name */\n\tlabel: string\n\t/** Change button display based on caller logic */\n\tgetDisplayStyle?: () => void\n\t/** callback to trigger upon clicking this button. should show some ui to collect\n\t * gene names and bring them into holding box */\n\tshowInput: (arg: any) => void\n}[]\n\nexport type GeneSetEditArg = {\n\tholder: Elem\n\tgenome: ClientGenome\n\t/** Optional: If provided, allow to load top variably mutated ('geneVariant') or\n\t * expressed genes ('geneExpression'). If not provided, only allow to add genes manually\n\t * later can be union of multiple mode strings */\n\tmode?: 'geneVariant' | 'geneExpression'\n\t/** Minimum number of genes to return in the callback */\n\tminNumGenes?: number\n\t/** Maxiumum number of genes allowed in gene set */\n\tmaxNumGenes?: number\n\t/** What to do with the genes returned */\n\tcallback: (arg: CallbackArg) => void\n\t/** passed termdb instance */\n\tvocabApi: any\n\t/** List of genes returned by the callback */\n\tgeneList?: Gene[]\n\t/** Title appearing above the UI */\n\ttitleText?: string\n\tcustomInputs?: CustomInputs\n\t/** Pass the genes available to be used by the caller. When not in the limited\n\t * list, genes will appear with a strikethrough */\n\tlimitedGenesList?: string[]\n\t/** show the terms in the order of input*/\n\ttermsAsListed?: boolean\n\t/** show input for geneset name */\n\tnameInput?: boolean\n\tbackBtn?: {\n\t\ttarget: string\n\t\tcallback: () => void\n\t}\n}\n\ntype MenuListEntry = {\n\t/** Label shown, either on the button or link */\n\tlabel: string\n\t/** For buttons, set display per condition(s) */\n\tgetDisplayStyle?: () => string\n\tcallback: (f?: any) => void\n\t/** Element tagname. If button, uses addButton to create elem */\n\ttagName?: string\n}\n\nexport class GeneSetEditUI {\n\tholder: Elem\n\tgenome: ClientGenome\n\tcallback: (arg: CallbackArg) => void\n\t/** termdb */\n\tvocabApi: any\n\ttip2: Menu\n\torigLst: Gene[]\n\torigNames: string\n\tapi: API\n\tgeneSearch: any //cheating\n\t/** Objects detailing the menus to create above the api.dom.geneHoldingDiv as clickable links */\n\tmenuList: MenuListEntry[]\n\tmode?: 'geneVariant' | 'geneExpression'\n\tminNumGenes?: number\n\tmaxNumGenes?: number\n\tupdateName: boolean // whether to update gene set name upon user input\n\tnameInput?: any\n\tgeneList: Gene[]\n\ttitleText?: string\n\tcustomInputs?: CustomInputs\n\tlimitedGenesList?: string[]\n\ttermsAsListed?: boolean\n\n\tconstructor(opts: GeneSetEditArg) {\n\t\tthis.holder = opts.holder\n\t\tthis.genome = opts.genome\n\t\tthis.callback = opts.callback\n\t\tthis.vocabApi = opts.vocabApi\n\t\tthis.termsAsListed = opts.termsAsListed\n\t\tthis.customInputs = opts.customInputs\n\t\tthis.geneList = structuredClone(opts.geneList || [])\n\t\tconst parent_menu = opts.holder?.node()?.closest('.sja_menu_div') || opts.holder.node()\n\t\tthis.tip2 = new Menu({ padding: '0px', parent_menu, test: 'test' })\n\t\tthis.updateName = true\n\t\tthis.minNumGenes = opts.minNumGenes || 0\n\t\tif ('maxNumGenes' in opts) this.maxNumGenes = opts.maxNumGenes\n\t\tif ('mode' in opts) this.mode = opts.mode\n\t\tif ('titleText' in opts) this.titleText = opts.titleText\n\t\tthis.origLst = structuredClone(this.geneList)\n\t\tthis.origNames = opts.termsAsListed\n\t\t\t? JSON.stringify(this.geneList.map(t => t.gene))\n\t\t\t: JSON.stringify(this.geneList.map(t => t.gene).sort())\n\n\t\tthis.holder.selectAll('*').remove()\n\t\tconst div = this.holder.append('div').attr('class', 'sja_genesetinput').style('padding', '5px')\n\n\t\tif (this.titleText) {\n\t\t\tdiv.append('div').style('margin-bottom', '10px').html(this.titleText)\n\t\t}\n\t\tif (opts.limitedGenesList) {\n\t\t\tthis.limitedGenesList = opts.limitedGenesList\n\t\t}\n\n\t\tconst headerDiv = div.append('div')\n\n\t\tconst label = headerDiv.append('label')\n\t\tlabel.append('span').html('Search')\n\t\tconst row = label\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-flex')\n\t\t\t.style('align-items', 'center')\n\t\t\t.style('margin', '8px 0px -5px 0px')\n\n\t\t// a holder to render optional buttons\n\t\tconst controlDiv = headerDiv\n\t\t\t.append('div')\n\t\t\t.style('display', 'inline-flex')\n\t\t\t.style('align-items', 'center')\n\t\t\t.style('float', 'right')\n\t\t\t.style('gap', '5px')\n\n\t\tconst addGene = this.addGene.bind(this)\n\t\tthis.geneSearch = addGeneSearchbox({\n\t\t\ttestid: 'sjpp-geneSetEditUi-geneSearchInput',\n\t\t\ttip: this.tip2,\n\t\t\tgenome: this.genome,\n\t\t\trow,\n\t\t\tsearchOnly: 'genes',\n\t\t\tcallback: addGene,\n\t\t\thideHelp: true,\n\t\t\tfocusOff: true\n\t\t})\n\n\t\tif (opts.nameInput) {\n\t\t\t// display input for geneset name\n\t\t\tconst nameDiv = row.append('div').style('margin-left', '10px')\n\t\t\tnameDiv.append('span').text('Name')\n\t\t\tthis.nameInput = nameDiv\n\t\t\t\t.append('input')\n\t\t\t\t.attr('data-testid', 'sja_genesetinput_name')\n\t\t\t\t.attr('type', 'text')\n\t\t\t\t.style('width', '150px')\n\t\t}\n\n\t\tthis.menuList = []\n\n\t\tthis.api = {\n\t\t\tdom: {\n\t\t\t\tholder: div,\n\t\t\t\ttextControlDiv: controlDiv.append('div'),\n\t\t\t\tclearBtn: addButton({\n\t\t\t\t\tdiv: controlDiv,\n\t\t\t\t\ttext: 'Clear',\n\t\t\t\t\tdisabled: !this.geneList?.length,\n\t\t\t\t\tcallback: () => {\n\t\t\t\t\t\tthis.geneList = []\n\t\t\t\t\t\tthis.updateName = true\n\t\t\t\t\t\tthis.renderGenes()\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\trestoreBtn: this.geneList?.length\n\t\t\t\t\t? addButton({\n\t\t\t\t\t\t\tdiv: controlDiv,\n\t\t\t\t\t\t\tdisabled: true,\n\t\t\t\t\t\t\ttext: 'Restore',\n\t\t\t\t\t\t\tcallback: () => {\n\t\t\t\t\t\t\t\tthis.geneList = this.origLst\n\t\t\t\t\t\t\t\tthis.renderGenes()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t })\n\t\t\t\t\t: null,\n\t\t\t\tgeneHoldingDiv: this.renderGeneHoldingDiv(div),\n\t\t\t\tstatLegendDiv: div.append('div'),\n\t\t\t\tsubmitBtn: addButton({\n\t\t\t\t\tdiv: div.append('div').style('margin-top', '10px'),\n\t\t\t\t\ttestid: 'sjpp-genesetedit-submitbtn',\n\t\t\t\t\ttext: 'Submit',\n\t\t\t\t\tdisabled: !this.geneList?.length,\n\t\t\t\t\tcallback: () => {\n\t\t\t\t\t\tif (this.maxNumGenes && this.geneList.length > this.maxNumGenes) {\n\t\t\t\t\t\t\twindow.alert(\n\t\t\t\t\t\t\t\t`Gene set size (${this.geneList.length} genes) exceeds the allowed limit (${this.maxNumGenes} genes).`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.api.dom.submitBtn.property('disabled', true).text('Loading...') // to prevent repeated clicking and triggering callback. when this ui is used in geneVariant tw edit, it can keep showing a while after user clicks btn thus this fix is needed\n\t\t\t\t\t\tconst result: CallbackArg = { geneList: this.geneList }\n\t\t\t\t\t\tif (this.nameInput) result.name = this.nameInput.property('value')\n\t\t\t\t\t\tthis.callback(result)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t},\n\t\t\ttopMutatedGenesParams: [],\n\t\t\ttopVariablyExpressedGenesParams: [],\n\t\t\tstatColor2label: new Map(),\n\t\t\tdestroy: () => {\n\t\t\t\tthis.tip2.destroy()\n\t\t\t\topts.holder.remove()\n\t\t\t}\n\t\t}\n\t\tthis.getParams()\n\t\tthis.createMenuList()\n\t\tthis.renderTextControls(this.api.dom.textControlDiv)\n\t\tthis.renderGenes()\n\t}\n\n\tgetParams() {\n\t\tif (this.mode == TermTypes.GENE_VARIANT && this.vocabApi.termdbConfig?.queries?.topMutatedGenes) {\n\t\t\tif (this.vocabApi.termdbConfig.queries.topMutatedGenes.arguments) {\n\t\t\t\tfor (const param of this.vocabApi.termdbConfig.queries.topMutatedGenes.arguments)\n\t\t\t\t\tthis.api.topMutatedGenesParams.push({ param })\n\t\t\t}\n\t\t}\n\t\tif (this.mode == TermTypes.GENE_EXPRESSION && this.vocabApi.termdbConfig?.queries?.topVariablyExpressedGenes) {\n\t\t\tif (this.vocabApi.termdbConfig.queries.topVariablyExpressedGenes.arguments) {\n\t\t\t\tfor (const param of this.vocabApi.termdbConfig.queries.topVariablyExpressedGenes.arguments) {\n\t\t\t\t\tif (param.type == 'radio' && (!param.options || param.options.length == 0))\n\t\t\t\t\t\tthrow 'Radio button must have options'\n\t\t\t\t\tthis.api.topVariablyExpressedGenesParams.push({ param })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tbaseGeneMenuArgs(arr) {\n\t\tarr = this.removeDuplicates(arr)\n\t\treturn {\n\t\t\ttip: this.tip2,\n\t\t\tgenome: this.genome,\n\t\t\tparams: arr,\n\t\t\taddOptionalParams: ({ param, input }) => {\n\t\t\t\tarr.push({ param, input })\n\t\t\t}\n\t\t}\n\t}\n\n\tremoveDuplicates(arr) {\n\t\tfor (const param of arr) {\n\t\t\tif (param.param?.options) {\n\t\t\t\tparam.param.options.forEach(opt => {\n\t\t\t\t\tif (!opt.id) return\n\t\t\t\t\tconst i = arr.findIndex(i => i.param.id == opt.id)\n\t\t\t\t\tif (i != -1) arr.splice(i, 1)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn arr\n\t}\n\n\tcreateMenuList() {\n\t\tif (this.api?.topMutatedGenesParams.length > 0) {\n\t\t\tthis.menuList.push({\n\t\t\t\tlabel: 'Top mutated genes',\n\t\t\t\tcallback: async (event: Event) => {\n\t\t\t\t\tthis.tip2.clear().showunder(event.target)\n\t\t\t\t\tconst callback = async () => {\n\t\t\t\t\t\tconst args = {\n\t\t\t\t\t\t\tgenome: this.vocabApi.vocab.genome,\n\t\t\t\t\t\t\tdslabel: this.vocabApi.vocab.dslabel,\n\t\t\t\t\t\t\tfilter: this.vocabApi.state.termfilter.filter,\n\t\t\t\t\t\t\tfilter0: this.vocabApi.state.termfilter.filter0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.getInputs(this.api.topMutatedGenesParams, args)\n\t\t\t\t\t\tconst result = await dofetch3('termdb/topMutatedGenes', { method: 'GET', body: args })\n\n\t\t\t\t\t\tthis.geneList = []\n\t\t\t\t\t\tthis.geneList.push(...result.genes)\n\t\t\t\t\t\tthis.renderGenes()\n\t\t\t\t\t}\n\t\t\t\t\tconst menuArgs = Object.assign(this.baseGeneMenuArgs(this.api.topMutatedGenesParams), { callback })\n\t\t\t\t\tnew GenesMenu(menuArgs)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (this.api?.topVariablyExpressedGenesParams.length > 0) {\n\t\t\tthis.menuList.push({\n\t\t\t\tlabel: 'Top variably expressed genes',\n\t\t\t\tcallback: (event: Event) => {\n\t\t\t\t\t/** Create a copy to avoid mutating the args in the state */\n\t\t\t\t\tconst copy = structuredClone(this.api.topVariablyExpressedGenesParams)\n\t\t\t\t\tcopy\n\t\t\t\t\t\t.filter(p => p.param.type == 'radio' && p.param?.options)\n\t\t\t\t\t\t.forEach(p => {\n\t\t\t\t\t\t\t//Sets the default value of the radio button to the first option\n\t\t\t\t\t\t\t//for top VE args, it will always be a string\n\t\t\t\t\t\t\tif (typeof p.param.options![0].value === 'string') {\n\t\t\t\t\t\t\t\tp.param.value = { type: p.param.options![0].value, value: null }\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconsole.error(`Unexpected radio button value type: ${typeof p.param.options![0].value}`)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\tthis.tip2.clear().showunder(event.target)\n\t\t\t\t\tconst callback = async () => {\n\t\t\t\t\t\tconst args: any = {\n\t\t\t\t\t\t\tgenome: this.vocabApi.state.vocab.genome,\n\t\t\t\t\t\t\tdslabel: this.vocabApi.state.vocab.dslabel\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// supply filters from app state\n\t\t\t\t\t\tif (this.vocabApi.state.termfilter) {\n\t\t\t\t\t\t\tif (this.vocabApi.state.termfilter.filter)\n\t\t\t\t\t\t\t\targs.filter = getNormalRoot(this.vocabApi.state.termfilter.filter) // pp filter\n\t\t\t\t\t\t\tif (this.vocabApi.state.termfilter.filter0) args.filter0 = this.vocabApi.state.termfilter.filter0 // gdc filter\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.getInputs(copy, args)\n\t\t\t\t\t\tconst result = await dofetch3('termdb/topVariablyExpressedGenes', { method: 'GET', body: args })\n\n\t\t\t\t\t\tthis.geneList = []\n\t\t\t\t\t\tif (result.genes) {\n\t\t\t\t\t\t\tfor (const gene of result.genes) this.geneList.push({ gene })\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.renderGenes()\n\t\t\t\t\t}\n\n\t\t\t\t\tconst menuArgs = Object.assign(this.baseGeneMenuArgs(copy), { callback })\n\t\t\t\t\tnew GenesMenu(menuArgs)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (this.genome?.termdbs?.msigdb) {\n\t\t\tfor (const key in this.genome.termdbs) {\n\t\t\t\tconst tdb = this.genome.termdbs[key]\n\t\t\t\tthis.menuList.push({\n\t\t\t\t\tlabel: `${tdb.label} gene set`,\n\t\t\t\t\tcallback: async () => {\n\t\t\t\t\t\tthis.tip2.clear().showunder(this.api.dom.textControlDiv.node()!)\n\t\t\t\t\t\tconst termdb = await import('../../termdb/app.js')\n\t\t\t\t\t\ttermdb.appInit({\n\t\t\t\t\t\t\tholder: this.tip2.d,\n\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\tdslabel: key,\n\t\t\t\t\t\t\t\tgenome: this.genome.name,\n\t\t\t\t\t\t\t\tnav: {\n\t\t\t\t\t\t\t\t\theader_mode: 'search_only'\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttree: {\n\t\t\t\t\t\t\t\tclick_term: term => {\n\t\t\t\t\t\t\t\t\tthis.geneList = []\n\t\t\t\t\t\t\t\t\tconst geneset = term._geneset\n\t\t\t\t\t\t\t\t\tif (geneset) {\n\t\t\t\t\t\t\t\t\t\tfor (const gene of geneset) this.geneList.push({ gene: gene.symbol })\n\t\t\t\t\t\t\t\t\t\tthis.renderGenes(term.name)\n\t\t\t\t\t\t\t\t\t\t// disable name update to retain msigdb gene set name\n\t\t\t\t\t\t\t\t\t\t// when user modifies gene set\n\t\t\t\t\t\t\t\t\t\tthis.updateName = false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.tip2.hide()\n\t\t\t\t\t\t\t\t\tthis.api.dom.submitBtn.node()!.focus()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tif (this.customInputs) {\n\t\t\tfor (const btn of this.customInputs) {\n\t\t\t\tconst opts = {\n\t\t\t\t\tlabel: btn.label,\n\t\t\t\t\tcallback: () => {\n\t\t\t\t\t\tbtn.showInput({\n\t\t\t\t\t\t\tcallback: ({ geneList }) => {\n\t\t\t\t\t\t\t\tthis.geneList = geneList\n\t\t\t\t\t\t\t\tthis.renderGenes()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\ttagName: 'button'\n\t\t\t\t} as any\n\t\t\t\tif (btn.getDisplayStyle) opts.getDisplayStyle = btn.getDisplayStyle\n\t\t\t\tthis.menuList.push(opts)\n\t\t\t}\n\t\t}\n\t}\n\n\trenderTextControls(div: Div) {\n\t\tfor (const menu of this.menuList) {\n\t\t\tif (menu.tagName == 'button')\n\t\t\t\taddButton({\n\t\t\t\t\tdiv,\n\t\t\t\t\ttext: menu.label,\n\t\t\t\t\tgetDisplayStyle: menu.getDisplayStyle || (() => ''),\n\t\t\t\t\tcallback: menu.callback\n\t\t\t\t})\n\t\t\telse\n\t\t\t\tdiv\n\t\t\t\t\t.append('a')\n\t\t\t\t\t.style('text-decoration', 'underline')\n\t\t\t\t\t.style('padding', '0px 10px')\n\t\t\t\t\t.style('color', 'black')\n\t\t\t\t\t.html(`${menu.label} ▼`)\n\t\t\t\t\t.on('click', async (event: Event) => {\n\t\t\t\t\t\tawait menu.callback(event)\n\t\t\t\t\t})\n\t\t}\n\t}\n\n\t/** Get the input value for the entire menu */\n\tgetInputs(arr, args) {\n\t\tfor (const { param, input } of arr) {\n\t\t\tif (param.parentId) {\n\t\t\t\tconst parent = arr.find(i => i.param.id == param.parentId)\n\t\t\t\t//Parents are always checkboxes/boolean\n\t\t\t\t//Do not include submenu inputs in the request if not checked\n\t\t\t\tif (!parent || !parent.input.node().checked) return\n\t\t\t}\n\t\t\tconst id = input.attr('id')\n\t\t\targs[id] = this.getInputValue({ param, input })\n\t\t}\n\t}\n\n\t/** Get value for single input based on type */\n\tgetInputValue({ param, input }) {\n\t\tif (param.type == 'radio') return param.value\n\t\tconst value = input.node().value\n\t\tif (input.attr('type') == 'number') return Number(value)\n\t\tif (input.attr('type') == 'checkbox') {\n\t\t\tif (param.type == 'string') return input.node().checked ? param.value : ''\n\t\t\tif (param.type == 'boolean') return input.node().checked ? 1 : 0\n\t\t}\n\t}\n\n\trenderGeneHoldingDiv(div: Div) {\n\t\treturn div\n\t\t\t.append('div')\n\t\t\t.append('div')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('flex-wrap', 'wrap')\n\t\t\t.style('gap', '5px')\n\t\t\t.style('min-height', '20px')\n\t\t\t.style('border', 'solid 1px #aaa')\n\t\t\t.style('margin', '15px 0px')\n\t\t\t.style('padding', '6px 2px')\n\t\t\t.style('min-height', '30px')\n\t}\n\n\trenderStatLegend() {\n\t\tif (!this.api.statColor2label || this.api.statColor2label.size == 0) {\n\t\t\t// no legend to display\n\t\t\tthis.api.dom.statLegendDiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tthis.api.dom.statLegendDiv.style('display', 'block').selectAll('*').remove()\n\t\tfor (const [c, n] of this.api.statColor2label) {\n\t\t\tthis.api.dom.statLegendDiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('width', '12px')\n\t\t\t\t.style('height', '12px')\n\t\t\t\t.style('background-color', c)\n\t\t\tthis.api.dom.statLegendDiv.append('span').html(` ${n} `)\n\t\t}\n\t\treturn this.api.dom.statLegendDiv\n\t}\n\n\t/** Functions supporting adding/removing genes from the geneHoldingDiv */\n\taddGene() {\n\t\tif (this.geneSearch.geneSymbol) {\n\t\t\tconst gene = this.geneSearch.geneSymbol\n\t\t\tfor (const item of this.geneList) {\n\t\t\t\tif (item.gene == gene) {\n\t\t\t\t\twindow.alert(`The gene ${gene} has already been added`)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (gene) this.geneList.push({ gene })\n\t\t} else if (this.geneSearch.genes) {\n\t\t\tconst newGenes: Gene[] = []\n\t\t\tconst duplicates: string[] = []\n\n\t\t\tfor (const geneObj of this.geneSearch.genes) {\n\t\t\t\tconst geneName = geneObj.geneSymbol\n\t\t\t\tconst isDuplicate = this.geneList.some(item => item.gene === geneName)\n\t\t\t\tif (isDuplicate) {\n\t\t\t\t\tduplicates.push(geneName)\n\t\t\t\t} else {\n\t\t\t\t\tnewGenes.push({ gene: geneName })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (newGenes.length > 0) {\n\t\t\t\tthis.geneList.push(...newGenes)\n\t\t\t}\n\n\t\t\tif (duplicates.length > 0) {\n\t\t\t\twindow.alert(`The following genes were already added and skipped: ${duplicates.join(', ')}`)\n\t\t\t}\n\t\t}\n\t\tthis.renderGenes()\n\t}\n\n\trenderGenes(geneSetName?: string) {\n\t\tthis.api.dom.geneHoldingDiv.selectAll('*').remove()\n\n\t\tconst renderGene = this.renderGene.bind(this)\n\t\tconst deleteGene = this.deleteGene.bind(this)\n\n\t\tthis.api.dom.geneHoldingDiv\n\t\t\t.selectAll('div')\n\t\t\t.data(this.geneList || [])\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('aria-label', 'Click to delete')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('data-testid', `sjpp-delete-gene-option`)\n\t\t\t.attr('tabindex', 0)\n\t\t\t.style('position', 'relative')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('padding', '5px 16px 5px 9px')\n\t\t\t.style('margin-left', '5px')\n\t\t\t.each(function (this: any, gene) {\n\t\t\t\tconst div = select(this).style('border-radius', '5px')\n\t\t\t\trenderGene(div, gene)\n\t\t\t\tdiv.on('click', () => deleteGene(gene))\n\t\t\t})\n\t\t\t// .on('click', deleteGene)\n\t\t\t.on('mouseover', function (event) {\n\t\t\t\tconst div = select(event.target)\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('margin-left', '4px')\n\t\t\t\t\t.classed('sjpp_deletebt', true)\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('position', 'absolute')\n\t\t\t\t\t.style('right', '0px')\n\t\t\t\t\t.style('top', '0px')\n\n\t\t\t\t\t.style('transform', 'scale(0.6)')\n\t\t\t\t\t.style('pointer-events', 'none')\n\t\t\t\t\t.html(\n\t\t\t\t\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#000\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\">\n <path stroke='#f00' d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z\"/>\n </svg>`\n\t\t\t\t\t)\n\t\t\t})\n\t\t\t.on('mouseout', function (event) {\n\t\t\t\tselect(event.target).select('.sjpp_deletebt').remove()\n\t\t\t})\n\t\t\t.on('focus', event => {\n\t\t\t\tevent.target.dispatchEvent(new PointerEvent('mouseover'))\n\t\t\t})\n\t\t\t.on('blur', event => {\n\t\t\t\tevent.target.dispatchEvent(new PointerEvent('mouseout'))\n\t\t\t})\n\t\t\t.on('keyup', event => {\n\t\t\t\tif (event.key == 'Enter') event.target.click()\n\t\t\t})\n\n\t\tthis.renderStatLegend() // api.statColor2label has been accumulated if available\n\n\t\tif (this.nameInput && this.updateName) {\n\t\t\tthis.nameInput.property('value', geneSetName || this.geneList.map(g => g.gene).join(', '))\n\t\t}\n\n\t\tthis.api.dom.clearBtn.property('disabled', !this.geneList?.length)\n\t\tconst hasChanged =\n\t\t\tthis.origNames !==\n\t\t\t(this.termsAsListed\n\t\t\t\t? JSON.stringify(this.geneList.map(t => t.gene))\n\t\t\t\t: JSON.stringify(this.geneList.map(t => t.gene).sort()))\n\t\tthis.api.dom.restoreBtn?.property('disabled', !hasChanged)\n\t\t// disable submit button when gene list not changed or is empty in expression mode\n\t\tthis.api.dom.submitBtn.property(\n\t\t\t'disabled',\n\t\t\t!hasChanged || (this.minNumGenes && this.geneList?.length < this.minNumGenes) || !this.geneList?.length\n\t\t)\n\t\tif (hasChanged) this.api.dom.submitBtn!.node()!.focus()\n\t}\n\n\trenderGene(div: Div, gene: Gene) {\n\t\tlet notInList = false\n\t\t//Check if list is present, then run check\n\t\tif (this.limitedGenesList && !this.limitedGenesList?.includes(gene.gene)) {\n\t\t\tnotInList = true\n\t\t}\n\t\tif (gene.mutationStat) {\n\t\t\tdiv.style('text-decoration', notInList ? 'line-through' : '').html(`${gene.gene} `)\n\t\t\tfor (const m of gene.mutationStat) {\n\t\t\t\t// m is {class,count} or {dt,count}; if class is given, bgcolor is determined by class; otherwise by dt and logicis a bit shaky now (may\n\t\t\t\tlet bgcolor: string\n\t\t\t\t/** bg and text color of gene button\n\t\t\t\t * default is black\n\t\t\t\t */\n\t\t\t\tlet textcolor = 'black'\n\t\t\t\tif ('class' in m) {\n\t\t\t\t\tif (!mclass[m.class]) throw 'invalid stat class'\n\t\t\t\t\tbgcolor = mclass[m.class].color\n\t\t\t\t\tthis.api.statColor2label.set(bgcolor, mclass[m.class].label)\n\t\t\t\t} else if ('dt' in m) {\n\t\t\t\t\tif (!dt2color[m['dt']]) throw 'invalid stat dt'\n\t\t\t\t\tbgcolor = dt2color[m['dt']]\n\t\t\t\t\ttextcolor = 'white' // hardcode it for now\n\t\t\t\t\tthis.api.statColor2label.set(bgcolor, dt2label[m['dt']])\n\t\t\t\t} else {\n\t\t\t\t\tthrow 'stat missing dt/class'\n\t\t\t\t}\n\t\t\t\tdiv\n\t\t\t\t\t.insert('span')\n\t\t\t\t\t.style('font-size', '.7em')\n\t\t\t\t\t.style('background-color', bgcolor)\n\t\t\t\t\t.style('padding', '1px 2px')\n\t\t\t\t\t.style('color', textcolor)\n\t\t\t\t\t.text(m.count)\n\t\t\t}\n\t\t\t/* enable different types of gene stats this way\n\t\t} else if(gene.expStat) {\n\t\t*/\n\t\t} else {\n\t\t\tdiv\n\t\t\t\t.insert('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('text-decoration', notInList ? 'line-through' : '')\n\t\t\t\t.html(gene.gene)\n\t\t}\n\t}\n\n\tdeleteGene(d: Gene) {\n\t\tconst i = this.geneList.findIndex(g => g.gene === d.gene)\n\t\tif (i != -1) {\n\t\t\tthis.geneList.splice(i, 1)\n\t\t\tthis.renderGenes()\n\t\t}\n\t}\n}\n", "import { select } from 'd3-selection'\nimport { rgb } from 'd3-color'\n\nexport default function htmlLegend(legendDiv, viz = { settings: {}, handlers: {} }, barDiv) {\n\tconst isHidden = {}\n\n\t// TODO: cleanup, reorgananize, and document all these options\n\tfunction render(data, opts = {}) {\n\t\tconst s = viz.settings\n\t\tif (!opts.div) legendDiv.selectAll('*').remove()\n\n\t\t// TODO: Instead of doing the loop here, the caller should\n\t\t// call legendRenderer instancce multipler times with different data/divs\n\t\tif (data.every(d => Array.isArray(d))) {\n\t\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\t\t// TODO: should not hardcode selectors here, this logic should be in the caller/viz code?\n\t\t\t\tconst barDivChild = barDiv.select(`.pp-sbar-div:nth-child(${i + 1})`)\n\t\t\t\tgenerateLegend(data[i], s, barDivChild)\n\t\t\t}\n\t\t} else if (data.every(d => typeof d == 'object')) {\n\t\t\tgenerateLegend(data, s, opts.div || legendDiv)\n\t\t} else {\n\t\t\tthrow 'render() only takes an array of objects or an array of arrays'\n\t\t}\n\t}\n\n\tfunction generateLegend(data, s, oneLegendDiv) {\n\t\toneLegendDiv.selectAll('.pp-sbar-div-oneLegend').remove()\n\n\t\toneLegendDiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'pp-sbar-div-oneLegend')\n\t\t\t.attr('data-testid', 'pp-sbar-div-oneLegend')\n\t\t\t.style('width', s.mainWidth || '')\n\t\t\t.style(\n\t\t\t\t'text-align',\n\t\t\t\tdata.legendTextAlign || s.legendTextAlign || (s.legendOrientation == 'vertical' ? 'left' : 'center')\n\t\t\t)\n\t\t\t.style('display', s.legendOrientation == 'grid' ? 'grid' : '')\n\t\t\t//.style('grid-template-cols', s.legendOrientation == 'grid' ? 'auto auto' : '')\n\t\t\t.style('grid-template-rows', s.legendOrientation == 'grid' ? 'auto auto' : '')\n\t\t\t.style('gap', s.legendOrientation == 'grid' ? '10px' : '')\n\t\t\t.selectAll('div')\n\t\t\t.data(data)\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.each(addLegendRow)\n\n\t\tif (s.legendChartSide == 'right') {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst pbox = viz.dom.container.node().parentNode.getBoundingClientRect()\n\t\t\t\tconst mbox = viz.dom.container.node().getBoundingClientRect()\n\t\t\t\tconst lbox = viz.dom.legendDiv.node().getBoundingClientRect()\n\t\t\t\tconst currPadTop = parseFloat(viz.dom.legendDiv.style('padding-top'))\n\t\t\t\tconst padTop = pbox.height - mbox.height + (mbox.height - lbox.height + currPadTop) / 2\n\t\t\t\tif (Math.abs(currPadTop - padTop) < 20) return\n\t\t\t\t//console.log(padTop, pbox.height, mbox.height, lbox.height)\n\t\t\t\tviz.dom.legendDiv\n\t\t\t\t\t.transition()\n\t\t\t\t\t.duration(100)\n\t\t\t\t\t.style('padding-top', padTop < 0 ? 0 : padTop + 'px')\n\t\t\t}, 1200)\n\t\t}\n\t}\n\n\tfunction addLegendRow(d) {\n\t\tconst s = viz.settings\n\t\tconst div = select(this).style(\n\t\t\t'display',\n\t\t\ts.legendOrientation == 'vertical' || s.legendOrientation == 'grid' ? 'block' : 'inline-block'\n\t\t)\n\n\t\tif (d.name) {\n\t\t\tif (s.legendChartSide == 'right') {\n\t\t\t\tdiv.style('text-align', 'left')\n\n\t\t\t\tdiv.append('div').style('font-size', s.legendFontSize).style('font-weight', 600).html(d.name)\n\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.selectAll('div')\n\t\t\t\t\t.data(d.items)\n\t\t\t\t\t.enter()\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('display', s.legendOrientation == 'vertical' ? 'block' : 'inline-block')\n\t\t\t\t\t.style('margin-right', '5px')\n\t\t\t\t\t.each(addLegendItem)\n\t\t\t} else {\n\t\t\t\tdiv.style('white-space', 'nowrap').style('width', s.legendOrientation == 'vertical' ? 'fit-content' : null)\n\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style(\n\t\t\t\t\t\t'display',\n\t\t\t\t\t\ts.legendOrientation == 'grid' || s.legendOrientation == 'vertical' ? 'block' : 'inline-block'\n\t\t\t\t\t)\n\t\t\t\t\t.style('width', d.rowLabelHangLeft ? d.rowLabelHangLeft + 'px' : null)\n\t\t\t\t\t.style('margin-left', s.legendOrientation == 'vertical' ? '15px' : null)\n\t\t\t\t\t.style('text-align', d.rowLabelHangLeft ? 'right' : null)\n\t\t\t\t\t.style('font-weight', 600)\n\t\t\t\t\t.style('vertical-align', 'top')\n\t\t\t\t\t.html(d.name)\n\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style(\n\t\t\t\t\t\t'display',\n\t\t\t\t\t\ts.legendOrientation == 'grid' || s.legendOrientation == 'vertical' ? 'block' : 'inline-block'\n\t\t\t\t\t)\n\t\t\t\t\t.style('max-width', 1.2 * d.rowLabelHangLeft + 'px')\n\t\t\t\t\t.style('white-space', 'normal')\n\t\t\t\t\t.style('vertical-align', 'top')\n\t\t\t\t\t.selectAll('div')\n\t\t\t\t\t.data(d.items)\n\t\t\t\t\t.enter()\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin-left', '15px')\n\t\t\t\t\t.each(addLegendItem)\n\t\t\t}\n\t\t} else {\n\t\t\tdiv\n\t\t\t\t.selectAll('div')\n\t\t\t\t.data(d.items)\n\t\t\t\t.enter()\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', s.legendOrientation == 'vertical' ? 'block' : 'inline-block')\n\t\t\t\t.style('margin-left', '15px')\n\t\t\t\t.each(addLegendItem)\n\t\t}\n\t}\n\n\tfunction addLegendItem(d) {\n\t\tconst s = viz.settings\n\t\tconst div = select(this)\n\t\tconst color = d.fill ? d.fill : d.stroke ? d.stroke : d.color\n\t\tdiv\n\t\t\t//.style('opacity', !d.isHidden ? 1 : d.hiddenOpacity ? d.hiddenOpacity : 0.3)\n\t\t\t.attr('class', 'legend-row')\n\t\t\t.classed('sjpp-hidden-legend-item', d.isHidden ? true : false)\n\t\t\t.style('display', s.legendOrientation == 'vertical' ? 'block' : 'inline-block')\n\t\t\t.style('width', s.legendOrientation == 'vertical' ? 'fit-content' : null)\n\n\t\tif (d.svg) {\n\t\t\tdiv\n\t\t\t\t.append('svg')\n\t\t\t\t.attr('width', d.svgw)\n\t\t\t\t.attr('height', d.svgh)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('vertical-align', 'top')\n\t\t\t\t.style('border', d.border)\n\t\t\t\t.html(d => d.svg)\n\t\t} else if (!d.noIcon) {\n\t\t\tconst stroke = d.noEditColor ? color : rgb(color).darker()\n\t\t\tdiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('position', 'relative')\n\t\t\t\t.style('min-width', '12px')\n\t\t\t\t.style('height', '12px')\n\t\t\t\t.style('top', '1px')\n\t\t\t\t.style('border', d.border ? d.border : '1px solid ' + stroke)\n\t\t\t\t.style('border-radius', d.shape == 'circle' ? '6px' : '')\n\t\t\t\t.style('background-color', d.shape == 'circle' ? '' : color)\n\t\t\t\t.style('cursor', 'isHidden' in d ? 'pointer' : 'default')\n\t\t\t\t.style('color', d.textColor ? d.textColor : '#fff')\n\t\t\t\t.style('font-size', '10px')\n\t\t\t\t.style('vertical-align', d.inset ? 'top' : '')\n\t\t\t\t.style('padding', d.inset ? '0 3px' : '')\n\t\t\t\t.text(d.inset)\n\t\t\t\t.on('click', viz.handlers.legend?.onColorClick)\n\t\t}\n\t\tdiv\n\t\t\t.append('div')\n\t\t\t.classed('sjpp-htmlLegend', true)\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('margin-left', d.svg ? '1px' : '3px')\n\t\t\t.style('cursor', handleCursor(d))\n\t\t\t.style('font-size', s.legendFontSize)\n\t\t\t.style('line-height', s.legendFontSize)\n\t\t\t.style('vertical-align', d.svg ? 'top' : null)\n\t\t\t.style('text-decoration', d.isHidden ? 'line-through' : 'none')\n\t\t\t.html(d.text)\n\t\t\t.on('click', viz.handlers.legend?.click)\n\n\t\tif (Object.keys(viz.handlers).length) {\n\t\t\tdiv.on('mouseover', viz.handlers.legend.mouseover).on('mouseout', viz.handlers.legend.mouseout)\n\t\t}\n\t}\n\n\treturn render\n}\n\n/** In some instances a legend item maybe hidden but not clickable\n * (e.g. uncomputable items in violin plot). In such cases, isHidden = true\n * for styling and isClickable = false to prevent cursor change, thus\n * avoiding user confusion.\n */\nfunction handleCursor(d) {\n\tif ('isClickable' in d) {\n\t\treturn d.isClickable ? 'pointer' : 'default'\n\t}\n\treturn 'isHidden' in d ? 'pointer' : 'default'\n}\n", "import { renderTable } from '#dom'\nimport { select } from 'd3-selection'\nimport type { Elem } from '../types/d3'\n\nexport type InvalidDataInfo = {\n\tentries: { dataType: string; reason: string }[]\n\terrorMsg?: string\n}\n\nexport class InvalidDataUI {\n\tstatic defaults = {\n\t\tbackgroundColor: '#f8f9fa',\n\t\tborderColor: '#dee2e6',\n\t\tborderRadius: '4px',\n\t\tcolor: '#dc3545', //punch red\n\t\tfontSize: 12, //use px, adjusted\n\t\tpadding: 8, // use px, adjusted\n\t\tmargin: '12px'\n\t}\n\n\tstatic render(container: Elem, invalidInfo: InvalidDataInfo) {\n\t\tconst expandableContainer = container\n\t\t\t.append('div')\n\t\t\t.style('margin-top', InvalidDataUI.defaults.margin)\n\t\t\t.attr('id', 'sjpp-invalid-data-ui')\n\n\t\tconst expandableHeader = expandableContainer\n\t\t\t.append('div')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('align-items', 'center')\n\t\t\t.style('gap', '8px')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.style('padding', `${InvalidDataUI.defaults.padding}px`)\n\t\t\t.style('border-radius', InvalidDataUI.defaults.borderRadius)\n\t\t\t.style('transition', 'background-color 0.2s')\n\t\t\t.style('background-color', 'rgba(220, 53, 69, 0.1)')\n\t\t\t.style('border', '1px solid rgba(220, 53, 69, 0.2)')\n\t\t\t.on('mouseenter', function (this: HTMLElement) {\n\t\t\t\tselect(this).style('background-color', 'rgba(220, 53, 69, 0.15)')\n\t\t\t})\n\t\t\t.on('mouseleave', function (this: HTMLElement) {\n\t\t\t\tselect(this).style('background-color', 'rgba(220, 53, 69, 0.1)')\n\t\t\t})\n\n\t\tconst expandIcon = expandableHeader\n\t\t\t.append('span')\n\t\t\t.style('font-size', `${InvalidDataUI.defaults.fontSize}px`)\n\t\t\t.style('color', InvalidDataUI.defaults.color)\n\t\t\t.style('transition', 'transform 0.2s')\n\t\t\t.text('\u25B6')\n\n\t\texpandableHeader\n\t\t\t.append('span')\n\t\t\t.style('color', InvalidDataUI.defaults.color)\n\t\t\t.style('text-decoration', 'underline')\n\t\t\t.style('font-size', `${InvalidDataUI.defaults.fontSize + 1}px`)\n\t\t\t.style('font-weight', '500')\n\t\t\t.text(`View ${invalidInfo.entries.length} invalid entries`)\n\n\t\tconst expandableContent = expandableContainer\n\t\t\t.append('div')\n\t\t\t.style('display', 'none')\n\t\t\t.style('margin-top', InvalidDataUI.defaults.margin)\n\t\t\t.style('padding', `${InvalidDataUI.defaults.padding + 4}px`)\n\t\t\t.style('background-color', '#fff')\n\t\t\t.style('border', '1px solid #f5c6cb')\n\t\t\t.style('border-radius', `${InvalidDataUI.defaults.borderRadius}`)\n\t\t\t.style('box-shadow', 'inset 0 1px 3px rgba(0, 0, 0, 0.1)')\n\n\t\tconst tableContainer = expandableContent\n\t\t\t.append('div')\n\t\t\t.style('max-height', '300px')\n\t\t\t.style('overflow-y', 'auto')\n\t\t\t.style('border', `1px solid ${InvalidDataUI.defaults.borderColor}`)\n\t\t\t.style('border-radius', InvalidDataUI.defaults.borderRadius)\n\n\t\trenderTable({\n\t\t\tdiv: tableContainer,\n\t\t\tcolumns: [\n\t\t\t\t{ label: 'Data Type', sortable: true },\n\t\t\t\t{ label: 'Reason', sortable: true }\n\t\t\t],\n\t\t\trows: invalidInfo.entries.map(e => [{ value: e.dataType }, { value: e.reason }]),\n\t\t\tshowLines: true,\n\t\t\tstriped: true,\n\t\t\tshowHeader: true,\n\t\t\tmaxHeight: '280px',\n\t\t\tresize: false,\n\t\t\theader: {\n\t\t\t\tallowSort: true,\n\t\t\t\tstyle: {\n\t\t\t\t\t'background-color': InvalidDataUI.defaults.backgroundColor,\n\t\t\t\t\t'font-weight': 'bold',\n\t\t\t\t\t'border-bottom': `2px solid ${InvalidDataUI.defaults.borderColor}`\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\texpandableContent\n\t\t\t.append('div')\n\t\t\t.style('margin-top', InvalidDataUI.defaults.margin)\n\t\t\t.style('padding', `${InvalidDataUI.defaults.padding}px`)\n\t\t\t.style('background-color', InvalidDataUI.defaults.backgroundColor)\n\t\t\t.style('border-radius', InvalidDataUI.defaults.borderRadius)\n\t\t\t.style('font-size', `${InvalidDataUI.defaults.fontSize}px`)\n\t\t\t.style('color', '#495057')\n\t\t\t.style('line-height', '1.4')\n\t\t\t.text(invalidInfo.errorMsg || 'Please address the issues above before proceeding.')\n\n\t\tlet isExpanded = false\n\t\texpandableHeader.on('click', function () {\n\t\t\tisExpanded = !isExpanded\n\t\t\tif (isExpanded) {\n\t\t\t\texpandableContent.style('display', 'block')\n\t\t\t\texpandIcon.style('transform', 'rotate(90deg)').text('\u25BC')\n\t\t\t} else {\n\t\t\t\texpandableContent.style('display', 'none')\n\t\t\t\texpandIcon.style('transform', 'rotate(0deg)').text('\u25B6')\n\t\t\t}\n\t\t})\n\t}\n}\n", "/**\n * Functions for sketching gene models, RNA, and protein structures on canvas.\n * All canvas rendering functions consider devicePixelRatio for crisp image rendering.\n */\n\nimport { scaleLinear } from 'd3-scale'\nimport type { Div, Td } from '../types/d3'\nimport type { GeneModel, ExonRegion } from './types/isoformSelect'\n\n/**\n * Interface for protein domains\n */\ninterface ProteinDomain {\n\tstart: number\n\tstop: number\n\tcolor: string\n}\n\n/**\n * Extended GeneModel type that includes optional protein domains\n */\ninterface GeneModelWithDomains extends GeneModel {\n\tpdomains?: ProteinDomain[]\n\trnalen?: number\n\tcodingstart?: number\n\tcodingstop?: number\n\tintron?: number[][]\n}\n\n/**\n * Helper function to configure canvas for high-DPI (Retina) displays.\n * Sets the canvas backing store size to match device pixel ratio for crisp rendering.\n */\nfunction setupCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {\n\tconst dpr = window.devicePixelRatio || 1\n\n\t// Set display size (css pixels)\n\tcanvas.style.width = `${width}px`\n\tcanvas.style.height = `${height}px`\n\n\t// Set actual size in memory (scaled by device pixel ratio)\n\tcanvas.width = width * dpr\n\tcanvas.height = height * dpr\n\n\tconst ctx = canvas.getContext('2d')!\n\n\t// Scale all drawing operations by the dpr\n\tctx.scale(dpr, dpr)\n\n\treturn ctx\n}\n\n/**\n * Sketches a spliced RNA structure showing exons, introns, and coding regions.\n *\n * @param holder - D3 selection to append canvas to\n * @param gm - Gene model with exon structure\n * @param pxwidth - Width in pixels\n * @param color - Color for coding regions\n */\nexport function sketchSplicerna(holder: Div | Td, gm: GeneModelWithDomains, pxwidth: number, color: string): void {\n\tlet intronpx = 10\n\tif (intronpx * (gm.exon.length - 1) > pxwidth * 0.3) {\n\t\tintronpx = Math.max(2, (pxwidth * 0.3) / (gm.exon.length - 1))\n\t}\n\tlet exonlen = 0\n\tfor (const e of gm.exon) {\n\t\texonlen += e[1] - e[0]\n\t}\n\tconst inw = intronpx * (gm.exon.length - 1)\n\tconst exonsf = (pxwidth - (inw > pxwidth * 0.4 ? 0 : inw)) / exonlen\n\t// reset width\n\tpxwidth = exonsf * exonlen + inw\n\tconst canvas = holder.append('canvas').node() as HTMLCanvasElement\n\tconst h = 20\n\tconst pad = 4\n\tconst ctx = setupCanvas(canvas, pxwidth, h)\n\n\tctx.strokeStyle = color\n\tctx.beginPath()\n\tctx.moveTo(0, Math.floor(h / 2) - 0.5)\n\tctx.lineTo(pxwidth, Math.floor(h / 2) - 0.5)\n\tctx.stroke()\n\n\t// gm.exon is 5 to 3\n\tconst reverse = gm.strand === '-'\n\tlet x = 0\n\tfor (const e of gm.exon) {\n\t\tlet thin1: number[] | null = null,\n\t\t\tthick: number[] | null = null,\n\t\t\tthin2: number[] | null = null\n\t\tif (reverse) {\n\t\t\t// Check if coding start/stop are defined for reverse strand logic\n\t\t\tif (gm.codingstop === undefined || gm.codingstart === undefined) {\n\t\t\t\t// For non-coding or incomplete genes, render as thin\n\t\t\t\tthin1 = e\n\t\t\t} else {\n\t\t\t\tconst start = e[1],\n\t\t\t\t\tstop = e[0],\n\t\t\t\t\tcds5 = gm.codingstop,\n\t\t\t\t\tcds3 = gm.codingstart\n\t\t\t\tif (stop >= cds5) {\n\t\t\t\t\tthin1 = e\n\t\t\t\t} else if (stop >= cds3) {\n\t\t\t\t\tif (start >= cds5) {\n\t\t\t\t\t\tthin1 = [cds5, start]\n\t\t\t\t\t\tthick = [stop, cds5]\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthick = e\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (start >= cds5) {\n\t\t\t\t\t\t// assumption: 1 single continuous cds\n\t\t\t\t\t\tthin1 = [cds5, start]\n\t\t\t\t\t\tthin2 = [stop, cds3]\n\t\t\t\t\t\tthick = [cds3, cds5]\n\t\t\t\t\t} else if (start >= cds3) {\n\t\t\t\t\t\tthin2 = [stop, cds3]\n\t\t\t\t\t\tthick = [cds3, start]\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthin2 = e\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Check if coding start/stop are defined for forward strand logic\n\t\t\tif (gm.codingstart === undefined || gm.codingstop === undefined) {\n\t\t\t\t// For non-coding or incomplete genes, render as thin\n\t\t\t\tthin1 = e\n\t\t\t} else {\n\t\t\t\tif (e[1] <= gm.codingstart) {\n\t\t\t\t\tthin1 = e\n\t\t\t\t} else if (e[1] <= gm.codingstop) {\n\t\t\t\t\tif (e[0] <= gm.codingstart) {\n\t\t\t\t\t\tthin1 = [e[0], gm.codingstart]\n\t\t\t\t\t\tthick = [gm.codingstart, e[1]]\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthick = e\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (e[0] <= gm.codingstart) {\n\t\t\t\t\t\t// assumption: 1 single continuous cds\n\t\t\t\t\t\tthin1 = [e[0], gm.codingstart]\n\t\t\t\t\t\tthin2 = [gm.codingstop, e[1]]\n\t\t\t\t\t\tthick = [gm.codingstart, gm.codingstop]\n\t\t\t\t\t} else if (e[0] < gm.codingstop) {\n\t\t\t\t\t\tthin2 = [gm.codingstop, e[1]]\n\t\t\t\t\t\tthick = [e[0], gm.codingstop]\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthin2 = e\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (thin1) {\n\t\t\tctx.fillStyle = '#aaa'\n\t\t\tconst exonw = Math.max(1, (thin1[1] - thin1[0]) * exonsf)\n\t\t\tctx.fillRect(x, pad, exonw, h - pad * 2)\n\t\t\tx += exonw\n\t\t}\n\t\tif (thick) {\n\t\t\tctx.fillStyle = color\n\t\t\tconst exonw = Math.max(1, (thick[1] - thick[0]) * exonsf)\n\t\t\tctx.fillRect(x, 0, exonw, h)\n\t\t\tx += exonw\n\t\t}\n\t\tif (thin2) {\n\t\t\tctx.fillStyle = '#aaa'\n\t\t\tconst exonw = Math.max(1, (thin2[1] - thin2[0]) * exonsf)\n\t\t\tctx.fillRect(x, pad, exonw, h - pad * 2)\n\t\t\tx += exonw\n\t\t}\n\t\tx += intronpx\n\t}\n}\n\n/**\n * Sketches a gene model summary across multiple regions.\n *\n * @param holder - D3 selection to append canvas to\n * @param rglst - List of exon regions\n * @param gm - Gene model\n * @param exonsf - Exon scale factor\n * @param intronw - Intron width\n * @param pxwidth - Total width in pixels\n * @param h - Height in pixels\n * @param color - Color for coding regions\n */\nexport function sketchGmsum(\n\tholder: Div | Td,\n\trglst: ExonRegion[],\n\tgm: GeneModelWithDomains,\n\texonsf: number,\n\tintronw: number,\n\tpxwidth: number,\n\th: number,\n\tcolor: string\n): void {\n\tconst canvas = holder.append('canvas').node() as HTMLCanvasElement\n\tconst pad = Math.ceil(h / 5)\n\tconst ctx = setupCanvas(canvas, pxwidth, h)\n\n\tlet start: number | undefined\n\tlet x = 0\n\tfor (const r of rglst) {\n\t\tif (r.chr !== gm.chr) {\n\t\t\tx += r.width! + intronw\n\t\t\tcontinue\n\t\t}\n\t\tif (gm.start >= r.start && gm.start <= r.stop) {\n\t\t\tstart = x + (r.reverse ? r.stop - gm.start : gm.start - r.start) * exonsf\n\t\t\tbreak\n\t\t}\n\t\tx += r.width! + intronw\n\t}\n\tlet stop: number | undefined\n\tx = 0\n\tfor (const r of rglst) {\n\t\tif (r.chr !== gm.chr) {\n\t\t\tx += r.width! + intronw\n\t\t\tcontinue\n\t\t}\n\t\tif (gm.stop >= r.start && gm.stop <= r.stop) {\n\t\t\tstop = x + (r.reverse ? r.stop - gm.stop : gm.stop - r.start) * exonsf\n\t\t\tbreak\n\t\t}\n\t\tx += r.width! + intronw\n\t}\n\n\tif (start !== undefined && stop !== undefined) {\n\t\tctx.strokeStyle = color\n\t\tctx.beginPath()\n\t\tctx.moveTo(start, Math.floor(h / 2) + 0.5)\n\t\tctx.lineTo(stop, Math.floor(h / 2) + 0.5)\n\t\tctx.stroke()\n\t}\n\n\tconst thin: number[][] = []\n\tif (gm.utr5) thin.push(...gm.utr5)\n\tif (gm.utr3) thin.push(...gm.utr3)\n\tif (!gm.cdslen) thin.push(...gm.exon)\n\tfor (const e of thin) {\n\t\tlet x = 0\n\t\tfor (const r of rglst) {\n\t\t\tif (r.chr !== gm.chr) {\n\t\t\t\tx += r.width! + intronw\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst start = Math.max(e[0], r.start)\n\t\t\tconst stop = Math.min(e[1], r.stop)\n\t\t\tif (start >= stop) {\n\t\t\t\tx += r.width! + intronw\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tctx.fillStyle = '#aaa'\n\t\t\tctx.fillRect(\n\t\t\t\tx + (r.reverse ? (r.stop - stop) * exonsf : (start - r.start) * exonsf),\n\t\t\t\tpad,\n\t\t\t\tMath.max(1, (stop - start) * exonsf),\n\t\t\t\th - pad * 2\n\t\t\t)\n\t\t\tx += r.width! + intronw\n\t\t}\n\t}\n\tif (gm.coding) {\n\t\tfor (const e of gm.coding) {\n\t\t\tlet x = 0\n\t\t\tfor (const r of rglst) {\n\t\t\t\tif (r.chr !== gm.chr) {\n\t\t\t\t\tx += r.width! + intronw\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst start = Math.max(e[0], r.start)\n\t\t\t\tconst stop = Math.min(e[1], r.stop)\n\t\t\t\tif (start >= stop) {\n\t\t\t\t\tx += r.width! + intronw\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tctx.fillStyle = color\n\t\t\t\tctx.fillRect(\n\t\t\t\t\tx + (r.reverse ? (r.stop - stop) * exonsf : (start - r.start) * exonsf),\n\t\t\t\t\t0,\n\t\t\t\t\tMath.max(1, (stop - start) * exonsf),\n\t\t\t\t\th\n\t\t\t\t)\n\t\t\t\tx += r.width! + intronw\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Sketches an RNA structure showing UTRs, coding region, and protein domains.\n *\n * @param holder - D3 selection to append canvas to\n * @param gm - Gene model with RNA and domain information\n * @param pxwidth - Width in pixels\n * @param color - Color for coding region\n */\nexport function sketchRna(holder: Div | Td, gm: GeneModelWithDomains, pxwidth: number, color: string): void {\n\tconst canvas = holder.append('canvas').node() as HTMLCanvasElement\n\tconst h = 20\n\tconst pad = 4\n\tconst ctx = setupCanvas(canvas, pxwidth, h)\n\n\tif (!gm.cdslen) {\n\t\tctx.fillStyle = '#aaa'\n\t\tctx.fillRect(0, pad, pxwidth, h - pad * 2)\n\t\treturn\n\t}\n\tconst sf = pxwidth / gm.rnalen!\n\tlet x = 0\n\tif (gm.utr5) {\n\t\tlet ulen = 0\n\t\tfor (const e of gm.utr5) ulen += e[1] - e[0]\n\t\tctx.fillStyle = '#aaa'\n\t\tctx.fillRect(0, pad, sf * ulen, h - pad * 2)\n\t\tx = sf * ulen\n\t}\n\tif (gm.pdomains && gm.pdomains.length) {\n\t\tctx.fillStyle = 'white'\n\t\tctx.fillRect(x, 0, gm.cdslen * sf, h)\n\t\tgm.pdomains.sort((a, b) => b.stop - b.start - a.stop + a.start)\n\t\tfor (const domain of gm.pdomains) {\n\t\t\tctx.fillStyle = domain.color\n\t\t\tctx.fillRect(x + domain.start * 3 * sf, 0, (domain.stop - domain.start + 1) * 3 * sf, h)\n\t\t}\n\t\tctx.strokeStyle = 'black'\n\t\tctx.strokeRect(x, 0, gm.cdslen * sf, h)\n\t} else {\n\t\tctx.fillStyle = color\n\t\tctx.fillRect(x, 0, gm.cdslen * sf, h)\n\t}\n\tx += gm.cdslen * sf\n\tif (gm.utr3) {\n\t\tlet ulen = 0\n\t\tfor (const e of gm.utr3) ulen += e[1] - e[0]\n\t\tctx.fillStyle = '#aaa'\n\t\tctx.fillRect(x, pad, sf * ulen, h - pad * 2)\n\t}\n}\n\n/**\n * Sketches a protein structure showing protein domains.\n *\n * @param holder - D3 selection to append canvas to\n * @param gm - Gene model with protein domain information\n * @param pxwidth - Width in pixels\n */\nexport function sketchProtein2(holder: Div | Td, gm: GeneModelWithDomains, pxwidth: number): void {\n\tconst canvas = holder.append('canvas').node() as HTMLCanvasElement\n\tconst h = 20\n\tconst ctx = setupCanvas(canvas, pxwidth, h)\n\n\tconst sf = pxwidth / (gm.cdslen! / 3)\n\tgm.pdomains!.sort((a, b) => b.stop - b.start - a.stop + a.start)\n\tctx.fillStyle = 'white'\n\tctx.fillRect(0, 0, pxwidth, h)\n\tfor (const domain of gm.pdomains!) {\n\t\tctx.fillStyle = domain.color\n\t\tctx.fillRect(domain.start * sf, 0, (domain.stop - domain.start + 1) * sf, h)\n\t}\n\tctx.strokeStyle = 'black'\n\tctx.strokeRect(0, 0, pxwidth, h)\n}\n\n/**\n * Sketches a gene structure with exons, introns, UTRs, and strand direction.\n *\n * @param holder - D3 selection to append canvas to\n * @param gm - Gene model\n * @param pxwidth - Width in pixels\n * @param h - Height in pixels\n * @param bpstart - Start base pair position\n * @param bpstop - Stop base pair position\n * @param color - Color for gene features\n * @param nostrand - If true, don't show strand direction\n * @param reverse - If true, reverse the direction\n */\nexport function sketchGene(\n\tholder: Div | Td,\n\tgm: GeneModelWithDomains,\n\tpxwidth: number,\n\th: number,\n\tbpstart: number,\n\tbpstop: number,\n\tcolor: string,\n\tnostrand?: boolean,\n\treverse?: boolean\n): void {\n\tconst canvas = holder.append('canvas').node() as HTMLCanvasElement\n\tconst ctx = setupCanvas(canvas, pxwidth, h)\n\n\tconst sf = scaleLinear().range([1, pxwidth])\n\tif (reverse) {\n\t\tsf.domain([bpstop, bpstart])\n\t} else {\n\t\tsf.domain([bpstart, bpstop])\n\t}\n\tctx.strokeStyle = color\n\tctx.fillStyle = color\n\tbpBox(ctx, gm.start, gm.stop, bpstart, bpstop, h / 2, 1)\n\tconst pad = Math.ceil(h / 5)\n\tif (gm.utr3) {\n\t\tfor (const e of gm.utr3) {\n\t\t\tbpBox(ctx, e[0], e[1], bpstart, bpstop, pad + 1, h - pad * 2 - 1)\n\t\t}\n\t}\n\tif (gm.utr5) {\n\t\tfor (const e of gm.utr5) {\n\t\t\tbpBox(ctx, e[0], e[1], bpstart, bpstop, pad + 1, h - pad * 2 - 1)\n\t\t}\n\t}\n\tif (gm.coding) {\n\t\tfor (const e of gm.coding) {\n\t\t\tbpBox(ctx, e[0], e[1], bpstart, bpstop, 1, h)\n\t\t}\n\t}\n\tif (gm.codingstart === gm.codingstop) {\n\t\tfor (const e of gm.exon) {\n\t\t\tbpBox(ctx, e[0], e[1], bpstart, bpstop, pad + 1, h - pad * 2 - 1)\n\t\t}\n\t}\n\tif (!nostrand && gm.strand) {\n\t\tconst ypad = 3 // but not pad\n\t\tif (gm.coding) {\n\t\t\tfor (const e of gm.coding) {\n\t\t\t\tbpStrand(ctx, gm.strand, e[0], e[1], bpstart, bpstop, 1 + ypad, h - ypad * 2 - 1, 'white')\n\t\t\t}\n\t\t}\n\t\tif (gm.intron) {\n\t\t\tfor (const e of gm.intron) {\n\t\t\t\tbpStrand(ctx, gm.strand, e[0], e[1], bpstart, bpstop, 1 + ypad, h - ypad * 2 - 1, color)\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction bpBox(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstart: number,\n\t\tstop: number,\n\t\tborderstart: number,\n\t\tborderstop: number,\n\t\ty: number,\n\t\th: number\n\t): void {\n\t\tconst a = Math.max(start, borderstart)\n\t\tconst b = Math.min(stop, borderstop)\n\t\tif (a >= b) return\n\t\tctx.fillRect(Math.floor(sf(reverse ? b : a)), y, Math.max(1, Math.abs(sf(b) - sf(a))), h)\n\t}\n\n\tfunction bpStrand(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstrand: string,\n\t\tstart: number,\n\t\tstop: number,\n\t\tborderstart: number,\n\t\tborderstop: number,\n\t\ty: number,\n\t\th: number,\n\t\tstrokeColor: string\n\t): void {\n\t\tconst a = Math.max(start, borderstart)\n\t\tconst b = Math.min(stop, borderstop)\n\t\tif (a >= b) return\n\t\tconst pad = 2,\n\t\t\tspacing = h / 2,\n\t\t\tw = sf(b) - sf(a)\n\t\tif (w <= pad * 2 + h / 2) return\n\t\tctx.strokeStyle = strokeColor\n\t\tconst fillcount = Math.floor((w - pad * 2) / (h / 2 + spacing))\n\t\tlet x = Math.floor(sf(a) + (w - fillcount * (h / 2 + spacing)) / 2) + 0.5\n\t\tctx.beginPath()\n\t\tfor (let i = 0; i < fillcount; i++) {\n\t\t\tif (strand === '+') {\n\t\t\t\tctx.moveTo(x, y)\n\t\t\t\tctx.lineTo(x + h / 2, y + h / 2)\n\t\t\t\tctx.lineTo(x, y + h)\n\t\t\t} else {\n\t\t\t\tctx.moveTo(x + h / 2, y)\n\t\t\t\tctx.lineTo(x, y + h / 2)\n\t\t\t\tctx.lineTo(x + h / 2, y + h)\n\t\t\t}\n\t\t\tx += h / 2 + spacing\n\t\t}\n\t\tctx.stroke()\n\t}\n}\n\n/**\n * Displays protein information (amino acid length) as text.\n * Note: This function does not use canvas rendering.\n *\n * @param holder - D3 selection to append span to\n * @param gm - Gene model with CDS information\n * @param pxwidth - Width in pixels (unused but kept for API compatibility)\n * @returns The created span element\n */\nexport function sketchProtein(holder: Div | Td, gm: GeneModelWithDomains, _pxwidth: number) {\n\tlet aalen = -1\n\tif (gm.cdslen) {\n\t\taalen = gm.cdslen / 3\n\t}\n\treturn holder\n\t\t.append('span')\n\t\t.html(\n\t\t\t' ' +\n\t\t\t\t(aalen > 0 ? Math.ceil(aalen) + ' AA' + (Number.isInteger(aalen) ? '' : ' (incomplete CDS)') : 'noncoding')\n\t\t)\n}\n", "import { sketchGmsum, sketchProtein } from './sketchGm'\nimport { exoncolor } from '#shared/common.js'\nimport type { GeneModel, ExonRegion, IsoformSelectOpts } from './types/isoformSelect'\nimport type { Td } from '../types/d3'\n\n/*\nStandalone reusable component for displaying and selecting gene model isoforms.\n\nExtracted from block.js showisoform4switch() to be reusable.\n\nTwo modes:\n\nSingle-select (default):\n Click a row to select one isoform. Calls onSelect(gm).\n Used by block.js for isoform switching.\n\nMulti-select (multiSelect: true):\n Each row has a checkbox. A \"Select all\" toggle at the top and a\n submit button at the bottom. Calls onMultiSelect(gms) on submit.\n Used by isoformExpression.ts to create a custom numeric termCollection\n from multiple isoforms.\n\n******* required (both modes)\n.holder d3 selection to render into\n.allgm array of gene model objects\n\n******* single-select\n.onSelect callback(gm) when an isoform row is clicked\n\n******* multi-select\n.multiSelect set to true\n.onMultiSelect callback(gms[]) when submit is clicked\n\n******* optional\n.usegm currently active gene model, highlighted (single-select only)\n.selectedIsoforms Set of pre-checked isoform IDs (multi-select only)\n.submitLabel text for the submit button (multi-select only, default \"Submit\")\n.maxHeight max height in px before scrolling (default 200)\n.scrollThreshold number of isoforms before enabling scroll (default 10)\n*/\n\n/**\n * Merge all exon regions across gene models to compute a unified layout\n * for sketching isoform exon structure.\n *\n * Returns [rglst, chrcount] where rglst is the merged exon region list\n * and chrcount is the number of distinct chromosomes.\n */\nexport function allgm2sum(gmlst: GeneModel[]) {\n\tconst chr2gm = new Map<string, GeneModel[]>()\n\tfor (const gm of gmlst) {\n\t\tif (gm.hidden) {\n\t\t\tcontinue\n\t\t}\n\t\tif (!chr2gm.has(gm.chr)) {\n\t\t\tchr2gm.set(gm.chr, [])\n\t\t}\n\t\tchr2gm.get(gm.chr)!.push(gm)\n\t}\n\tconst alllst: ExonRegion[] = []\n\tfor (const [chr, gmlstForChr] of chr2gm.entries()) {\n\t\tconst elst: number[][] = []\n\t\tfor (const m of gmlstForChr) {\n\t\t\tfor (const e of m.exon) {\n\t\t\t\telst.push([e[0], e[1]])\n\t\t\t}\n\t\t}\n\t\tif (elst.length === 0) continue\n\t\tconst reverse = gmlstForChr[0].strand == '-'\n\t\telst.sort((a: number[], b: number[]) => a[0] - b[0])\n\t\tlet thisregion = elst[0]\n\t\tconst rglst: ExonRegion[] = []\n\t\tfor (let i = 1; i < elst.length; i++) {\n\t\t\tconst e = elst[i]\n\t\t\tif (e[0] > thisregion[1]) {\n\t\t\t\tconst r = {\n\t\t\t\t\tchr: chr,\n\t\t\t\t\tbstart: thisregion[0],\n\t\t\t\t\tbstop: thisregion[1],\n\t\t\t\t\tstart: thisregion[0],\n\t\t\t\t\tstop: thisregion[1],\n\t\t\t\t\treverse: reverse\n\t\t\t\t}\n\t\t\t\tif (reverse) {\n\t\t\t\t\trglst.unshift(r)\n\t\t\t\t} else {\n\t\t\t\t\trglst.push(r)\n\t\t\t\t}\n\t\t\t\tthisregion = e\n\t\t\t} else {\n\t\t\t\tthisregion[1] = Math.max(thisregion[1], e[1])\n\t\t\t}\n\t\t}\n\t\tconst r = {\n\t\t\tchr: chr,\n\t\t\tbstart: thisregion[0],\n\t\t\tbstop: thisregion[1],\n\t\t\tstart: thisregion[0],\n\t\t\tstop: thisregion[1],\n\t\t\treverse: reverse\n\t\t}\n\t\tif (reverse) {\n\t\t\trglst.unshift(r)\n\t\t} else {\n\t\t\trglst.push(r)\n\t\t}\n\t\talllst.push(...rglst)\n\t}\n\treturn [alllst, chr2gm.size] as const\n}\n\n/**\n * Render a list of gene model isoforms for selection.\n *\n * Single-select: click a row to select one isoform and call onSelect(gm).\n * Multi-select: checkboxes with select-all and submit button, calls onMultiSelect(gms).\n */\nexport function isoformSelect(opts: IsoformSelectOpts) {\n\tconst { holder, allgm, multiSelect } = opts\n\tconst maxHeight = opts.maxHeight ?? 200\n\tconst scrollThreshold = opts.scrollThreshold ?? 10\n\n\tconst [rglst, chrcount] = allgm2sum(allgm)\n\tif (rglst.length === 0) return\n\n\t// compute exon layout sizing\n\tlet pxwidth = 370\n\tlet intronpx = 10\n\tif (intronpx * (rglst.length - 1) > pxwidth * 0.3) {\n\t\tintronpx = Math.max(2, (pxwidth * 0.3) / (rglst.length - 1))\n\t}\n\tconst inw = intronpx * (rglst.length - 1)\n\tconst exonlen = rglst.reduce((a: number, b: ExonRegion) => a + b.stop - b.start, 0)\n\tconst exonsf = (pxwidth - (inw > pxwidth * 0.4 ? 0 : inw)) / exonlen\n\tpxwidth = exonlen * exonsf + inw\n\tfor (const e of rglst) {\n\t\te.width = Math.ceil((e.stop - e.start) * exonsf)\n\t}\n\n\t// multi-select state\n\tconst checkedSet = new Set<string>(multiSelect ? opts.selectedIsoforms || [] : [])\n\tconst checkboxes: { isoform: string; input: any }[] = []\n\tlet selectAllCheckbox: any\n\tlet submitBtn: any\n\n\t// select-all header (multi-select only)\n\tif (multiSelect) {\n\t\tconst headerDiv = holder.append('div').style('margin-bottom', '4px')\n\t\tselectAllCheckbox = headerDiv\n\t\t\t.append('input')\n\t\t\t.attr('type', 'checkbox')\n\t\t\t.property('checked', checkedSet.size === allgm.length)\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.on('change', function (this: HTMLInputElement) {\n\t\t\t\tconst checked = this.checked\n\t\t\t\tfor (const cb of checkboxes) {\n\t\t\t\t\tcb.input.property('checked', checked)\n\t\t\t\t\tif (checked) checkedSet.add(cb.isoform)\n\t\t\t\t\telse checkedSet.delete(cb.isoform)\n\t\t\t\t}\n\t\t\t\tupdateSubmitBtn()\n\t\t\t})\n\t\theaderDiv\n\t\t\t.append('span')\n\t\t\t.text(' Select all')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.style('user-select', 'none')\n\t\t\t.on('click', () => {\n\t\t\t\tconst el = selectAllCheckbox.node() as HTMLInputElement\n\t\t\t\tel.checked = !el.checked\n\t\t\t\tel.dispatchEvent(new Event('change'))\n\t\t\t})\n\t}\n\n\t// scrollable container if many isoforms\n\tlet mayscroll = holder\n\tif (allgm.length > scrollThreshold) {\n\t\tmayscroll = holder\n\t\t\t.append('div')\n\t\t\t.attr('tabindex', 0)\n\t\t\t.style('height', maxHeight + 'px')\n\t\t\t.style('overflow-y', 'scroll')\n\t\t\t.style('resize', 'vertical')\n\t}\n\n\tconst table = mayscroll.append('table').style('color', '#555')\n\n\t// single-select: track labels for highlighting\n\tconst gmlabellst: { isoform: string; chr: string; start: number; label: Td }[] = []\n\n\tfor (const gm of allgm) {\n\t\tconst tr = table.append('tr').attr('tabindex', 0)\n\n\t\tif (multiSelect) {\n\t\t\t// checkbox column\n\t\t\tconst cb = tr\n\t\t\t\t.append('td')\n\t\t\t\t.append('input')\n\t\t\t\t.attr('type', 'checkbox')\n\t\t\t\t.property('checked', checkedSet.has(gm.isoform))\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.on('change', function (this: HTMLInputElement) {\n\t\t\t\t\tif (this.checked) checkedSet.add(gm.isoform)\n\t\t\t\t\telse checkedSet.delete(gm.isoform)\n\t\t\t\t\tselectAllCheckbox.property('checked', checkedSet.size === allgm.length)\n\t\t\t\t\tupdateSubmitBtn()\n\t\t\t\t})\n\t\t\tcheckboxes.push({ isoform: gm.isoform, input: cb })\n\n\t\t\t// clicking or pressing Enter/Space on the row toggles the checkbox\n\t\t\ttr.style('cursor', 'pointer').on('click', (event: MouseEvent) => {\n\t\t\t\tif ((event.target as HTMLElement).tagName === 'INPUT') return\n\t\t\t\tconst el = cb.node() as HTMLInputElement\n\t\t\t\tel.checked = !el.checked\n\t\t\t\tel.dispatchEvent(new Event('change'))\n\t\t\t})\n\t\t\ttr.on('keydown', (event: KeyboardEvent) => {\n\t\t\t\tif (event.key === 'Enter' || event.key === ' ') {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tconst el = cb.node() as HTMLInputElement\n\t\t\t\t\tel.checked = !el.checked\n\t\t\t\t\tel.dispatchEvent(new Event('change'))\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\t// single-select: click row to select\n\t\t\ttr.attr('class', 'sja_clb')\n\t\t\tconst selectRow = () => {\n\t\t\t\tfor (const gm2 of gmlabellst) {\n\t\t\t\t\tgm2.label.style(\n\t\t\t\t\t\t'color',\n\t\t\t\t\t\tgm2.isoform == gm.isoform && gm2.chr == gm.chr && gm2.start == gm.start ? '#cc0000' : '#545454'\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\topts.onSelect!(gm)\n\t\t\t}\n\t\t\ttr.on('click', selectRow)\n\t\t\ttr.on('keydown', (event: KeyboardEvent) => {\n\t\t\t\tif (event.key == 'Enter') selectRow()\n\t\t\t})\n\t\t}\n\n\t\t// DEFAULT label\n\t\ttr.append('td')\n\t\t\t.text(gm.isdefault ? 'DEFAULT' : '')\n\t\t\t.style('font-size', '.6em')\n\n\t\t// isoform name\n\t\tconst usegm = !multiSelect ? opts.usegm : undefined\n\t\tconst isActive =\n\t\t\t!multiSelect && usegm && gm.isoform == usegm.isoform && gm.chr == usegm.chr && gm.start == usegm.start\n\t\tconst lab = tr\n\t\t\t.append('td')\n\t\t\t.text(gm.isoform)\n\t\t\t.style('color', isActive ? '#cc0000' : '#545454')\n\t\tif (!multiSelect) {\n\t\t\tgmlabellst.push({ isoform: gm.isoform, chr: gm.chr, start: gm.start, label: lab })\n\t\t}\n\n\t\t// chromosome column (only if multiple chromosomes)\n\t\tif (chrcount > 1) {\n\t\t\ttr.append('td').text(gm.chr)\n\t\t}\n\n\t\t// exon structure sketch\n\t\tsketchGmsum(tr.append('td'), rglst, gm, exonsf, intronpx, pxwidth, 16, exoncolor)\n\n\t\t// protein length sketch\n\t\tsketchProtein(tr.append('td'), gm, 200)\n\t}\n\n\t// submit button (multi-select only)\n\tif (multiSelect) {\n\t\tsubmitBtn = holder\n\t\t\t.append('button')\n\t\t\t.text(opts.submitLabel || 'Submit')\n\t\t\t.style('margin-top', '8px')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.on('click', () => {\n\t\t\t\tconst selected = allgm.filter(gm => checkedSet.has(gm.isoform))\n\t\t\t\tif (selected.length > 0) opts.onMultiSelect!(selected)\n\t\t\t})\n\t\tupdateSubmitBtn()\n\t}\n\n\tfunction updateSubmitBtn() {\n\t\tconst label = multiSelect ? opts.submitLabel || 'Submit' : 'Submit'\n\t\tsubmitBtn.property('disabled', checkedSet.size === 0).text(`${label} (${checkedSet.size})`)\n\t}\n}\n", "import type { LegendCircleReferenceOpts } from './types/LegendCircleReference'\nimport type { Div, SvgG } from '../types/d3'\nimport { Menu, make_radios } from '#dom'\n\n/** Creates a visual reference of the circle elements used\n * in a plot by rendering the smallest to largest circles\n * in scale.\n *\n * Also includes the option to set the min to max radius and\n * whether the scale is ascending or descending by clicking\n * on the holder.\n */\n\nexport class LegendCircleReference {\n\tg: SvgG\n\tinputMax: number\n\tinputMin: number\n\tisAscending: boolean\n\tmaxLabel: number\n\tmaxRadius: number\n\tminLabel: number\n\tminRadius: number\n\tmenu?: {\n\t\tminMaxLabel?: string\n\t\tshowOrder?: boolean\n\t\tcallback: (obj: { min: number; max: number; isAscending: boolean }) => void\n\t}\n\ttitle?: string\n\treadonly color = '#aaa'\n\treadonly shift = 20\n\treadonly width = 70\n\treadonly tip = new Menu({ padding: '5px' })\n\treadonly x = 40\n\treadonly y = 40\n\tconstructor(opts: LegendCircleReferenceOpts) {\n\t\tthis.validateOpts(opts)\n\t\tthis.g = opts.g\n\t\tthis.inputMax = opts.inputMax\n\t\tthis.inputMin = opts.inputMin\n\t\tthis.isAscending = opts.isAscending ?? true\n\t\tthis.maxLabel = opts.maxLabel ?? opts.maxRadius\n\t\tthis.maxRadius = opts.maxRadius\n\t\tthis.minLabel = opts.minLabel ?? opts.minRadius\n\t\tthis.minRadius = opts.minRadius\n\n\t\tif (opts.menu) this.menu = opts.menu\n\t\tif (opts.title) this.title = opts.title\n\n\t\tthis.renderLegendComponent()\n\t}\n\n\tvalidateOpts(opts: LegendCircleReferenceOpts) {\n\t\tif (!opts.g) throw `Missing g in LegendCircleReference`\n\t\tif (opts.maxRadius > opts.inputMax) throw `Max radius must be less than inputMax`\n\t\tif (opts.minRadius < opts.inputMin) throw `Min radius must be greater than inputMin`\n\t}\n\n\trenderLegendComponent() {\n\t\tthis.g.selectAll('*').remove()\n\n\t\tif (this.title) this.g.append('text').style('font-weight', 'bold').style('font-size', '0.8em').text(this.title)\n\n\t\tconst minG = this.g.append('g').attr('transform', `translate(${this.x},${this.y})`)\n\t\tconst maxG = this.g.append('g').attr('transform', `translate(${this.x + this.width},${this.y})`)\n\n\t\t//Starting text and circle element\n\t\tconst startRadius = this.isAscending ? this.minRadius : this.maxRadius\n\t\tthis.renderLabel(minG, -startRadius - this.shift, this.minLabel)\n\t\tthis.renderReferenceCircle(minG, startRadius)\n\n\t\t//Ending text and circle element\n\t\tconst endRadius = this.isAscending ? this.maxRadius : this.minRadius\n\t\tthis.renderReferenceCircle(maxG, endRadius)\n\t\tthis.renderLabel(maxG, endRadius + this.shift, this.maxLabel)\n\n\t\t//Lines connecting the top and bottom of the circles\n\t\tthis.renderScalingLine(minG, this.minRadius, this.maxRadius)\n\t\tthis.renderScalingLine(minG, -this.minRadius, -this.maxRadius)\n\n\t\tconst minBBox = minG.node()!.getBBox()\n\t\tconst maxBBox = maxG.node()!.getBBox()\n\n\t\tif (this.menu) {\n\t\t\tthis.g\n\t\t\t\t.append('rect')\n\t\t\t\t.attr('width', minBBox.width + maxBBox.width)\n\t\t\t\t.attr('height', (this.isAscending ? maxBBox.height : minBBox.height) + 20)\n\t\t\t\t.attr('fill', 'transparent')\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tthis.renderMenu()\n\t\t\t\t})\n\t\t}\n\t}\n\n\trenderReferenceCircle(g: SvgG, radius: number) {\n\t\tg.append('circle')\n\t\t\t.style('fill', this.color)\n\t\t\t.style('stroke', this.color)\n\t\t\t.attr('cx', 0)\n\t\t\t.attr('cy', 0)\n\t\t\t.attr('r', radius)\n\t}\n\n\trenderLabel(g: SvgG, x: number, text: number) {\n\t\tg.append('text').attr('x', x).attr('y', 5).style('font-size', '.8em').text(text)\n\t}\n\n\trenderScalingLine(g: SvgG, minRadius: number, maxRadius: number) {\n\t\tg.append('line')\n\t\t\t.attr('x1', 0)\n\t\t\t.attr('y1', this.isAscending ? minRadius : maxRadius)\n\t\t\t.attr('x2', this.width)\n\t\t\t.attr('y2', this.isAscending ? maxRadius : minRadius)\n\t\t\t.style('stroke', this.color)\n\t}\n\n\trenderMenu() {\n\t\tif (!this.menu) return\n\t\tthis.tip.clear().showunder(this.g.node())\n\t\tconst div = this.tip.d.append('div')\n\t\tconst minMaxRow = div.append('div')\n\t\tif (this.menu?.minMaxLabel)\n\t\t\tminMaxRow\n\t\t\t\t.append('span')\n\t\t\t\t.style('padding-right', '10px')\n\t\t\t\t.style('opacity', 0.7)\n\t\t\t\t.style('font-size', '.8em')\n\t\t\t\t.text(`${this.menu.minMaxLabel.toUpperCase()}`)\n\n\t\tthis.addInput(minMaxRow, 'Min', this.minRadius)\n\t\tthis.addInput(minMaxRow, 'Max', this.maxRadius)\n\n\t\tif (this.menu.showOrder) {\n\t\t\tconst orderRow = div.append('div')\n\t\t\tmake_radios({\n\t\t\t\tholder: orderRow,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tchecked: this.isAscending,\n\t\t\t\t\t\tlabel: 'Ascending',\n\t\t\t\t\t\ttitle: 'Show in ascending order',\n\t\t\t\t\t\tvalue: true\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tchecked: !this.isAscending,\n\t\t\t\t\t\tlabel: 'Descending',\n\t\t\t\t\t\ttitle: 'Show in descending order',\n\t\t\t\t\t\tvalue: false\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\tcallback: value => {\n\t\t\t\t\tif (!this.menu) return //so TS doesn't complain\n\t\t\t\t\tthis.isAscending = value\n\t\t\t\t\tthis.menu.callback({ min: this.minRadius, max: this.maxRadius, isAscending: this.isAscending })\n\t\t\t\t\tthis.renderLegendComponent()\n\t\t\t\t\tthis.tip.hide()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\taddInput(div: Div, label: string, value: number) {\n\t\tdiv.append('label').text(label)\n\t\tconst input = div\n\t\t\t.append('input')\n\t\t\t.style('width', '50px')\n\t\t\t.attr('type', 'number')\n\t\t\t.attr('min', this.inputMin)\n\t\t\t.attr('max', this.inputMax)\n\t\t\t.attr('value', value)\n\t\t\t.on('change', () => {\n\t\t\t\tif (!this.menu) return //so TS doesn't complain\n\t\t\t\tconst value = input.property('value')\n\t\t\t\tthis[`${label.toLowerCase()}Radius`] = Number(value)\n\t\t\t\tthis.menu.callback({ min: this.minRadius, max: this.maxRadius, isAscending: this.isAscending })\n\t\t\t\tthis.renderLegendComponent()\n\t\t\t\tthis.tip.hide()\n\t\t\t})\n\t}\n}\n", "import type { Svg, SvgG } from '../types/d3'\n/**\n * Label Width Calculator for Data Visualizations\n *\n * This utility function calculates the maximum width needed to display text labels\n * in SVG-based data visualizations. It works by temporarily rendering each label\n * to measure its exact width, accounting for font characteristics and actual text content.\n *\n * The function is designed to work with different visualization types (like box plots\n * and violin plots) by providing flexible ways to extract label text from data:\n *\n * 1. Custom Function: You can provide your own function to extract label text\n * 2. Standard Formats: Without a custom function, it automatically handles:\n * - Box plot data: Uses item.boxplot.label\n * - Violin plot data: Combines item.label with item.plotValueCount as \"label, n=count\"\n * - Simple data: Uses item.label directly\n * Be aware that if the svg is hidden this function will return 0 as getBBox will return 0\n *\n * Example Usage:\n *\n * // With box plot data:\n * const width2 = getMaxLabelWidth(svg, boxPlotData);\n * // Automatically uses boxPlotData[i].boxplot.label\n *\n * // With violin plot data:\n * const width3 = getMaxLabelWidth(svg, violinData);\n * // Automatically formats as \"label, n=count\"\n *\n * Implementation Details:\n * - Creates a temporary text element for each measurement\n * - Uses the browser's rendering engine for precise width calculation\n * - Removes the temporary element after measurement\n * - Maintains the maximum width seen across all labels\n *\n * @param svg - D3 selection of an SVG element where temporary text elements will be added\n * for measurement. These elements are immediately removed after measuring.\n *\n * @param items - Array of strings containing label information.\n * @param size - Font size multiplier for labels. Default is 1.\n * @returns The width in pixels of the widest label in the provided items array\n */\nexport function getMaxLabelWidth(svg: Svg | SvgG, items: string[], size = 1): number {\n\tlet maxLabelLgth = 0\n\tfor (const item of items) {\n\t\t// Create temporary text element for measurement\n\t\tconst label = svg.append('text').text(item).style('font-size', `${size}em`)\n\n\t\t// Update maximum width if current label is wider\n\t\t//If the svg is hidden getBBox will return 0 !!!!\n\t\tmaxLabelLgth = Math.max(maxLabelLgth, label.node()!.getBBox().width)\n\n\t\t// Clean up: remove temporary element\n\t\tlabel.remove()\n\t}\n\treturn maxLabelLgth\n}\n", "import type { RawCategoricalTerm, TermGroupSetting, TermValues } from '#types'\n\nconst termType = 'categorical'\n\nexport class CategoricalBase {\n\tid: string\n\tname: string\n\tgroupsetting: TermGroupSetting\n\tvalues: TermValues\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic fill(term: RawCategoricalTerm) {\n\t\tif (term instanceof CategoricalBase) return\n\t\tCategoricalBase.validate(term)\n\t\tif (!term.name) term.name = term.id\n\t\tif (!term.groupsetting) term.groupsetting = { disabled: false }\n\t\tif (!term.values) term.values = {}\n\t}\n\n\tstatic validate(term: RawCategoricalTerm) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != termType) throw `incorrect term.type='${term?.type}', expecting '${termType}'`\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of tw.term literal object\n\tconstructor(term: RawCategoricalTerm) {\n\t\tCategoricalBase.validate(term)\n\t\tthis.id = term.id\n\t\tthis.name = term.name || term.id\n\t\tthis.groupsetting = term.groupsetting || { disabled: false }\n\t\tthis.values = term.values || {}\n\t}\n}\n", "import type { Term, TermWrapper, Q } from '#types'\nimport type { SetCellPropsSignature } from '../plots/matrix/matrix.xtw.ts'\nimport { type UseCase } from '#termsetting'\nimport { isDictionaryType } from '#shared'\nimport { deepFreeze } from '#rx'\n\nexport type TwOpts = {\n\tvocabApi?: any // TODO\n\tdefaultQ?: any // TODO\n\tdefaultQByTsHandler?: any // TODO\n\taddons?: {\n\t\t[TwTypeName: string]: {\n\t\t\t[methodName: string]: {\n\t\t\t\tvalue: (a: any) => any // required nested shape for native Object.defineProperties()\n\t\t\t}\n\t\t\t// | ((a: any) => any) // for convenience, not supported yet\n\t\t}\n\t}\n\t//usecase?: any // TODO\n}\n\nexport class TwBase {\n\ttype: string\n\t$id: string\n\tisAtomic = true\n\t#tw: TermWrapper\n\t#isFrozen = false\n\n\t// define addons below, to be set using Object.defineProperties(this)\n\t// by defining allowed method names here, subclasses that inherit from\n\t// TwBase will be type checked\n\tsetCellProps!: SetCellPropsSignature\n\n\t// TODO: may need to track these matrix specific tw props elsewhere\n\tsortSamples?: any\n\tminNumSamples?: number\n\tvalueFilter?: any\n\tvalues?: { [key: string]: any }\n\n\tconstructor(tw: TermWrapper, opts: TwOpts) {\n\t\tthis.#tw = tw\n\t\tthis.type = tw.type\n\t\tthis.isAtomic = true\n\t\tthis.$id = typeof tw.$id == 'string' ? tw.$id : get$id()\n\t\tif (tw.sortSamples) this.sortSamples = tw.sortSamples\n\t\tif (tw.minNumSamples) this.minNumSamples = tw.minNumSamples\n\t\tif (tw.valueFilter) this.valueFilter = tw.valueFilter\n\t\tif (tw.values) this.values = tw.values\n\n\t\t// By using Object.defineProperties(), addon methods are not enumerable\n\t\t// and makes the xtw instance compatible with structuredClone(),\n\t\t// in contrast to using Object.assign()\n\t\tif (opts.addons?.[this.type]) {\n\t\t\tObject.defineProperties(this, opts.addons[this.type])\n\t\t}\n\t}\n\n\tstatic setHiddenValues(q: Q, term: Term) {\n\t\tif (q.hiddenValues) return\n\t\tq.hiddenValues = {}\n\t\t// by default, fill-in with uncomputable values\n\t\tif (term.values) {\n\t\t\tfor (const k in term.values) {\n\t\t\t\tif (term.values[k].uncomputable) q.hiddenValues[k] = 1\n\t\t\t}\n\t\t}\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\trender(a: any): any {\n\t\tconsole.log(a)\n\t\tthrow `should implement this method in subclass code, as needed`\n\t}\n\n\tgetStatus(_?: UseCase, __?: any) {\n\t\t//if (_) {}\n\t\treturn { text: '' }\n\t}\n\n\tgetMinCopy(override: any = {}) {\n\t\tconst tw = this.#tw\n\t\tconst copy: any = { term: {}, q: structuredClone(override.q || tw.q) }\n\t\tif (tw.$id) copy.$id = tw.$id\n\t\tif (tw.term) {\n\t\t\tif (isDictionaryType(tw.term.type)) {\n\t\t\t\t// dictionary term\n\t\t\t\tif (tw.term.id) copy.term.id = tw.term.id\n\t\t\t\tif (tw.term.name) copy.term.name = tw.term.name\n\t\t\t\tif (tw.term.type) copy.term.type = tw.term.type\n\t\t\t\t//if (tw.term.values) copy.term.values = tw.term.values\n\t\t\t\tif ((tw.term as any).groupsetting) copy.term.groupsetting = (tw.term as any).groupsetting\n\t\t\t} else {\n\t\t\t\t// non-dictionary term\n\t\t\t\t// pass entire tw.term because non-dictionary terms\n\t\t\t\t// cannot get rehydrated on server-side\n\t\t\t\tcopy.term = structuredClone(tw.term)\n\t\t\t\t// dummy preset bins should not affect the uniqueness of a request payload\n\t\t\t\tif (copy.term.bins?.default?.isDummyPreset) delete copy.term.bins\n\t\t\t}\n\t\t}\n\t\tif (copy.q) {\n\t\t\tdelete copy.q.isAtomic\n\t\t}\n\t\treturn copy\n\t}\n\n\tdeepFreeze() {\n\t\tif (this.#isFrozen) return this\n\t\tdeepFreeze(this)\n\t\tthis.#isFrozen = true\n\t\treturn this\n\t}\n}\n\nconst idSuffix = `_${Math.random().toString().slice(-5)}_${Date.now().toString().slice(-8, -3)}`\nlet i = 0\n\nfunction get$id(): string {\n\treturn `TwBase_${i++}_${idSuffix}`\n}\n", "import { type TwOpts } from './TwBase.ts'\nimport type { RawIsoformExpTerm } from '#types'\nimport { ISOFORM_EXPRESSION } from '#shared/terms.js'\n\nexport class IsoformExpBase {\n\tisoform: string\n\tname: string\n\tunit: string\n\n\t// option to fill-in/mutate the input raw term object in-place\n\tstatic async fill(term: RawIsoformExpTerm, opts: TwOpts) {\n\t\tIsoformExpBase.validate(term)\n\t\tif (!term.name) {\n\t\t\tterm.unit = opts.vocabApi.termdbConfig.queries.isoformExpression?.unit || 'Isoform Expression'\n\t\t\tconst name = `${term.isoform} ${term.unit}`\n\t\t\tterm.name = name\n\t\t}\n\t}\n\n\tstatic validate(term: RawIsoformExpTerm) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != ISOFORM_EXPRESSION) throw `incorrect term.type='${term?.type}', expecting '${ISOFORM_EXPRESSION}'`\n\t\tif (!term.isoform && !term.name) throw 'no isoform or name present'\n\t\tif (!term.isoform || typeof term.isoform != 'string')\n\t\t\tthrow 'isoformExpression term.isoform must be non-empty string'\n\t}\n\n\tconstructor(term: RawIsoformExpTerm, opts: TwOpts) {\n\t\tIsoformExpBase.validate(term)\n\t\tthis.isoform = term.isoform || term.name\n\t\tthis.unit = term.unit || opts.vocabApi.termdbConfig.queries.isoformExpression?.unit || 'Isoform Expression'\n\t\tthis.name = term.name || `${term.isoform} ${this.unit}`\n\t}\n}\n", "import type { RawMetaboliteIntensityTerm, PresetNumericBins } from '#types'\n\nconst termType = 'metaboliteIntensity'\n\nexport class MetaboliteIntensityBase {\n\ttype = termType\n\tmetabolite: string\n\tname: string\n\tunit: string\n\tbins?: PresetNumericBins\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic async fill(term: RawMetaboliteIntensityTerm) {\n\t\tMetaboliteIntensityBase.validate(term)\n\t\tif (!term.metabolite) term.metabolite = term.name\n\t\telse if (!term.name) term.name = term.metabolite\n\t}\n\n\tstatic validate(term: RawMetaboliteIntensityTerm) {\n\t\tif (term.type != 'metaboliteIntensity') throw 'unexpected term.type'\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (!term.name && !term.metabolite) throw `missing both term.name and metabolite`\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of term literal object\n\tconstructor(term: RawMetaboliteIntensityTerm) {\n\t\tMetaboliteIntensityBase.validate(term)\n\t\tthis.metabolite = term.metabolite || term.name\n\t\tthis.name = term.name || term.metabolite\n\t\tthis.unit = term.unit || ''\n\t\tif (term.bins) this.bins = term.bins\n\t}\n}\n", "import type { RawProteomeAbundanceTerm, PresetNumericBins } from '#types'\n\nconst termType = 'proteomeAbundance'\n\nexport class ProteomeAbundanceBase {\n\ttype = termType\n\tprotein: string\n\tname: string\n\tunit: string\n\tbins?: PresetNumericBins\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic async fill(term: RawProteomeAbundanceTerm) {\n\t\tProteomeAbundanceBase.validate(term)\n\t\tif (!term.protein) term.protein = term.name\n\t\telse if (!term.name) term.name = term.protein\n\t}\n\n\tstatic validate(term: RawProteomeAbundanceTerm) {\n\t\tif (term.type != 'proteomeAbundance') throw 'unexpected term.type'\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (!term.name && !term.protein) throw `missing both term.name and protein`\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of term literal object\n\tconstructor(term: RawProteomeAbundanceTerm) {\n\t\tProteomeAbundanceBase.validate(term)\n\t\tthis.protein = term.protein || term.name\n\t\tthis.name = term.name || term.protein\n\t\tthis.unit = term.unit || ''\n\t\tif (term.bins) this.bins = term.bins\n\t}\n}\n", "import type { RawDateTerm } from '#types'\n\nconst termType = 'date'\n\nexport class DateBase {\n\ttype = termType\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic async fill(term: RawDateTerm) {\n\t\tthis.validate(term)\n\t}\n\n\tstatic validate(term: RawDateTerm) {\n\t\tif (term.type != 'date') throw 'unexpected term.type'\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (!term.name || typeof term.name != 'string') throw 'invalid date term.name'\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of term literal object\n\tconstructor(term: RawDateTerm) {\n\t\tDateBase.validate(term)\n\t}\n}\n", "import type { RawSsGSEATerm, PresetNumericBins } from '#types'\n\nconst termType = 'ssGSEA'\n\nexport class SsGSEABase {\n\ttype = termType\n\tid: string\n\tname: string\n\tbins?: PresetNumericBins\n\tunit?: string\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic async fill(term: RawSsGSEATerm) {\n\t\tSsGSEABase.validate(term)\n\t\tif (!term.name) term.name = term.id // only apply to native; lack way to auto retrieve\n\t}\n\n\tstatic validate(term: RawSsGSEATerm) {\n\t\tif (term.type != 'ssGSEA') throw `unexpected term.type='$term.type', should be '${termType}'`\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (!term.id) throw 'term.id missing'\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of term literal object\n\tconstructor(term: RawSsGSEATerm) {\n\t\tSsGSEABase.validate(term)\n\t\tthis.id = term.id\n\t\tthis.name = term.name || term.id\n\t\tthis.bins = term.bins\n\t\tthis.unit = term.unit\n\t}\n}\n", "import type { RawDnaMethylationTerm, VocabApi } from '#types'\nimport { type TwOpts } from './TwBase.ts'\nimport { DNA_METHYLATION } from '#shared/terms.js'\n\nconst termType = DNA_METHYLATION\n\nexport class DnaMethylationBase {\n\tid: string\n\tname: string\n\tunit: string\n\n\tstatic async fill(term: RawDnaMethylationTerm, opts: TwOpts) {\n\t\tDnaMethylationBase.validate(term)\n\t\tif (!term.id) term.id = makeDNAMethTermId(term)\n\t\tif (!term.name) {\n\t\t\tterm.unit = getDNAMethUnit(term.genomicFeatureType, opts.vocabApi)\n\t\t\tterm.name = getDNAMethTermName(term)\n\t\t}\n\t}\n\n\tstatic validate(term: RawDnaMethylationTerm) {\n\t\tif (!term || typeof term !== 'object') throw 'Term is missing or not an object'\n\t\tif (term.type != termType) throw `Incorrect term.type='${term?.type}', expecting '${termType}'`\n\t\tif (!term.chr || !Number.isInteger(term.start) || !Number.isInteger(term.stop))\n\t\t\tthrow 'Incomplete coordinate in term{}'\n\t\tif (!term.genomicFeatureType) throw 'Missing term.genomicFeatureType'\n\t\tif (term.genomicFeatureType !== 'gene' && term.featureName)\n\t\t\tthrow 'term.featureName required for DNA methylation term when genomicFeatureType = gene'\n\t}\n\n\tconstructor(term: RawDnaMethylationTerm, opts: TwOpts) {\n\t\tDnaMethylationBase.validate(term)\n\t\tthis.id = term.id || makeDNAMethTermId(term)\n\t\tthis.unit = term.unit || getDNAMethUnit(term.genomicFeatureType, opts.vocabApi)\n\t\tthis.name = term.name || getDNAMethTermName({ ...term, id: this.id }, this.unit)\n\t}\n}\n\n/** Build the query string used by the server to look up CpG sites in the HDF5\n * file. Both the genome browser and the HDF5 file use 0-based coordinates\n * (verified against UCSC hg38 via api.genome.ucsc.edu/search for 5 probes;\n * see coordinate note in client/termdb/handlers/dnaMethylation.ts). */\nfunction makeDNAMethTermId(term: RawDnaMethylationTerm) {\n\treturn `${term.chr}:${term.start}-${term.stop}`\n}\n\n/** Function standardizes DNA methylation units */\nexport function getDNAMethUnit(genomicFeatureType: string, vocabApi: VocabApi) {\n\tswitch (genomicFeatureType) {\n\t\tcase 'promoter':\n\t\t\treturn vocabApi.termdbConfig.queries.dnaMethylation?.promoter?.unit || 'Average M-value'\n\t\tcase 'gene':\n\t\t\treturn vocabApi.termdbConfig.queries.dnaMethylation?.unit || 'Average Beta Value'\n\t\tdefault:\n\t\t\treturn 'Average Beta Value'\n\t}\n}\n\n/** Function standardizes DNA methylation term name */\nexport function getDNAMethTermName(term: RawDnaMethylationTerm, termUnit?: string) {\n\tconst unit = term.unit || termUnit\n\tif (!unit) throw 'Unit is required to generate term name'\n\tconst id = term.id || makeDNAMethTermId(term)\n\tconst featureName = term.featureName || id\n\n\tswitch (term.genomicFeatureType) {\n\t\tcase 'promoter':\n\t\t\treturn `Promoter ${unit} (${id})`\n\t\tcase 'gene':\n\t\t\treturn `${featureName} - Promoter ${unit} (${id})`\n\t\tdefault:\n\t\t\treturn `${id} ${unit}`\n\t}\n}\n", "import type {\n\tNumericTerm,\n\tNumericQ,\n\tNumTW,\n\tNumTWRegularBin,\n\tNumTWCustomBin,\n\tNumTWCont,\n\tNumTWSpline,\n\tRawNumTW,\n\tRawNumTWRegularBin,\n\tRawNumTWCustomBin,\n\tRawNumTWCont,\n\tRawNumTWSpline,\n\tContinuousNumericQ,\n\tSplineNumericQ,\n\tStartUnboundedBin,\n\tStopUnboundedBin,\n\tRegularNumericBinConfig,\n\tCustomNumericBinConfig\n} from '#types'\nimport { TwBase, type TwOpts } from './TwBase.ts'\nimport { isNumeric } from '#shared/helpers.js'\nimport { roundValueAuto } from '#shared/roundValue.js'\nimport { copyMerge } from '#rx'\nimport { GeneExpBase } from './geneExpression.ts'\nimport { IsoformExpBase } from './isoformExpression.ts'\nimport { MetaboliteIntensityBase } from './metaboliteIntensity.ts'\nimport { ProteomeAbundanceBase } from './proteomeAbundance.ts'\nimport { DateBase } from './date.ts'\nimport { SsGSEABase } from './ssGSEA.ts'\nimport { DnaMethylationBase } from './dnaMethylation.ts'\nimport { SingleCellGeneExpressionBase } from './singleCellGeneExpression.ts'\nimport * as tt from '#shared/terms.js'\n\nexport class NumericBase extends TwBase {\n\t// type is set by TwBase constructor\n\tterm: NumericTerm\n\ttype: 'NumTWRegularBin' | 'NumTWCustomBin' | 'NumTWCont' | 'NumTWBinary' | 'NumTWSpline'\n\tstatic termTypes = new Set([\n\t\t'integer',\n\t\t'float',\n\t\t'date',\n\t\t'geneExpression',\n\t\t'isoformExpression',\n\t\t'metaboliteIntensity',\n\t\t'proteomeAbundance',\n\t\t'ssGSEA',\n\t\t'dnaMethylation',\n\t\ttt.SINGLECELL_GENE_EXPRESSION\n\t])\n\n\tconstructor(tw: NumTW, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.type = tw.type\n\t\tthis.term = tw.term\n\t}\n\n\tstatic async fill(tw: RawNumTW, opts: TwOpts = {}): Promise<NumTW> {\n\t\tif (!tw.term) throw `missing tw.term, must already be filled in`\n\t\tif (!NumericBase.termTypes.has(tw.term.type)) throw `non-numeric term.type='${tw.term.type}'`\n\n\t\tswitch (tw.term.type) {\n\t\t\tcase 'integer':\n\t\t\tcase 'float':\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'discrete'\n\t\t\t\tbreak\n\n\t\t\tcase 'geneExpression':\n\t\t\t\tGeneExpBase.fill(tw.term, opts)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'isoformExpression':\n\t\t\t\tIsoformExpBase.fill(tw.term, opts)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'metaboliteIntensity':\n\t\t\t\tMetaboliteIntensityBase.fill(tw.term)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'proteomeAbundance':\n\t\t\t\tProteomeAbundanceBase.fill(tw.term)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'date':\n\t\t\t\tDateBase.fill(tw.term)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'ssGSEA':\n\t\t\t\tSsGSEABase.fill(tw.term)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase 'dnaMethylation':\n\t\t\t\tDnaMethylationBase.fill(tw.term, opts)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\tcase tt.SINGLECELL_GENE_EXPRESSION:\n\t\t\t\tSingleCellGeneExpressionBase.fill(tw.term, opts)\n\t\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\t\tbreak\n\n\t\t\t// default:\n\t\t\t// \t// should never be reached if TwRouter.fill() routes correctly\n\t\t\t// \tthrow `unexpected numeric term.type='${tw.term.type}'`\n\t\t}\n\n\t\tif (opts.defaultQ) {\n\t\t\topts.defaultQ.isAtomic = true\n\t\t\ttw.q.isAtomic = true\n\t\t\tif (opts.defaultQ.preferredBins == 'median') {\n\t\t\t\tif (!opts.defaultQ.type) opts.defaultQ.type = 'custom-bin'\n\t\t\t\telse if (opts.defaultQ.type != 'custom-bin') throw '.type must be custom-bin when .preferredBins=median'\n\t\t\t}\n\t\t\t// merge defaultQ into tw.q\n\t\t\tcopyMerge(tw.q, opts.defaultQ)\n\t\t}\n\n\t\t// set q.type based on q.mode\n\t\tswitch (tw.q.mode) {\n\t\t\tcase 'discrete':\n\t\t\t\tif (tw.q.type != 'regular-bin') {\n\t\t\t\t\t// support malformed tw.q that combines properties from different modes, such as continuous and discrete\n\t\t\t\t\tif (Array.isArray((tw as RawNumTWCustomBin).q.lst)) tw.q.type = 'custom-bin'\n\t\t\t\t}\n\t\t\t\tif (!tw.q.type) {\n\t\t\t\t\tif (tw.term.bins) mayFillQWithPresetBins(tw)\n\t\t\t\t\telse tw.q.type = 'regular-bin'\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'binary':\n\t\t\t\ttw.q.type = 'custom-bin'\n\t\t\t\tbreak\n\n\t\t\tcase 'continuous':\n\t\t\tcase 'spline':\n\t\t\t\tdelete tw.q.type\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tthrow 'numeric tw.q.mode not supported'\n\t\t}\n\n\t\t/* \n\t\t\tPre-fill the tw.type, since it's required for ROUTING to the\n\t\t\tcorrect fill() function. Tsc will be able to use tw.type as a \n\t\t\tdiscriminant property for the RawNumTW union type, enabling \n\t\t\tstatic type checks on the input raw tw.\n\n\t\t\tNOTE: tw.type is NOT required when calling a specialized fill() \n\t\t\tfunction directly, outside of TwRouter.fill(). The input tw.type\n\t\t\tdoes not have to be discriminated in that case.\n\t\t*/\n\t\ttw.type =\n\t\t\ttw.q.type == 'regular-bin'\n\t\t\t\t? 'NumTWRegularBin'\n\t\t\t\t: tw.q.type == 'custom-bin' || tw.q.mode == 'binary'\n\t\t\t\t? 'NumTWCustomBin'\n\t\t\t\t: tw.q.mode == 'continuous'\n\t\t\t\t? 'NumTWCont'\n\t\t\t\t: tw.q.mode == 'spline'\n\t\t\t\t? 'NumTWSpline'\n\t\t\t\t: tw.type\n\t\t/*\n\t\t\tFor each of fill() functions below:\n\t\t\t1. The `tw` argument must already have a tw.type string value, \n\t\t\t which corresponds to the RawNumTW* equivalent of the full NumTW* type \n\n\t\t\t2. The fill() function must fill-in any expected missing values,\n\t\t\t validate the tw.q shape at runtime, and throw on any error or mismatched expectation.\n\t\t\t Runtime validation is required because the input raw tw can come from anywhere,\n\t\t\t like term.bins.default, which is a runtime variable that is not possible to statically check.\n\n\t\t\t3. The filled-in tw, when returned, must be **coerced** to the full NumTW* type, \n\t\t\t in order to match the function signature's return type.\n\t\t*/\n\t\tswitch (tw.type) {\n\t\t\tcase 'NumTWRegularBin':\n\t\t\t\treturn await NumRegularBin.fill(tw, opts)\n\n\t\t\tcase 'NumTWCustomBin':\n\t\t\t\treturn await NumCustomBins.fill(tw, opts)\n\n\t\t\tcase 'NumTWCont':\n\t\t\t\treturn await NumCont.fill(tw)\n\n\t\t\tcase 'NumTWSpline':\n\t\t\t\treturn await NumSpline.fill(tw)\n\n\t\t\tdefault:\n\t\t\t\tthrow `tw.type='${tw.type} (q.mode:q.type=${tw.q.mode}:${tw.q.type}' is not supported by NumericBase.fill()`\n\t\t}\n\t}\n\n\tgetTitleText() {\n\t\treturn this.term.name\n\t}\n}\n\nexport class NumRegularBin extends NumericBase {\n\t// type, isAtomic, $id are set in ancestor base classes\n\tq: RegularNumericBinConfig\n\t#tw: NumTWRegularBin\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: NumTWRegularBin, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set by base constructor\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\tgetStatus() {\n\t\treturn { text: 'bin size=' + this.q.bin_size }\n\t}\n\n\t// See the relevant comments in the NumericBase.fill() function above\n\tstatic async fill(tw: RawNumTWRegularBin, opts: TwOpts = {}): Promise<NumTWRegularBin> {\n\t\tif (!tw.type) tw.type = 'NumTWRegularBin'\n\t\telse if (tw.type != 'NumTWRegularBin') throw `expecting tw.type='NumTWRegularBin', got '${tw.type}'`\n\n\t\tif (!tw.q.mode) tw.q.mode = 'discrete'\n\t\telse if (tw.q.mode != 'discrete' && tw.q.mode != 'binary' && tw.q.mode != 'continuous')\n\t\t\tthrow `expecting tw.q.mode='discrete'|'binary'|'continous', got '${tw.q.mode}'`\n\n\t\tif (tw.q.type && tw.q.type != 'regular-bin') throw `expecting tw.q.type='regular-bin', got '${tw.q.type}'`\n\n\t\tif (!tw.term.bins || tw.term.bins.default?.isDummyPreset) {\n\t\t\t/* non-dictionary term (e.g. gene term) may be missing bin definition, this is expected as it's not valid to apply same bin to genes with vastly different exp range,\n\t\t\tand not worth it to precompute each gene's default bin with its actual exp data as cohort filter can not be predicted\n\t\t\there make a request to determine default bin for this term based on its data\n\n\t\t\tdo not do this when tw.q.mode is continuous:\n\t\t\t1. it will add significant delay to gene exp clustering, esp for gdc. bins are useless for hiercluster and the request will lock up server\n\t\t\t2. the way setTermBins works, tw.q.type won't be filled and errors out\n\t\t\t*/\n\t\t\tawait opts.vocabApi.setTermBins(tw)\n\t\t}\n\n\t\tif (tw.q.isDummyPreset || !tw.q.first_bin || !isNumeric(tw.q.bin_size)) mayFillQWithPresetBins(tw)\n\n\t\tif (tw.q.bin_size === null) throw new Error(`No ${tw.term.name} numeric data to create bins`)\n\t\tif (!isNumeric(tw.q.bin_size)) throw `tw.q.bin_size=${tw.q.bin_size} is not numeric`\n\t\tif (!tw.q.first_bin) throw `missing tw.q.first_bin`\n\t\tif (!isNumeric(tw.q.first_bin?.stop)) throw `tw.q.first_bin.stop is not numeric`\n\n\t\tTwBase.setHiddenValues(tw.q as NumericQ, tw.term)\n\t\treturn tw as NumTWRegularBin\n\t}\n}\n\nexport class NumCustomBins extends NumericBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: CustomNumericBinConfig\n\t#tw: NumTWCustomBin\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: NumTWCustomBin, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set by base constructor\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\tgetStatus(opts?: any, data?: any) {\n\t\tif (this.q.mode == 'binary') {\n\t\t\tconst regressionStatus =\n\t\t\t\topts.usecase?.target == 'regression' && this.q.lst.find(x => x.label != data.refGrp)?.label\n\t\t\treturn { text: regressionStatus || 'binary' }\n\t\t}\n\t\treturn { text: this.q.lst.length + ' bins' }\n\t}\n\n\t// See the relevant comments in the NumericBase.fill() function above\n\tstatic async fill(tw: RawNumTWCustomBin, opts: TwOpts = {}): Promise<NumTWCustomBin> {\n\t\tif (!tw.type) tw.type = 'NumTWCustomBin'\n\t\telse if (tw.type != 'NumTWCustomBin') throw `expecting tw.type='NumTWCustomBin', got '${tw.type}'`\n\n\t\tif (!tw.q.mode) tw.q.mode = 'discrete'\n\t\telse if (tw.q.mode != 'discrete' && tw.q.mode != 'binary' && tw.q.mode != 'continuous')\n\t\t\tthrow `expecting tw.q.mode='discrete'|binary|continuous', got '${tw.q.mode}'`\n\n\t\tif (tw.q.mode == 'binary' && !tw.q.preferredBins) tw.q.preferredBins = 'median'\n\n\t\tif (!tw.term.bins) {\n\t\t\t/* non-dictionary term (e.g. gene term) may be missing bin definition, this is expected as it's not valid to apply same bin to genes with vastly different exp range,\n\t\t\tand not worth it to precompute each gene's default bin with its actual exp data as cohort filter can not be predicted\n\t\t\there make a request to determine default bin for this term based on its data\n\n\t\t\tdo not do this when tw.q.mode is continuous:\n\t\t\t1. it will add significant delay to gene exp clustering, esp for gdc. bins are useless for hiercluster and the request will lock up server\n\t\t\t2. the way setTermBins works, tw.q.type won't be filled and errors out\n\t\t\t*/\n\t\t\tawait opts.vocabApi.setTermBins(tw)\n\t\t}\n\n\t\tif (tw.q.preferredBins == 'median' && !tw.q.lst?.length) await fillQWithMedianBin(tw, opts.vocabApi)\n\t\telse if (tw.q.type != 'custom-bin') throw `expecting tw.q.type='custom-bin', got '${tw.q.type}'`\n\n\t\tif (!Array.isArray(tw.q.lst)) mayFillQWithPresetBins(tw)\n\n\t\tif (!tw.q.lst || !tw.q.lst.length) throw `missing or empty q.lst[] for custom-bin`\n\t\tif (tw.q.mode == 'binary' && tw.q.lst.length != 2) throw `numeric q.mode='binary' requires exactly 2 bins`\n\n\t\tTwBase.setHiddenValues(tw.q as NumericQ, tw.term)\n\t\ttw.type = 'NumTWCustomBin'\n\t\treturn tw as NumTWCustomBin\n\t}\n}\n\nexport class NumCont extends NumericBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: ContinuousNumericQ\n\t#tw: NumTWCont\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: NumTWCont, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set by base constructor\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\tgetStatus() {\n\t\treturn { text: this.q.scale ? `scale=${this.q.scale}` : 'continuous' } // FIXME not effective\n\t}\n\n\t// See the relevant comments in the NumericBase.fill() function above\n\tstatic async fill(tw: RawNumTWCont): Promise<NumTWCont> {\n\t\tif (!tw.type) tw.type = 'NumTWCont'\n\t\telse if (tw.type != 'NumTWCont') throw `expecting tw.type='NumTWCont', got '${tw.type}'`\n\n\t\tif (tw.q.mode != 'continuous') throw `tw.q.mode='${tw.q.mode}', expecting 'continuous'`\n\n\t\tTwBase.setHiddenValues(tw.q as NumericQ, tw.term)\n\t\ttw.type = 'NumTWCont'\n\t\treturn tw as NumTWCont\n\t}\n}\n\nexport class NumSpline extends NumericBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: SplineNumericQ\n\t#tw: NumTWSpline\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: NumTWSpline, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set by base constructor\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetStatus() {\n\t\treturn { text: 'cubic spline' }\n\t}\n\n\tstatic async fill(tw: RawNumTWSpline): Promise<NumTWSpline> {\n\t\tif (!tw.type) tw.type = 'NumTWSpline'\n\t\telse if (tw.type != 'NumTWSpline') throw `expecting tw.type='NumTWSpline', got '${tw.type}'`\n\n\t\tif (tw.q.mode != 'spline') throw `tw.q.mode='${tw.q.mode}', expecting 'spline'`\n\t\tif (!tw.q.knots) throw `missing tw.q.knots`\n\t\tif (!tw.q.knots.length) throw `empty tw.q.knots[]`\n\n\t\tTwBase.setHiddenValues(tw.q as NumericQ, tw.term)\n\t\ttw.type = 'NumTWSpline'\n\t\treturn tw as NumTWSpline\n\t}\n}\n\nexport async function fillQWithMedianBin(tw, vocabApi) {\n\tconst result = await vocabApi.getPercentile(tw.term, [50], vocabApi.state.termfilter)\n\tif (!result.values) throw '.values[] missing from vocab.getPercentile()'\n\tconst median = roundValueAuto(result.values[0])\n\n\t/* do not check if median is numeric here because median will be null\n\tif term has no data in dataset, so instead of throwing error, should\n\tproceed to plot code, which will report to user that no data is available */\n\t//if (!isNumeric(median)) throw 'median value not a number'\n\n\ttw.q.type = 'custom-bin'\n\ttw.q.lst = [\n\t\t{\n\t\t\tstartunbounded: true,\n\t\t\tstop: median,\n\t\t\tstopinclusive: false,\n\t\t\tlabel: '<' + median // if label is missing, cuminc will break with \"unexpected seriesId\", cuminc.js:367\n\t\t} as StartUnboundedBin,\n\t\t{\n\t\t\tstart: median,\n\t\t\tstartinclusive: true,\n\t\t\tstopunbounded: true,\n\t\t\tlabel: '\u2265' + median\n\t\t} as StopUnboundedBin\n\t]\n\tdelete tw.q.preferredBins\n}\n\nconst validPreferredBins = new Set(['default', 'less', 'median'])\n\nfunction mayFillQWithPresetBins(tw) {\n\tif (!tw.term.bins) throw `missing tw.term.bins`\n\t// preprocessing the preferredBins to make sure that q.type is set\n\t// and can be used to route the raw tw to the correct subclass fill() function\n\tconst preferredBins = tw.q.preferredBins || 'default'\n\tif (!validPreferredBins.has(preferredBins)) throw `invalid preferredBins='${preferredBins}'`\n\tif (preferredBins != 'median') {\n\t\tif (!Object.keys(tw.term.bins).includes(preferredBins))\n\t\t\tthrow `term.bins does not have a preset '${preferredBins}' key`\n\t\tconst bins = structuredClone(tw.term.bins[preferredBins])\n\t\tif (!bins.mode) bins.mode = 'discrete'\n\t\tif (tw.q.type && tw.q.type != bins.type) throw `mismatched tw.q.type and term.bins[preferredBins].type`\n\t\tif (tw.q.isDummyPreset) {\n\t\t\ttw.q = bins // replace atomically\n\t\t\tdelete tw.q.descrStats\n\t\t} else {\n\t\t\tconst qkeys = Object.keys(tw.q)\n\t\t\tfor (const [k, v] of Object.entries(bins)) {\n\t\t\t\t// only override tw.q values that don't already exist in tw.q;\n\t\t\t\t// NOTES:\n\t\t\t\t// - Object.hasOwn(tw.q, k) will work with lib: [\"es2022\"], but that causes other tsc errors\n\t\t\t\t// - using tw.q.hasOwnProperty(k) causes an eslint error, no-prototype-builtins\n\t\t\t\tif (!qkeys.includes(k)) tw.q[k] = v\n\t\t\t}\n\t\t\tdelete tw.q.preferredBins\n\t\t}\n\t}\n}\n", "import type { RawSnpTerm, SnpTerm, TermGroupSetting, TermValues } from '#types'\n\nconst termType = 'snp'\n\nexport class SnpBase {\n\ttype = termType\n\tid: string\n\tname: string\n\tchr: string\n\tstart: number\n\tstop: number\n\tref: string\n\talt: string[]\n\tgroupsetting: TermGroupSetting\n\tvalues: TermValues\n\n\t// option to fill-in/mutate the input raw term object in-place\n\t// - does not have to construct, but may require forced type casting in consumer code\n\tstatic fill(term: RawSnpTerm) {\n\t\tif (term instanceof SnpBase) return\n\t\tSnpBase.validate(term)\n\t\tif (!term.groupsetting) term.groupsetting = { disabled: false }\n\t\tif (!term.values) term.values = {}\n\t}\n\n\tstatic validate(term: RawSnpTerm) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != termType) throw `incorrect term.type='${term?.type}', expecting '${termType}'`\n\t\tif (!term.id || !term.name) throw 'missing snp id/name'\n\t\tif (!term.chr || !Number.isInteger(term.start) || !Number.isInteger(term.stop))\n\t\t\tthrow 'incomplete position information'\n\t\tif (!term.ref || !term.alt) throw 'missing allele information'\n\t}\n\n\t// option to construct an object instance and not mutate the input raw term\n\t// - will be used instead of tw.term literal object\n\tconstructor(term: RawSnpTerm | SnpTerm) {\n\t\tSnpBase.validate(term)\n\t\tthis.id = term.id\n\t\tthis.name = term.name\n\t\tthis.chr = term.chr\n\t\tthis.start = term.start\n\t\tthis.stop = term.stop\n\t\tthis.ref = term.ref\n\t\tthis.alt = term.alt\n\t\tthis.groupsetting = term.groupsetting || { disabled: false }\n\t\tthis.values = term.values || {}\n\t}\n}\n", "import type { RawSingleCellCellTypeTerm, SingleCellCellTypeTerm, TermGroupSetting, TermValues } from '#types'\nimport { SINGLECELL_CELLTYPE } from '#shared/terms.js'\n\nconst termType = SINGLECELL_CELLTYPE\n\nexport class SingleCellCellTypeBase {\n\ttype = termType\n\tsample: object\n\tplot?: string\n\tgroupsetting: TermGroupSetting\n\tvalues: TermValues\n\n\tstatic fill(term: RawSingleCellCellTypeTerm) {\n\t\tif (term instanceof SingleCellCellTypeBase) return\n\t\tSingleCellCellTypeBase.validate(term)\n\t\tif (!term.groupsetting) term.groupsetting = { disabled: false }\n\t\tif (!term.values) term.values = {}\n\t\t/** Normalize native and gdc sample objects. Use sID as sample key */\n\t\tif (typeof term.sample == 'string') term.sample = { sID: term.sample }\n\t}\n\n\tstatic validate(term: RawSingleCellCellTypeTerm) {\n\t\tif (!term || typeof term !== 'object') throw new Error('term is not an object')\n\t\tif (term.type != termType) throw new Error(`incorrect term.type='${term?.type}', expecting '${termType}'`)\n\t\tif (!term?.sample) throw new Error('missing term.sample')\n\t\t// if (!term?.plot) throw new Error('missing term.plot')\n\t}\n\n\tconstructor(term: RawSingleCellCellTypeTerm | SingleCellCellTypeTerm) {\n\t\tSingleCellCellTypeBase.validate(term)\n\t\tthis.sample = term.sample\n\t\tthis.plot = term.plot || ''\n\t\tthis.groupsetting = term.groupsetting || { disabled: false }\n\t\tthis.values = term.values || {}\n\t}\n}\n", "import type {\n\tTerm,\n\tQualTerm,\n\tQualQ,\n\tGroupEntry,\n\tValuesQ,\n\tPredefinedGroupSettingQ,\n\tCustomGroupSettingQ,\n\tBaseGroupSet,\n\tQualTW,\n\tQualTWValues,\n\tQualTWPredefinedGS,\n\tQualTWCustomGS,\n\tRawQualTW,\n\tRawQualTWValues,\n\tRawQualTWPredefinedGS,\n\tRawQualTWCustomGS\n} from '#types'\nimport { CategoricalBase } from './categorical.ts'\nimport { SnpBase } from './snp.ts'\nimport { SingleCellCellTypeBase } from './singleCellCellType.ts'\nimport type { TwOpts } from './TwBase.ts'\nimport { TwBase } from './TwBase.ts'\nimport { copyMerge } from '#rx'\nimport { set_hiddenvalues, type UseCase } from '#termsetting'\nimport { throwMsgWithFilePathAndFnName } from '#dom/sayerror'\nimport * as tt from '#shared/terms.js'\n\nexport type QualInstance = QualValues | QualPredefinedGS | QualCustomGS\nexport type QualTypes = typeof QualValues | typeof QualPredefinedGS | typeof QualCustomGS\n\nexport class QualitativeBase extends TwBase {\n\t// type, isAtomic, $id are set in ancestor base classes\n\tterm: QualTerm\n\tq: QualQ\n\tstatic termTypes = new Set([tt.CATEGORICAL, tt.SNP, tt.SINGLECELL_CELLTYPE])\n\n\tconstructor(tw: QualTW, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.term = tw.term\n\t\tthis.q = tw.q\n\t}\n\n\t/** tw.term must already be filled-in at this point */\n\tstatic async fill(tw: RawQualTW, opts: TwOpts = {}): Promise<QualTW> {\n\t\tif (!tw.term) throw `missing tw.term`\n\t\tif (typeof tw.term != 'object') throw `tw.term is not an object`\n\t\tif (!QualitativeBase.termTypes.has(tw.term.type)) throw `non-qualitative term.type='${tw.term.type}'`\n\n\t\tswitch (tw.term.type) {\n\t\t\tcase 'categorical':\n\t\t\t\tCategoricalBase.fill(tw.term)\n\t\t\t\tbreak\n\n\t\t\tcase 'snp':\n\t\t\t\tSnpBase.fill(tw.term)\n\t\t\t\tbreak\n\n\t\t\tcase tt.SINGLECELL_CELLTYPE:\n\t\t\t\tSingleCellCellTypeBase.fill(tw.term)\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\t// should never be reached if TwRouter.fill() routes correctly\n\t\t\t\tthrow `unexpected qualitative term.type'` //='${tw.term.type}'`\n\t\t}\n\n\t\t// GDC or other dataset may allow missing or empty term.values\n\t\t//if (!tw.term.values || !Object.keys(tw.term.values).length) throw `missing or empty tw.term.values`\n\n\t\tif (opts.defaultQ != null) {\n\t\t\topts.defaultQ.isAtomic = true\n\t\t\t// merge defaultQ into tw.q\n\t\t\tcopyMerge(tw.q, opts.defaultQ)\n\t\t}\n\t\t// set a default q.mode for clarity, otherwise `mode?: 'binary'` may seem like the only option\n\t\t// NOTES:\n\t\t// - many code that process categorical tw already assume discrete mode, without checking q.mode,\n\t\t// except for applications that allow or require q.mode='binary'\n\t\t// - may convert legacy q.mode\n\t\tif (!tw.q.mode || tw.q.mode == 'values') tw.q.mode = 'discrete'\n\n\t\t// set q.type based on q.mode\n\t\tswitch (tw.q.mode) {\n\t\t\tcase 'discrete':\n\t\t\t\tif (!tw.q.type) tw.q.type = 'values'\n\t\t\t\tbreak\n\n\t\t\tcase 'binary':\n\t\t\t\tif (tw.term.values && Object.keys(tw.term.values).length == 2) {\n\t\t\t\t\t// term only has 2 values, should not allow groupset\n\t\t\t\t\ttw.q.type = 'values'\n\t\t\t\t} else {\n\t\t\t\t\ttw.q.type = 'custom-groupset'\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tthrow 'qualitative tw.q.mode not supported'\n\t\t}\n\n\t\t/* \n\t\t\tPre-fill the tw.type, since it's required for ROUTING to the\n\t\t\tcorrect fill() function. Tsc will be able to use tw.type as a \n\t\t\tdiscriminant property for the RawQualTW union type, enabling \n\t\t\tstatic type checks on the input raw tw.\n\n\t\t\tNOTE: tw.type is NOT required when calling a specialized fill() \n\t\t\tfunction directly, outside of TwRouter.fill(). The input tw.type\n\t\t\tdoes not have to be discriminated in that case.\n\t\t*/\n\t\ttw.type =\n\t\t\t!tw.q.type || tw.q.type == 'values'\n\t\t\t\t? 'QualTWValues'\n\t\t\t\t: tw.q.type == 'predefined-groupset'\n\t\t\t\t? 'QualTWPredefinedGS'\n\t\t\t\t: tw.q.type == 'custom-groupset'\n\t\t\t\t? 'QualTWCustomGS'\n\t\t\t\t: tw.type\n\n\t\t/*\n\t\t\tFor each of fill() functions below:\n\t\t\t1. The `tw` argument must already have a tw.type string value, \n\t\t\t which corresponds to the RawQualTW* equivalent of the full QualTW* type \n\n\t\t\t2. The fill() function must fill-in any expected missing values,\n\t\t\t validate the tw.q shape at runtime, and throw on any error or mismatched expectation.\n\t\t\t Runtime validation is required because the input raw tw can come from anywhere,\n\t\t\t like term.bins.default, which is a runtime variable that is not possible to statically check.\n\n\t\t\t3. The filled-in tw, when returned, must be **coerced** to the full QualTW* type, \n\t\t\t in order to match the function signature's return type.\n\t\t*/\n\t\tswitch (tw.type) {\n\t\t\tcase 'QualTWValues':\n\t\t\t\treturn await QualValues.fill(tw)\n\n\t\t\tcase 'QualTWPredefinedGS':\n\t\t\t\treturn await QualPredefinedGS.fill(tw)\n\n\t\t\tcase 'QualTWCustomGS':\n\t\t\t\treturn await QualCustomGS.fill(tw, opts)\n\n\t\t\tdefault:\n\t\t\t\tthrow `tw.type='${tw.type} (q.mode:q.type=${tw.q.mode}:${tw.q.type}' is not supported by QualitativeBase.fill()`\n\t\t}\n\t}\n\n\tgetTitleText() {\n\t\treturn this.term.name\n\t}\n\n\tgetStatus(_?: UseCase) {\n\t\treturn { text: '' }\n\t}\n}\n\nexport class QualValues extends QualitativeBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: ValuesQ\n\t#tw: QualTWValues\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: QualTWValues, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\t// See the relevant comments in the QualitativeBase.fill() function above\n\tstatic async fill(tw: RawQualTWValues): Promise<QualTWValues> {\n\t\tif (!tw.type) tw.type = 'QualTWValues'\n\t\telse if (tw.type != 'QualTWValues') throw `expecting tw.type='QualTWValues', got '${tw.type}'`\n\n\t\tconst { term, q } = tw\n\t\tif (!q.type) q.type = 'values'\n\t\telse if (q.type != 'values') throw `expecting tw.q.type='values', got ${tw.q.type}`\n\n\t\t// GDC or other dataset may allow missing term.values\n\t\tif (!term.values) term.values = {}\n\n\t\tif (q.mode == 'binary') {\n\t\t\t// a tw with q.type = 'values' can only have mode='binary' if it has exactly 2 values\n\t\t\tif (Object.keys(term.values).length != 2) throw 'term.values must have two keys'\n\t\t}\n\n\t\tset_hiddenvalues(q, term as Term) // TODO: do not force type\n\t\t// TODO: figure out not having to force the returned type\n\t\treturn tw as QualTWValues\n\t}\n\n\tgetStatus(usecase?: UseCase) {\n\t\tif (usecase?.target == 'regression') {\n\t\t\treturn this.q.mode == 'binary' ? { text: 'binary' } : { text: 'categorical' }\n\t\t}\n\t\treturn { text: '' }\n\t}\n\n\tgetGroups(category2samplecount: any[], maxGrpNum: number = 3) {\n\t\tconst values: any[] = []\n\t\tconst groups: any[] = []\n\t\tconst grpIdxes: Set<number> = new Set([0, 1, 2])\n\t\tfor (const v of category2samplecount) {\n\t\t\tif (v.uncomputable) return //Still necessary? Possibly taken care of termdb route... somewhere\n\t\t\tif (v?.group > maxGrpNum)\n\t\t\t\tthrowMsgWithFilePathAndFnName(\n\t\t\t\t\t`The maximum number of groups is ${maxGrpNum}. The group index for value = ${v.label} is ${v.group}`\n\t\t\t\t)\n\t\t\tconst value = {\n\t\t\t\tkey: v.key,\n\t\t\t\tlabel: v.label,\n\t\t\t\tgroup: v.group || 1,\n\t\t\t\tsamplecount: v.samplecount\n\t\t\t}\n\t\t\tvalues.push(value)\n\t\t}\n\n\t\tfor (const g of Array.from(grpIdxes)) {\n\t\t\t//add any required groups, specifically Excluded Categories and Group 2\n\t\t\tgroups.push({\n\t\t\t\tcurrentIdx: g,\n\t\t\t\ttype: this.type,\n\t\t\t\tname: g === 0 ? `Excluded categories` : `Group ${g.toString()}`,\n\t\t\t\tuncomputable: g === 0\n\t\t\t})\n\t\t}\n\n\t\treturn { groups, values }\n\t}\n}\n\nexport class QualPredefinedGS extends QualitativeBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: PredefinedGroupSettingQ\n\t// set by Object.defineProperty() so that the property is not\n\t// enumerable, will not show up in JSON.stringify() and structuredClone(),\n\t// but can still be accessed by addon methods, unlike #private props\n\tgroupset!: BaseGroupSet\n\t#tw: QualTWPredefinedGS\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: QualTWPredefinedGS, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t// this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tObject.defineProperty(this, 'groupset', {\n\t\t\tvalue: this.#tw.term.groupsetting[this.#tw.q.predefined_groupset_idx]\n\t\t})\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\tstatic async fill(tw: RawQualTWPredefinedGS): Promise<QualTWPredefinedGS> {\n\t\tif (!tw.type) tw.type = 'QualTWPredefinedGS'\n\t\telse if (tw.type != 'QualTWPredefinedGS') throw `expecting tw.type='QualTWPredefinedGS', got '${tw.type}'`\n\n\t\tif (tw.q.type != 'predefined-groupset') throw `expecting tw.q.type='predefined-groupset', got '${tw.q.type}'`\n\n\t\tconst { term, q } = tw\n\t\tconst i = q.predefined_groupset_idx\n\t\tif (i !== undefined && !Number.isInteger(i)) throw `missing or invalid tw.q.predefined_groupset_idx='${i}'`\n\t\tq.predefined_groupset_idx = i || 0\n\t\tconst gs = tw.term.groupsetting\n\t\tif (!gs) throw 'no term.groupsetting'\n\t\tif (!gs.lst?.length) throw 'term.groupsetting.lst is empty'\n\t\tconst groupset = gs.lst?.[q.predefined_groupset_idx]\n\t\tif (!groupset) throw `no groupset entry for groupsetting.lst?.[predefined_groupset_idx=${i}]`\n\n\t\tif (q.mode == 'binary') {\n\t\t\t//\n\t\t\tif (groupset.groups.length != 2) throw 'there must be exactly two groups'\n\t\t}\n\t\tset_hiddenvalues(q, term as Term) // TODO: do not force type\n\t\t// TODO: figure out not having to force the returned type\n\t\treturn tw as QualTWPredefinedGS\n\t}\n\n\tgetStatus(usecase?: UseCase) {\n\t\tif (usecase?.target == 'regression') {\n\t\t\treturn this.q.mode == 'binary' ? { text: 'binary' } : { text: 'categorical' }\n\t\t}\n\t\t// fill() should have already validated q\n\t\treturn { text: this.term.groupsetting.lst?.[this.q.predefined_groupset_idx].name || 'predefined groups' }\n\t}\n\n\tgetGroups() {\n\t\tthrow `q.type='predefined-groupset' not supported in groupsetting menu`\n\t}\n}\n\nexport class QualCustomGS extends QualitativeBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: CustomGroupSettingQ\n\tgroupset!: BaseGroupSet\n\t#tw: QualTWCustomGS\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: QualTWCustomGS, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t// this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tObject.defineProperty(this, 'groupset', { value: this.q.customset })\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\t// See the relevant comments in the QualitativeBase.fill() function above\n\tstatic async fill(tw: RawQualTWCustomGS, opts: TwOpts): Promise<QualTWCustomGS> {\n\t\tif (!tw.type) tw.type = 'QualTWCustomGS'\n\t\telse if (tw.type != 'QualTWCustomGS') throw `expecting tw.type='QualTWCustomGS', got '${tw.type}'`\n\n\t\tif (tw.q.type != 'custom-groupset') throw `expecting tw.q.type='custom-groupset', got '${tw.q.type}'`\n\n\t\tconst { term, q } = tw\n\t\tif (!q.customset) await mayFillCustomSet(q, term, opts.vocabApi)\n\t\tif (q.mode == 'binary') {\n\t\t\tif (q.customset.groups.filter((g: any) => !g.uncomputable).length != 2) throw 'there must be exactly two groups'\n\t\t}\n\t\tset_hiddenvalues(q, term as Term) // TODO: do not force type\n\t\t// TODO: figure out not having to force the returned type\n\t\treturn tw as QualTWCustomGS\n\t}\n\n\tgetStatus(usecase?: UseCase) {\n\t\tif (usecase?.target == 'regression') {\n\t\t\treturn this.q.mode == 'binary' ? { text: 'binary' } : { text: 'categorical' }\n\t\t}\n\t\t// TODO: move this validation to the fill() function above?\n\t\tconst n = this.q.customset.groups.filter(group => {\n\t\t\tif (group.type != 'values') throw `group.type must be 'values'`\n\t\t\tif (!group.uncomputable) return true\n\t\t}).length\n\t\treturn { text: 'Divided into ' + n + ' groups' }\n\t}\n\n\tgetGroups(category2samplecount) {\n\t\tconst values: any = []\n\t\tconst groups: any[] = []\n\t\tconst grpIdxes = new Set([0, 1, 2])\n\t\tconst q = this.q\n\t\tfor (const [i, g] of q.customset.groups.entries()) {\n\t\t\tconst group = g as any // TODO: improve typing\n\t\t\tconst uncomputable = Object.keys(group).includes('uncomputable') ? group.uncomputable : i === 0\n\t\t\tgroups.push({\n\t\t\t\tcurrentIdx: i,\n\t\t\t\ttype: group.type,\n\t\t\t\tname: group.name,\n\t\t\t\tuncomputable\n\t\t\t})\n\t\t\tgrpIdxes.delete(i)\n\t\t\tif (group.type != 'values') throw `group.type should equal 'values'`\n\t\t\tfor (const value of group.values) {\n\t\t\t\t/** label may not be provided in groupsetting.customset.\n\t\t\t\t * If missing, find the label from category2samplecout or\n\t\t\t\t * use the last ditch effort to use the key.\n\t\t\t\t */\n\t\t\t\tconst c2s = category2samplecount?.find(\n\t\t\t\t\t(d: { key: string; label?: string; samplecount: number }) => d.key == value.key\n\t\t\t\t)\n\t\t\t\tconst label = value.label || c2s?.label || value.key\n\t\t\t\tvalues.push({\n\t\t\t\t\tkey: value.key,\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tgroup: i,\n\t\t\t\t\tsamplecount: value.samplecount || c2s.samplecount\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn { groups, values }\n\t}\n}\n\nasync function mayFillCustomSet(q, term, vocabApi) {\n\tif (q.mode == 'binary') {\n\t\t// binary mode, divide categories evenly into two groups\n\t\tconst data = await vocabApi.getCategories(term, vocabApi.state.termfilter.filter)\n\t\tconst sorted = [...data.lst].sort((a, b) => b.samplecount - a.samplecount)\n\t\tconst group1: GroupEntry = { name: 'Group 1', type: 'values', values: [] }\n\t\tconst group2: GroupEntry = { name: 'Group 2', type: 'values', values: [] }\n\t\tlet sum1 = 0\n\t\tlet sum2 = 0\n\t\tfor (const item of sorted) {\n\t\t\tif (sum1 <= sum2) {\n\t\t\t\tgroup1.values.push({ key: item.key, label: item.label })\n\t\t\t\tsum1 += item.samplecount\n\t\t\t} else {\n\t\t\t\tgroup2.values.push({ key: item.key, label: item.label })\n\t\t\t\tsum2 += item.samplecount\n\t\t\t}\n\t\t}\n\n\t\tif (sum1 == 0 || sum2 == 0) throw 'both groups must have non-zero sample counts'\n\n\t\tconst customset: BaseGroupSet = {\n\t\t\t// creating 3 groups instead of 2 groups since current groupset UI expects first group to be excluded group\n\t\t\t// TODO: refactor client/termsetting/handlers/qualitative.ts to not consider the first group (i.e. group.currentIdx === 0) as the excluded group, but rather to consider group.excluded=true as the excluded group\n\t\t\tgroups: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Excluded categories',\n\t\t\t\t\ttype: 'values',\n\t\t\t\t\tvalues: [],\n\t\t\t\t\tuncomputable: true\n\t\t\t\t},\n\t\t\t\tgroup1,\n\t\t\t\tgroup2\n\t\t\t]\n\t\t}\n\t\tq.customset = customset\n\t} else {\n\t\t// discrete mode, should already have custom set\n\t\tthrow 'tw.q.customset is required for q.mode=discrete'\n\t}\n}\n", "import type { RawNumericTermCollection, NumericTermCollection as NumericTermCollectionType } from '#types'\nimport { type TwOpts } from '../TwBase'\n\nconst termType = 'termCollection'\n\n/** Term class for numeric termCollections (memberType: 'numeric') */\nexport class NumericTermCollection {\n\treadonly type = termType\n\treadonly memberType = 'numeric' as const\n\tid: string\n\tname: string\n\ttermIds?: string[]\n\tvalueTransform?: { offset?: number }\n\ttermlst: object[]\n\tpropsByTermId: {\n\t\t[termId: string]: {\n\t\t\t[prop: string]: any\n\t\t}\n\t}\n\tnumerators?: string[]\n\n\t// Mutates the raw term object in-place; routes from CollectionCont.fill()\n\tstatic fill(term: RawNumericTermCollection, opts: TwOpts = {}) {\n\t\tif (term instanceof NumericTermCollection) return\n\t\tif (term.isCustom && term.termlst?.length) {\n\t\t\t// Custom collection: termlst is already populated with full term objects,\n\t\t\t// no need to look up from termdbConfig\n\t\t\tif (!term.propsByTermId) term.propsByTermId = {}\n\t\t} else {\n\t\t\tif (!opts.vocabApi?.termdbConfig?.termCollections)\n\t\t\t\tthrow `missing vocabApi.termdbConfig.termCollections argument for fill()`\n\t\t\tconst tc = opts.vocabApi.termdbConfig.termCollections.find((c: { name: string }) => c.name === term.name)\n\t\t\tif (tc) {\n\t\t\t\tif (!Array.isArray(tc.termIds)) throw new Error(`missing termCollection.termIds for '${tc.name}'`)\n\t\t\t\tif (!Array.isArray(tc.termlst)) throw new Error('missing tc.termlst[]')\n\t\t\t\tif (tc.termIds.length == 0) throw new Error('empty termIds[]')\n\t\t\t\tif (tc.termIds.length != tc.termlst.length) throw new Error('tc.termIds.length!=tc.termlst.length')\n\t\t\t\tif (!tc.propsByTermId) throw new Error(`propsByTermId missing for termCollection='${tc.name}'`)\n\t\t\t\tif (!term.propsByTermId) term.propsByTermId = tc.propsByTermId\n\t\t\t\tif (!term.termlst) term.termlst = tc.termlst\n\t\t\t\tif (tc.isCustom) term.isCustom = tc.isCustom\n\t\t\t\tterm.name = tc.name // normalize legacy display-label to canonical config name\n\t\t\t\tconst propsByTermId = term.propsByTermId!\n\t\t\t\tfor (const t of term.termlst!) {\n\t\t\t\t\tif (!propsByTermId[(t as any).id]) propsByTermId[(t as any).id] = tc.propsByTermId[(t as any).id]\n\t\t\t\t}\n\t\t\t} else if (!term.termlst?.length) {\n\t\t\t\tthrow new Error(`no matching termCollection for '${term.name}'`)\n\t\t\t}\n\t\t}\n\t\tterm.memberType = 'numeric'\n\t\tif (!term.isCustom && !term.termIds) term.termIds = term.termlst!.map((t: any) => t.id || t.name)\n\t\tNumericTermCollection.validate(term)\n\t}\n\n\tstatic validate(term: RawNumericTermCollection | NumericTermCollectionType) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != termType) throw `incorrect term.type='${term?.type}', expecting '${termType}'`\n\t}\n\n\tconstructor(term: NumericTermCollectionType) {\n\t\tNumericTermCollection.validate(term)\n\t\tthis.id = term.id\n\t\tthis.name = term.name\n\t\tthis.termlst = term.termlst\n\t\tthis.termIds = term.termIds\n\t\tthis.propsByTermId = term.propsByTermId || {}\n\t\tthis.numerators = term.numerators\n\t}\n}\n", "import type {\n\tCategoryKey,\n\tRawCategoricalTermCollection,\n\tCategoricalTermCollection as QualTermCollectionType\n} from '#types'\nimport { type TwOpts } from '../TwBase'\n\nconst termType = 'termCollection'\n\n/** Term class for categorical termCollections (memberType: 'categorical') */\nexport class QualTermCollection {\n\treadonly type = termType\n\treadonly memberType = 'categorical' as const\n\tid: string\n\tname: string\n\ttermIds?: string[]\n\ttermlst: object[]\n\tpropsByTermId: {\n\t\t[termId: string]: {\n\t\t\t[prop: string]: any\n\t\t}\n\t}\n\tcategoryKeys: CategoryKey[]\n\n\t// Mutates the raw term object in-place; routes from CollectionQual.fill()\n\tstatic fill(term: RawCategoricalTermCollection, opts: TwOpts = {}) {\n\t\tif (term instanceof QualTermCollection) return\n\t\tif (term.isCustom && term.termlst?.length) {\n\t\t\t// Custom collection: termlst is already populated with full term objects,\n\t\t\t// no need to look up from termdbConfig\n\t\t\tif (!term.propsByTermId) term.propsByTermId = {}\n\t\t} else {\n\t\t\tif (!opts.vocabApi?.termdbConfig?.termCollections)\n\t\t\t\tthrow `missing vocabApi.termdbConfig.termCollections argument for fill()`\n\t\t\tconst tc = opts.vocabApi.termdbConfig.termCollections.find((c: { name: string }) => c.name === term.name)\n\t\t\tif (tc) {\n\t\t\t\tif (!Array.isArray(tc.termIds)) throw new Error(`missing termCollection.termIds for '${tc.name}'`)\n\t\t\t\tif (!Array.isArray(tc.termlst)) throw new Error('missing tc.termlst[]')\n\t\t\t\tif (tc.termIds.length == 0) throw new Error('empty termIds[]')\n\t\t\t\tif (tc.termIds.length != tc.termlst.length) throw new Error('tc.termIds.length!=tc.termlst.length')\n\t\t\t\tif (!tc.propsByTermId) throw new Error(`propsByTermId missing for termCollection='${tc.name}'`)\n\t\t\t\tif (!term.propsByTermId) term.propsByTermId = tc.propsByTermId\n\t\t\t\tif (!term.termlst) term.termlst = tc.termlst\n\t\t\t\tif (tc.isCustom) term.isCustom = tc.isCustom\n\t\t\t\tterm.name = tc.name // normalize legacy display-label to canonical config name\n\t\t\t\tconst rawCategoryKeys = term.categoryKeys ?? tc.categoryKeys\n\t\t\t\tif (rawCategoryKeys) term.categoryKeys = rawCategoryKeys\n\t\t\t\tconst propsByTermId = term.propsByTermId!\n\t\t\t\tfor (const t of term.termlst!) {\n\t\t\t\t\tif (!propsByTermId[(t as any).id]) propsByTermId[(t as any).id] = tc.propsByTermId[(t as any).id]\n\t\t\t\t}\n\t\t\t} else if (!term.termlst?.length) {\n\t\t\t\tthrow new Error(`no matching termCollection for '${term.name}'`)\n\t\t\t}\n\t\t}\n\t\tterm.memberType = 'categorical'\n\t\tif (!term.isCustom && !term.termIds) term.termIds = term.termlst!.map((t: any) => t.id || t.name)\n\t\tQualTermCollection.validate(term)\n\t}\n\n\tstatic validate(term: RawCategoricalTermCollection | QualTermCollectionType) {\n\t\tif (typeof term !== 'object') throw 'term is not an object'\n\t\tif (term.type != termType) throw `incorrect term.type='${term?.type}', expecting '${termType}'`\n\t}\n\n\tconstructor(term: QualTermCollectionType) {\n\t\tQualTermCollection.validate(term)\n\t\tthis.id = term.id\n\t\tthis.name = term.name\n\t\tthis.termlst = term.termlst\n\t\tthis.termIds = term.termIds\n\t\tthis.propsByTermId = term.propsByTermId || {}\n\t\tthis.categoryKeys = term.categoryKeys\n\t}\n}\n", "import { NumericTermCollection } from './NumericTermCollection'\nimport { TwBase, type TwOpts } from '../TwBase'\nimport type { TermCollectionQCont, RawTermCollectionTWCont, TermCollectionTWCont } from '#types'\n\nexport type TermCollectionTransformedValue = {\n\tlabel: string\n\tvalue: number\n\tpre_val_sum: number\n\tcolor?: string\n}\n\nexport class CollectionCont extends TwBase {\n\tterm: NumericTermCollection\n\tq: TermCollectionQCont\n\n\tstatic fill(tw: RawTermCollectionTWCont, opts: TwOpts = {}): TermCollectionTWCont {\n\t\tNumericTermCollection.fill(tw.term, opts)\n\t\ttw.type = 'TermCollectionTWCont'\n\n\t\tif (!tw.q) tw.q = { mode: 'continuous', type: 'values', lst: [] }\n\t\telse {\n\t\t\tif (!tw.q.mode) tw.q.mode = 'continuous'\n\t\t\tif (!tw.q.type) tw.q.type = 'values'\n\t\t\tif (!tw.q.lst) tw.q.lst = []\n\t\t\t// Default numerators to all term IDs for old URLs that predate this field\n\t\t\tif (!tw.q.numerators)\n\t\t\t\ttw.q.numerators = tw.term.termIds?.slice() || tw.term.termlst?.map((t: any) => t.id || t.name) || []\n\t\t}\n\n\t\treturn tw as TermCollectionTWCont\n\t\t//TODO: check tw.q.lst against term.termIds[], should be a subset\n\t}\n\n\tconstructor(tw: TermCollectionTWCont, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.term = tw.term\n\t\tthis.q = tw.q\n\t}\n\n\tgetMinCopy() {\n\t\tconst copy: any = { term: {}, q: structuredClone(this.q) }\n\t\tif (this.$id) copy.$id = this.$id\n\t\tcopy.term.type = this.term.type\n\t\tcopy.term.name = this.term.name\n\t\tif (this.term.id) copy.term.id = this.term.id\n\t\tcopy.term.memberType = this.term.memberType\n\t\tif (this.term.numerators) copy.term.numerators = structuredClone(this.term.numerators)\n\t\tif (this.term.propsByTermId) copy.term.propsByTermId = structuredClone(this.term.propsByTermId)\n\t\tif (this.term.valueTransform) copy.term.valueTransform = structuredClone(this.term.valueTransform)\n\t\tcopy.term.termIds = this.term.termlst?.map((t: any) => t.id || t.name) || []\n\t\tif ((this.term as any).isCustom) {\n\t\t\tcopy.term.isCustom = true\n\t\t\tcopy.term.termlst = structuredClone(this.term.termlst)\n\t\t}\n\t\tif (copy.q) {\n\t\t\tdelete copy.q.isAtomic\n\t\t}\n\t\treturn copy\n\t}\n\n\ttransformData(d: any) {\n\t\tconst termsValue: { [termId: string]: number } = d.value\n\t\t// Collect all non-zero values after applying value transformation (if any)\n\t\tconst allValues: { [label: string]: number } = {}\n\t\tfor (const [label, value] of Object.entries(termsValue)) {\n\t\t\tlet transformedV: number = value\n\t\t\tif (this.term.valueTransform) {\n\t\t\t\tconst offset = (this.term.valueTransform as any).offset\n\t\t\t\tif (typeof offset === 'number') {\n\t\t\t\t\ttransformedV += offset\n\t\t\t\t}\n\t\t\t\t// Add more transformation types here as needed\n\t\t\t}\n\n\t\t\tif (transformedV !== 0) {\n\t\t\t\tallValues[label] = transformedV as number\n\t\t\t}\n\t\t}\n\n\t\t// Calculate total absolute sum of all values\n\t\tconst absoluteSum = Object.values(allValues).reduce((total, val) => total + Math.abs(val), 0)\n\n\t\t// Separate positive and negative values for proper stacking\n\t\tconst positiveEntries = Object.entries(allValues).filter(([, value]) => value > 0)\n\t\tconst negativeEntries = Object.entries(allValues).filter(([, value]) => value < 0)\n\t\tconst hasMixedValues = positiveEntries.length > 0 && negativeEntries.length > 0\n\n\t\tlet pre_val_sum_positive = 0\n\t\tlet pre_val_sum_negative = 0\n\t\tlet numerators_sum = 0\n\t\tconst values: TermCollectionTransformedValue[] = []\n\n\t\t// Process positive values\n\t\tfor (const [label, value] of positiveEntries) {\n\t\t\t// Calculate percentage based on absolute sum of all values\n\t\t\tconst pct = absoluteSum > 0 ? (value / absoluteSum) * 100 : 0\n\t\t\tif (pct && this.q.numerators?.includes(label)) {\n\t\t\t\tnumerators_sum += pct\n\t\t\t}\n\t\t\tconst color = this.term.propsByTermId[label]?.color\n\t\t\tvalues.push({\n\t\t\t\tlabel,\n\t\t\t\tvalue: pct,\n\t\t\t\tpre_val_sum: pre_val_sum_positive,\n\t\t\t\tcolor\n\t\t\t})\n\t\t\tpre_val_sum_positive += pct\n\t\t}\n\n\t\t// Process negative values\n\t\tfor (const [label, value] of negativeEntries) {\n\t\t\t// Calculate percentage based on absolute sum of all values (keeps sign)\n\t\t\tconst pct = absoluteSum > 0 ? (value / absoluteSum) * 100 : 0\n\t\t\tif (Math.abs(pct) && this.q.numerators?.includes(label)) {\n\t\t\t\tnumerators_sum += Math.abs(pct)\n\t\t\t}\n\t\t\tconst color = this.term.propsByTermId[label]?.color\n\t\t\tvalues.push({\n\t\t\t\tlabel,\n\t\t\t\tvalue: pct,\n\t\t\t\tpre_val_sum: pre_val_sum_negative,\n\t\t\t\tcolor\n\t\t\t})\n\t\t\tpre_val_sum_negative += pct\n\t\t}\n\n\t\td.values = values\n\t\td.numerators_sum = numerators_sum\n\t\td.hasMixedValues = hasMixedValues\n\t\tdelete d.value\n\t}\n}\n", "import { QualTermCollection } from './QualTermCollection'\nimport { TwBase, type TwOpts } from '../TwBase'\nimport type { TermCollectionQQual, RawTermCollectionTWQual, TermCollectionTWQual } from '#types'\n\nexport class CollectionQual extends TwBase {\n\tterm: QualTermCollection\n\tq: TermCollectionQQual\n\n\tstatic fill(tw: RawTermCollectionTWQual, opts: TwOpts = {}): TermCollectionTWQual {\n\t\tQualTermCollection.fill(tw.term, opts)\n\t\ttw.type = 'TermCollectionTWQual'\n\n\t\tif (!tw.q)\n\t\t\ttw.q = {\n\t\t\t\tmode: 'discrete',\n\t\t\t\ttype: 'values',\n\t\t\t\tlst: tw.term.termIds || tw.term.termlst?.map((t: any) => t.id || t.name) || []\n\t\t\t}\n\t\telse {\n\t\t\tif (!tw.q.mode) tw.q.mode = 'discrete'\n\t\t\tif (!tw.q.type) tw.q.type = 'values'\n\t\t\tif (!tw.q.lst) tw.q.lst = tw.term.termIds || tw.term.termlst?.map((t: any) => t.id || t.name) || []\n\t\t}\n\t\tif (!tw.q.categoryKeys && tw.term.categoryKeys?.length) {\n\t\t\ttw.q.categoryKeys = structuredClone(tw.term.categoryKeys)\n\t\t}\n\n\t\treturn tw as TermCollectionTWQual\n\t\t//TODO: check tw.q.lst against term.termIds[], should be a subset\n\t}\n\n\tconstructor(tw: TermCollectionTWQual, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.term = tw.term\n\t\tthis.q = tw.q\n\t}\n\n\tgetMinCopy() {\n\t\tconst copy: any = { term: {}, q: structuredClone(this.q) }\n\t\tif (this.$id) copy.$id = this.$id\n\t\tcopy.term.type = this.term.type\n\t\tcopy.term.name = this.term.name\n\t\tif (this.term.id) copy.term.id = this.term.id\n\t\tcopy.term.memberType = this.term.memberType\n\t\tif (this.term.categoryKeys) copy.term.categoryKeys = structuredClone(this.term.categoryKeys)\n\t\tif (this.term.propsByTermId) copy.term.propsByTermId = structuredClone(this.term.propsByTermId)\n\t\tcopy.term.termIds = this.term.termlst?.map((t: any) => t.id || t.name) || []\n\t\tif ((this.term as any).isCustom) {\n\t\t\tcopy.term.isCustom = true\n\t\t\tcopy.term.termlst = structuredClone(this.term.termlst)\n\t\t}\n\t\tif (copy.q) {\n\t\t\tdelete copy.q.isAtomic\n\t\t}\n\t\treturn copy\n\t}\n}\n", "import type {\n\tTermCollectionTW,\n\tRawTermCollectionTW,\n\tRawTermCollectionTWCont,\n\tRawTermCollectionTWQual,\n\tTermCollectionQ\n} from '#types'\nimport type { NumericTermCollection } from './NumericTermCollection'\nimport type { QualTermCollection } from './QualTermCollection'\nimport { CollectionCont } from './CollectionCont'\nimport { CollectionQual } from './CollectionQual'\nimport { type TwOpts, TwBase } from '../TwBase'\n\nexport class CollectionBase extends TwBase {\n\tterm: NumericTermCollection | QualTermCollection\n\tq: TermCollectionQ\n\n\tconstructor(tw: TermCollectionTW, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.type = tw.type\n\t\tthis.term = tw.term\n\t\tthis.q = tw.q\n\t}\n\n\tstatic fill(tw: RawTermCollectionTW, opts: TwOpts = {}): TermCollectionTW {\n\t\tif (!tw.type) {\n\t\t\tconst term = tw.term as any\n\t\t\tif (term.isCustom && term.memberType) {\n\t\t\t\t// Custom collection: memberType is already on the term, no config lookup needed\n\t\t\t\ttw.type = term.memberType === 'numeric' ? 'TermCollectionTWCont' : 'TermCollectionTWQual'\n\t\t\t} else {\n\t\t\t\t// Peek at config to determine memberType for routing (full fill happens inside CollectionCont/Qual)\n\t\t\t\tif (!opts.vocabApi?.termdbConfig?.termCollections)\n\t\t\t\t\tthrow `missing vocabApi.termdbConfig.termCollections argument for fill()`\n\t\t\t\tconst tc = opts.vocabApi.termdbConfig.termCollections.find((c: { name: string }) => c.name === term.name)\n\t\t\t\tif (!tc) throw new Error(`no matching termCollection for '${term.name}'`)\n\t\t\t\ttw.type = tc.type === 'numeric' ? 'TermCollectionTWCont' : 'TermCollectionTWQual'\n\t\t\t}\n\t\t}\n\n\t\tswitch (tw.type) {\n\t\t\tcase 'TermCollectionTWCont': {\n\t\t\t\tCollectionCont.fill(tw as RawTermCollectionTWCont, opts)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'TermCollectionTWQual': {\n\t\t\t\tCollectionQual.fill(tw as RawTermCollectionTWQual, opts)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\t// should never be reached if TwRouter.fill() routes correctly\n\t\t\t\tthrow `unexpected collection tw.type='${(tw as any).type}'`\n\t\t}\n\n\t\treturn tw as TermCollectionTW\n\t\t//TODO: check tw.q.lst against term.termIds[], should be a subset\n\t}\n}\n", "import { Menu, make_radios, addGeneSearchbox, GeneSetEditUI, table2col } from '#dom'\nimport type { VocabApi } from '#types'\nimport { dtTerms, dtcnv } from '#shared/common.js'\nimport { isEligibleForAllelicGroupset } from '../../tw/geneVariant'\n\n// TODO: output of this handler should not be q.predefined_groupset_idx, instead should be q.dt and q.origin. Then, in client/tw/geneVariant.ts, should fill in q.predefined_groupset_idx based on q.dt and q.origin. This will also allow easy specification of desired dt/origin in url. Will need to make separate radio buttons for dt and origin to support the different q properties.\n\ntype Opts = {\n\tholder: any\n\tapp: any\n\tgenomeObj: any\n\tdt?: number // dt to search, if missing will use first available dt in ds\n\tmsg?: string // message to be displayed below search bar\n\tcallback: (tw: any) => Promise<void>\n}\n\nexport class SearchHandler {\n\topts: any\n\tdom: any\n\tmutationTypeRadio: any\n\tinputTypeRadio: any\n\tterm: any // tw.term\n\tq: any // tw.q\n\tcallback: any\n\tmaxNumGenes: any\n\n\tasync init(opts: Opts) {\n\t\tthis.opts = opts\n\t\tthis.dom = {}\n\t\tthis.term = { type: 'geneVariant' }\n\t\tthis.q = { type: 'predefined-groupset' }\n\t\tthis.callback = opts.callback\n\t\tthis.maxNumGenes = this.opts.app.vocabApi.termdbConfig?.maxGeneVariantGeneSetSize || 200 // max # genes allowed\n\t\topts.holder.style('padding', '5px 10px 10px 25px')\n\t\tthis.dom.typeSettingDiv = opts.holder.append('div')\n\t\tthis.dom.searchDiv = opts.holder\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-genevariant-geneSearchDiv')\n\t\t\t.style('padding-left', '3px')\n\t\tthis.dom.msgDiv = opts.holder\n\t\t\t.append('div')\n\t\t\t.style('display', 'none')\n\t\t\t.style('font-size', '.7em')\n\t\t\t.style('margin-top', '5px')\n\t\t\t.style('padding-left', '3px')\n\t\tif (opts.msg) this.dom.msgDiv.style('display', 'block').text(opts.msg)\n\n\t\t// get child dt terms\n\t\tgetChildTerms(this.term, this.opts.app.vocabApi)\n\n\t\t// collect mutation type terms\n\t\tconst mutationTypeTerms = structuredClone(this.term.childTerms)\n\t\t// add in bi/mono-allelic mutation type, if applicable\n\t\tif (isEligibleForAllelicGroupset(this.term, this.opts.app.vocabApi))\n\t\t\tmutationTypeTerms.push({ name: 'Bi/mono-allelic' })\n\n\t\t// get index of mutation type term to select in mutation type radios\n\t\tconst mutationTypeTermIdx = opts.dt ? mutationTypeTerms.findIndex(t => t.dt == opts.dt) : 0\n\t\tif (!Number.isInteger(mutationTypeTermIdx) || mutationTypeTermIdx == -1)\n\t\t\tthrow new Error('invalid mutation type term index')\n\n\t\t{\n\t\t\tconst table = table2col({ holder: this.dom.typeSettingDiv, margin: '0px 0px 15px 0px' })\n\t\t\t// create radios for mutation type\n\t\t\t{\n\t\t\t\tconst [td1, td2] = table.addRow()\n\t\t\t\ttd1.text('Mutation Type')\n\t\t\t\tthis.mutationTypeRadio = make_radios({\n\t\t\t\t\tholder: td2.attr('data-testid', 'sjpp-genevariant-mutationTypeRadios'),\n\t\t\t\t\tstyles: { display: 'inline-block' },\n\t\t\t\t\toptions: mutationTypeTerms.map((t, i) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tlabel: t.name,\n\t\t\t\t\t\t\tvalue: i,\n\t\t\t\t\t\t\tchecked: i == mutationTypeTermIdx,\n\t\t\t\t\t\t\ttestid: 'sjpp-genevarianttermdbhandler-radio-' + t.name\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tcallback: v => {\n\t\t\t\t\t\tthis.toggleGeneSetRadioDisplay(v)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\t// create radios for type of gene input\n\t\t\t{\n\t\t\t\tconst [td1, td2] = table.addRow()\n\t\t\t\ttd1.text('Input Type')\n\t\t\t\tthis.inputTypeRadio = make_radios({\n\t\t\t\t\tholder: td2.attr('data-testid', 'sjpp-genevariant-genesetTypeRadios'),\n\t\t\t\t\tstyles: { display: 'inline-block' },\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Single Gene',\n\t\t\t\t\t\t\tvalue: 'single',\n\t\t\t\t\t\t\tchecked: true,\n\t\t\t\t\t\t\ttestid: 'sjpp-genevarianttermdbhandler-singlegene'\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ label: 'Gene Set', value: 'geneset', checked: false, testid: 'sjpp-genevarianttermdbhandler-geneset' }\n\t\t\t\t\t],\n\t\t\t\t\tcallback: v => (v == 'single' ? this.searchGene() : this.searchGeneSet())\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tthis.toggleGeneSetRadioDisplay(mutationTypeTermIdx)\n\t\tthis.searchGene()\n\t}\n\n\t// hide gene set radio when mutation type is cnv\n\t// because cnv of one gene can disguise cnv of another gene\n\t// example: if sample has cnv amplification in geneA and\n\t// cnv deletion in geneB, classification of the sample will\n\t// be ambiguous\n\ttoggleGeneSetRadioDisplay(childTermIdx) {\n\t\tconst childTerm = this.term.childTerms[childTermIdx]\n\t\tconst geneSetDiv = this.inputTypeRadio.divs.filter(d => {\n\t\t\tif (d.value != 'single' && d.value != 'geneset') throw new Error('unexpected input type radio value')\n\t\t\treturn d.value == 'geneset'\n\t\t})\n\t\tconst geneInput = this.inputTypeRadio.inputs.filter(d => {\n\t\t\tif (d.value != 'single' && d.value != 'geneset') throw new Error('unexpected input type radio value')\n\t\t\treturn d.value == 'single'\n\t\t})\n\t\tif (childTerm?.dt == dtcnv) {\n\t\t\t// mutation type is cnv\n\t\t\t// hide gene set radio button\n\t\t\tgeneSetDiv.style('display', 'none')\n\t\t\t// select single gene radio button\n\t\t\tgeneInput.node().click()\n\t\t} else {\n\t\t\t// mutation type is not cnv\n\t\t\t// can display gene set radio button\n\t\t\tgeneSetDiv.style('display', 'inline-block')\n\t\t}\n\t}\n\n\tsearchGene() {\n\t\tthis.dom.searchDiv.selectAll('*').remove()\n\t\tthis.dom.searchDiv.style('margin', '10px 0px')\n\t\tconst geneSearch = addGeneSearchbox({\n\t\t\ttip: new Menu({ padding: '0px' }),\n\t\t\tgenome: this.opts.genomeObj,\n\t\t\trow: this.dom.searchDiv,\n\t\t\t/* only allowing gene search for now because:\n\t\t\t- coordinate search is not yet supported for gdc\n\t\t\t- for other datasets, even though coordinate search is supported, it is not compatible with input type radios (single gene vs. geneset) because a coordinate may include one or more genes.\n\t\t\tTODO: fully support coordinate search\n\t\t\t*/\n\t\t\tsearchOnly: 'gene',\n\t\t\tcallback: async () => await this.selectGene(geneSearch)\n\t\t})\n\t\tthis.dom.searchDiv.select('.sja_genesearchinput').style('margin', '0px')\n\t}\n\n\tasync selectGene(geneSearch) {\n\t\tif (geneSearch.geneSymbol) {\n\t\t\tconst name = geneSearch.geneSymbol\n\t\t\tObject.assign(this.term, {\n\t\t\t\tid: name,\n\t\t\t\tname,\n\t\t\t\tgenes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: 'gene',\n\t\t\t\t\t\tid: name,\n\t\t\t\t\t\tgene: name,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttype: 'geneVariant'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\ttype: 'geneVariant'\n\t\t\t})\n\t\t} else if (geneSearch.chr && geneSearch.start && geneSearch.stop) {\n\t\t\tconst { chr, start, stop } = geneSearch\n\t\t\t// name should be 1-based coordinate\n\t\t\tconst name = `${chr}:${start + 1}-${stop}`\n\t\t\tObject.assign(this.term, {\n\t\t\t\tid: name,\n\t\t\t\tname,\n\t\t\t\tgenes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: 'coord',\n\t\t\t\t\t\tchr,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\tstop,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttype: 'geneVariant'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\ttype: 'geneVariant'\n\t\t\t})\n\t\t} else {\n\t\t\tthrow 'no gene or position specified'\n\t\t}\n\t\tawait this.runCallback()\n\t}\n\n\tsearchGeneSet() {\n\t\tthis.dom.searchDiv.selectAll('*').remove()\n\t\tthis.dom.searchDiv.style('margin-top', '0px')\n\t\tnew GeneSetEditUI({\n\t\t\tholder: this.dom.searchDiv.append('div'),\n\t\t\tgenome: this.opts.genomeObj,\n\t\t\tvocabApi: this.opts.app.vocabApi,\n\t\t\tnameInput: true,\n\t\t\tmaxNumGenes: this.maxNumGenes,\n\t\t\tcallback: async result => await this.selectGeneSet(result)\n\t\t})\n\t\tthis.dom.searchDiv.select('.sja_genesetinput').style('padding', '0px').style('margin-top', '-10px')\n\t}\n\n\tasync selectGeneSet(result) {\n\t\tconst genes = result.geneList.map(v => {\n\t\t\tif (!v.gene) throw 'gene name not found'\n\t\t\tconst name = v.gene\n\t\t\tconst gene = {\n\t\t\t\tkind: 'gene',\n\t\t\t\tid: name,\n\t\t\t\tgene: name,\n\t\t\t\tname,\n\t\t\t\ttype: 'geneVariant'\n\t\t\t}\n\t\t\treturn gene\n\t\t})\n\t\tconst name = result.name\n\t\tif (!name) throw 'gene set name not found'\n\t\tObject.assign(this.term, {\n\t\t\tid: name,\n\t\t\tname,\n\t\t\tgenes,\n\t\t\ttype: 'geneVariant'\n\t\t})\n\t\tawait this.runCallback()\n\t}\n\n\tasync runCallback() {\n\t\tthis.dom.msgDiv.style('display', 'block').text('LOADING ...')\n\t\t// add parent geneVariant term to each child term now\n\t\t// that gene(s) have been selected\n\t\taddParentTerm(this.term)\n\t\tconst selectedMutationType = this.mutationTypeRadio.inputs.nodes().find(r => r.checked)\n\t\tthis.q.predefined_groupset_idx = Number(selectedMutationType.value)\n\t\tawait this.callback({ term: this.term, q: this.q })\n\t\tthis.dom.msgDiv.style('display', 'none')\n\t}\n}\n\n// function to get child dt terms that are present in dataset\nexport function getChildTerms(term, vocabApi: VocabApi) {\n\tif (!vocabApi.termdbConfig?.queries) throw 'termdbConfig.queries is missing'\n\tterm.childTerms = []\n\tfor (const _t of dtTerms) {\n\t\tconst t = structuredClone(_t)\n\t\tif (!Object.keys(vocabApi.termdbConfig.queries).includes(t.query)) continue // dt is not in dataset\n\t\tconst byOrigin = vocabApi.termdbConfig.assayAvailability?.byDt[t.dt]?.byOrigin\n\t\tif (byOrigin) {\n\t\t\t// dt has origins in dataset\n\t\t\tif (!t.origin) continue // dt term does not have origin, so skip\n\t\t\tif (!Object.keys(byOrigin).includes(t.origin)) throw 'unexpected origin of dt term'\n\t\t} else {\n\t\t\t// dt does not have origins in dataset\n\t\t\tif (t.origin) continue // dt term has origin, so skip\n\t\t}\n\t\tterm.childTerms.push(t)\n\t}\n}\n\n// add parent geneVariant term to each child dt term\n// note: cannot be done within getChildTerms() because\n// getChildTerms() is called by init() before any genes\n// have been selected\nexport function addParentTerm(term) {\n\tif (!term.childTerms?.length) throw 'term.childTerms[] is missing'\n\tfor (const t of term.childTerms) {\n\t\tt.parentTerm = structuredClone(term)\n\t\tdelete t.parentTerm.childTerms // remove any nested child terms\n\t\tdelete t.parentTerm.groupsetting // remove nested term groupsetting\n\t}\n}\n", "import { getPillNameDefault } from '../utils.ts'\nimport { make_radios, renderTable } from '#dom'\nimport { filterInit, filterPromptInit, getNormalRoot, excludeFilterByTag } from '#filter/filter'\nimport type { TermSetting } from '../TermSetting.ts'\nimport { vocabInit } from '#termdb/vocabulary'\nimport { getDtTermValues } from '#filter/tvs.dt'\nimport { getColors } from '#shared/common.js'\nimport { rgb } from 'd3-color'\n\nconst colorScale = getColors(5)\n\n// self is the termsetting instance\nexport function getHandler(self: TermSetting) {\n\treturn {\n\t\tgetPillName(d: any) {\n\t\t\tlet name = d.name\n\t\t\tif (!name) {\n\t\t\t\tif (d.genes) name = d.genes.map(g => g.gene).join(', ')\n\t\t\t\telse if (d.chr) name = `${d.chr}:${d.start}-${d.stop}`\n\t\t\t\telse name = d.id || 'geneVariant'\n\t\t\t}\n\t\t\treturn getPillNameDefault(self, { name })\n\t\t},\n\n\t\tgetPillStatus() {\n\t\t\tlet text\n\t\t\tconst q = self.q as any // TODO: migrate this handler to use client/tw code\n\t\t\tif (q.type == 'predefined-groupset') {\n\t\t\t\tconst groupsetting = self.term.groupsetting\n\t\t\t\tif (!groupsetting?.lst?.length) throw 'no predefined groupsets found'\n\t\t\t\tconst groupset = groupsetting.lst[q.predefined_groupset_idx]\n\t\t\t\ttext = groupset.name\n\t\t\t} else if (q.type == 'custom-groupset') {\n\t\t\t\tconst n = q.customset.groups.length\n\t\t\t\ttext = `Divided into ${n} groups`\n\t\t\t} else {\n\t\t\t\ttext = 'any variant class'\n\t\t\t}\n\t\t\treturn { text }\n\t\t},\n\n\t\tasync showEditMenu(div: Element) {\n\t\t\tawait makeEditMenu(self, div)\n\t\t}\n\t}\n}\n\nasync function makeEditMenu(self: TermSetting, _div: any) {\n\t/* TODO: instead of directly modifying self.q here, should create a separate property on the handler to store pending user\n\tconfigurations (similar to numeric continuous/discrete switching)\n\tconst handler = self.handlerByType.geneVariant */\n\tconst div = _div.append('div').style('margin', '10px')\n\tdiv.append('div').style('font-size', '1.2rem').text(self.term.name)\n\tconst optsDiv = div.append('div').style('margin-top', '10px').style('margin-bottom', '1px')\n\tconst groupsDiv = div.append('div').style('display', 'none').style('margin', '10px').style('vertical-align', 'top')\n\t// radio buttons for whether or not to group samples\n\toptsDiv.append('div').style('font-weight', 'bold').text('Group samples')\n\tconst q = self.q as any // TODO: migrate this handler to use client/tw code\n\tconst isGroupset = q.type == 'predefined-groupset' || q.type == 'custom-groupset'\n\tmake_radios({\n\t\tholder: optsDiv,\n\t\toptions: [\n\t\t\t{ label: 'No sample grouping', value: 'noGroup', checked: !isGroupset },\n\t\t\t{ label: 'Assign samples to groups', value: 'group', checked: isGroupset }\n\t\t],\n\t\tcallback: async v => {\n\t\t\tif (v == 'group') {\n\t\t\t\tif (q.type == 'values') Object.assign(q, { type: 'custom-groupset', customset: { groups: [] } })\n\t\t\t\tawait makeGroupUI(self, groupsDiv)\n\t\t\t} else {\n\t\t\t\tclearGroupset(self)\n\t\t\t\tgroupsDiv.style('display', 'none')\n\t\t\t}\n\t\t}\n\t})\n\tif (isGroupset) await makeGroupUI(self, groupsDiv)\n\n\tif (\n\t\t(self.usecase?.detail && ['term', 'term0', 'term2'].includes(self.usecase.detail)) ||\n\t\tself.opts.geneVariantEditMenuOnlyGrp\n\t) {\n\t\t// only groupsetting is allowed\n\t\t// hide option for turning off groupsetting\n\t\toptsDiv.style('display', 'none')\n\t\tgroupsDiv.style('margin', '0px')\n\t}\n\n\t// apply button\n\tdiv\n\t\t.append('div')\n\t\t.style('margin-top', '25px')\n\t\t.append('button')\n\t\t.text('Apply')\n\t\t.on('click', () => {\n\t\t\tconst q = self.q as any // TODO: migrate this handler to use client/tw code\n\t\t\tif (q.type == 'predefined-groupset' || q.type == 'custom-groupset') {\n\t\t\t\t// groupsetting\n\t\t\t\tif (!self.groups?.length) {\n\t\t\t\t\t// no groups created\n\t\t\t\t\twindow.alert('Samples must be assigned to at least one group.')\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\t// groups created, assign to custom groupset\n\t\t\t\t\tconst dtLst = getDtsFromGroups(self.groups)\n\t\t\t\t\tObject.assign(q, { type: 'custom-groupset', customset: { groups: self.groups }, dtLst })\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// no groupsetting\n\t\t\t\tif (q.type != 'values') throw `q.type must be 'values'`\n\t\t\t}\n\t\t\tself.api.runCallback()\n\t\t})\n}\n\nexport function getDtsFromGroups(groups) {\n\tconst dts = new Set()\n\tfor (const group of groups) {\n\t\tconst filter = group.filter\n\t\tfor (const dt of getDtsFromFilter(filter)) {\n\t\t\tdts.add(dt)\n\t\t}\n\t}\n\tconst dtLst = [...dts]\n\treturn dtLst\n}\n\nfunction getDtsFromFilter(filter) {\n\tconst dts = new Set()\n\tfor (const item of filter.lst) {\n\t\tif (item.type == 'tvslst') {\n\t\t\tfor (const dt of getDtsFromFilter(item)) dts.add(dt)\n\t\t} else {\n\t\t\tconst tvs = item.tvs\n\t\t\tdts.add(tvs.term.dt)\n\t\t}\n\t}\n\treturn dts\n}\n\n// make UI for grouping variants\nasync function makeGroupUI(self: TermSetting, div) {\n\tdiv.style('display', 'block')\n\tdiv.selectAll('*').remove()\n\n\t// message\n\tdiv\n\t\t.append('div')\n\t\t.style('margin', '15px 0px')\n\t\t.text(\n\t\t\t'Group samples by mutation status. Samples are assigned to first possible group. Only tested samples are considered.'\n\t\t)\n\n\t// filter table\n\tconst filterTableDiv = div.append('div')\n\t// add new group button\n\tconst addNewGroupBtnHolder = div.append('div')\n\n\tconst q = self.q as any // TODO: migrate this handler to use client/tw code\n\t// get groups\n\tif (q.type != 'predefined-groupset' && q.type != 'custom-groupset') throw 'unexpected q.type'\n\tif (!self.groups) {\n\t\tlet groupset\n\t\tif (q.type == 'predefined-groupset') {\n\t\t\tconst groupsetting = self.term.groupsetting\n\t\t\tif (!groupsetting.lst?.length) throw 'no predefined groupsets found'\n\t\t\tgroupset = groupsetting.lst[q.predefined_groupset_idx]\n\t\t} else {\n\t\t\tgroupset = q.customset\n\t\t}\n\t\tif (!groupset) throw 'groupset is missing'\n\t\tif (!Array.isArray(groupset.groups)) throw 'groupset.groups is not array'\n\t\tself.groups = structuredClone(groupset.groups)\n\t}\n\n\t// fill values of child dt terms with mutation classes of gene in dataset\n\tfor (const dtTerm of self.term.childTerms) {\n\t\tawait getDtTermValues(dtTerm, self.filter, self.vocabApi)\n\t}\n\n\t// build frontend vocab using child dt terms\n\tconst vocabApi: any = vocabInit({ vocab: { terms: self.term.childTerms } })\n\t// need termdbConfig.queries for cnv tvs (see getDtCnvType() in filter/tvs.js and\n\t// fillMenu() in filter/tvs.dtcnv.continuous.js)\n\t// not passing complete termdbConfig as presence of .allowedTermTypes will\n\t// trigger term type toggles (see init() in termdb/TermTypeSearch.ts)\n\tvocabApi.termdbConfig = { queries: self.vocabApi.termdbConfig.queries }\n\n\t// filter prompt\n\tconst filterPrompt = await filterPromptInit({\n\t\tholder: addNewGroupBtnHolder,\n\t\tvocabApi,\n\t\temptyLabel: 'Add group',\n\t\theader_mode: 'hide_search',\n\t\tcallback: f => {\n\t\t\tconst filter = getNormalRoot(f)\n\t\t\taddNewGroup(filter, self.groups)\n\t\t\tmakeGroupUI(self, div)\n\t\t},\n\t\tdebug: self.opts.debug\n\t})\n\n\t// filterPrompt.main() always empties the filterUiRoot data\n\tconst filter = structuredClone(self.filter)\n\tfilterPrompt.main(excludeFilterByTag(filter, 'cohortFilter')) // provide mass filter to limit the term tree\n\n\tif (!self.groups.length) {\n\t\t// no groups, hide table\n\t\tfilterTableDiv.style('display', 'none')\n\t\treturn\n\t}\n\n\t// clear table and populate rows\n\tfilterTableDiv.style('display', '').selectAll('*').remove()\n\tconst tableArg: any = {\n\t\tdiv: filterTableDiv,\n\t\tcolumns: [\n\t\t\t{}, // blank column to add delete buttons\n\t\t\t{\n\t\t\t\tlabel: 'NAME',\n\t\t\t\teditCallback: async (i, cell) => {\n\t\t\t\t\tconst newName = cell.value\n\t\t\t\t\tconst index = self.groups.findIndex(group => group.name == newName)\n\t\t\t\t\tif (index != -1) {\n\t\t\t\t\t\talert(`Group named ${newName} already exists`)\n\t\t\t\t\t\tmakeGroupUI(self, div)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.groups[i].name = newName\n\t\t\t\t\t\tmakeGroupUI(self, div)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: 'COLOR',\n\t\t\t\teditCallback: async (i, cell) => {\n\t\t\t\t\tself.groups[i].color = cell.color\n\t\t\t\t\tmakeGroupUI(self, div)\n\t\t\t\t}\n\t\t\t},\n\t\t\t//{ label: '#SAMPLE' }, // will re-enable when filtered sample count can be supported for gdc\n\t\t\t{ label: 'FILTER' }\n\t\t],\n\t\trows: [],\n\t\tstriped: false, // no alternating row bg color so delete button appears more visible\n\t\tshowLines: false\n\t}\n\n\tfor (const g of self.groups) {\n\t\ttableArg.rows.push([\n\t\t\t{}, // blank cell to add delete button\n\t\t\t{ value: g.name }, // to allow click to show <input>\n\t\t\t{ color: g.color },\n\t\t\t// { value: 'n=' + (await self.vocabApi.getFilteredSampleCount(g.filter)) }, // will re-enable when filtered sample count can be supported for gdc\n\t\t\t{} // blank cell to show filter ui\n\t\t])\n\t}\n\n\trenderTable(tableArg)\n\n\t// after rendering table, iterate over rows again to fill cells with control elements\n\tfor (const [i, row] of tableArg.rows.entries()) {\n\t\t// add delete button in 1st cell\n\t\trow[0].__td\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.style('padding', '1px 6px')\n\t\t\t.html('×')\n\t\t\t.on('click', () => {\n\t\t\t\tself.groups.splice(i, 1)\n\t\t\t\tmakeGroupUI(self, div)\n\t\t\t})\n\n\t\t// create filter ui in its cell\n\t\tconst group = self.groups[i]\n\t\tfilterInit({\n\t\t\tholder: row[3].__td,\n\t\t\tvocabApi,\n\t\t\theader_mode: 'hide_search',\n\t\t\tcallback: f => {\n\t\t\t\tif (!f || f.lst.length == 0) {\n\t\t\t\t\t// blank filter (user removed last tvs from this filter), delete this element from groups[]\n\t\t\t\t\tconst i = self.groups.findIndex(g => g.name == group.name)\n\t\t\t\t\tself.groups.splice(i, 1)\n\t\t\t\t} else {\n\t\t\t\t\t// update filter\n\t\t\t\t\texcludeGeneNameFromFilter(f) // no need to show gene name in filter pill\n\t\t\t\t\tgroup.filter = f\n\t\t\t\t}\n\t\t\t\tmakeGroupUI(self, div)\n\t\t\t}\n\t\t}).main(group.filter)\n\t}\n}\n\nfunction addNewGroup(filter, groups, name?: string) {\n\tif (!groups) throw 'groups is missing'\n\tif (!name) {\n\t\tconst base = 'New group'\n\t\tname = base\n\t\tfor (let i = 0; ; i++) {\n\t\t\tname = base + (i === 0 ? '' : ' ' + i)\n\t\t\tif (!groups.find(g => g.name === name)) break\n\t\t}\n\t}\n\texcludeGeneNameFromFilter(filter) // no need to show gene name in filter pill\n\tconst newGroup = {\n\t\tname,\n\t\ttype: 'filter',\n\t\tfilter,\n\t\tcolor: rgb(colorScale(groups.length)).formatHex()\n\t}\n\tgroups.push(newGroup)\n}\n\nfunction excludeGeneNameFromFilter(filter) {\n\tfor (const item of filter.lst) {\n\t\tif (item.type == 'tvslst') {\n\t\t\texcludeGeneNameFromFilter(item)\n\t\t} else if (item.type == 'tvs') {\n\t\t\titem.tvs.excludeGeneName = true\n\t\t} else {\n\t\t\tthrow 'unexpected item.type'\n\t\t}\n\t}\n}\n\nfunction clearGroupset(self) {\n\tself.q.type = 'values'\n\tdelete self.q.predefined_groupset_idx\n\tdelete self.q.customset\n}\n", "import type {\n\tGvTerm,\n\tBaseGroupSet,\n\tGvValuesQ,\n\tGvCustomGsQ,\n\tGvPredefinedGsQ,\n\tRawGvValuesTW,\n\tGvValuesTW,\n\tRawGvCustomGsTW,\n\tGvCustomGsTW,\n\tRawGvPredefinedGsTW,\n\tGvPredefinedGsTW,\n\tRawGvTW,\n\tGvTW,\n\tRawGvTerm,\n\tVocabApi,\n\tTermValues\n} from '#types'\nimport { TwBase, type TwOpts } from './TwBase.ts'\nimport { copyMerge } from '#rx'\nimport { set_hiddenvalues } from '#termsetting'\nimport { getWrappedTvslst } from '#filter/filter'\nimport { getDtTermValues } from '#filter/tvs.dt'\nimport { getChildTerms, addParentTerm } from '../termdb/handlers/geneVariant'\nimport { getColors, dtcnv, dtsnvindel, mclass } from '#shared/common.js'\nimport { getDtsFromGroups } from '../termsetting/handlers/geneVariant'\nimport { rgb } from 'd3-color'\n\nlet colorScale = getColors(3)\n\nexport class GvBase extends TwBase {\n\t// type, isAtomic, $id are set in ancestor base classes\n\tterm: GvTerm\n\n\tconstructor(tw: GvTW, opts: TwOpts) {\n\t\tsuper(tw, opts)\n\t\tthis.term = tw.term\n\t}\n\n\t/** tw.term must already be filled-in at this point */\n\tstatic async fill(tw: RawGvTW, opts: TwOpts = {}): Promise<GvTW> {\n\t\tif (!tw.term) throw `missing tw.term, must already be filled in`\n\t\tif (tw.term.type != 'geneVariant') throw `incorrect term.type='${tw.term?.type}', expecting 'geneVariant'`\n\n\t\tif (opts.defaultQ != null) {\n\t\t\topts.defaultQ.isAtomic = true\n\t\t\t// merge defaultQ into tw.q\n\t\t\tcopyMerge(tw.q, opts.defaultQ)\n\t\t}\n\n\t\tif (!tw.term.genes?.length) {\n\t\t\t// support legacy term structure that lacks term.genes[]\n\t\t\tconst gene = structuredClone(tw.term)\n\t\t\ttw.term.genes = [gene]\n\t\t}\n\n\t\tfor (const gene of tw.term.genes) {\n\t\t\tif (!gene.kind) {\n\t\t\t\t// support saved states that don't have term.kind, applied when rehydrating at runtime\n\t\t\t\tconst term: any = gene\n\t\t\t\tif (term.gene || (term.name && !term.chr)) term.kind = 'gene'\n\t\t\t\telse if (term.chr) term.kind = 'coord'\n\t\t\t\telse throw 'unable to assign geneVariant term.kind'\n\t\t\t}\n\n\t\t\tif (gene.kind == 'gene') {\n\t\t\t\tif (!gene.gene) gene.gene = gene.name\n\t\t\t\tif (!gene.name) gene.name = gene.gene\n\t\t\t\tif (!gene.gene || !gene.name) throw 'missing gene/name'\n\t\t\t} else if (gene.kind == 'coord') {\n\t\t\t\tif (!gene.chr || !Number.isInteger(gene.start) || !Number.isInteger(gene.stop)) throw 'no position specified'\n\t\t\t\tif (!gene.name) {\n\t\t\t\t\tgene.name = `${gene.chr}:${gene.start + 1}-${gene.stop}`\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow 'cannot recognize gene.kind'\n\t\t\t}\n\n\t\t\tif (!gene.id) gene.id = gene.name\n\t\t}\n\n\t\tif (!tw.term.name) tw.term.name = tw.term.genes.map(gene => gene.name).join(', ')\n\n\t\tif (!Object.keys(tw.q).includes('type')) tw.q.type = 'values'\n\n\t\t// fill term.groupsetting\n\t\tif (!tw.term.groupsetting) tw.term.groupsetting = { disabled: false }\n\n\t\t// fill child dt terms\n\t\tif (!tw.term.childTerms) getChildTerms(tw.term, opts.vocabApi)\n\n\t\t// add geneVariant term to each child dt term\n\t\taddParentTerm(tw.term)\n\n\t\t// apply optional ds-level configs for this specific term\n\t\tconst cnv = opts.vocabApi.termdbConfig.queries.cnv\n\t\tif (cnv) {\n\t\t\tif ('cnvGainCutoff' in cnv || 'cnvLossCutoff' in cnv || 'cnvMaxLength' in cnv) {\n\t\t\t\t// continuous cnv data\n\t\t\t\t// assign cnv cutoffs to tw.q\n\t\t\t\t// priority of cnv cutoffs: tw.q > cnvCutoffsByGene > dsCnvCutoffs\n\t\t\t\tconst dsCnvCutoffs: { [key: string]: number } = {}\n\t\t\t\tif ('cnvGainCutoff' in cnv) dsCnvCutoffs.cnvGainCutoff = cnv.cnvGainCutoff\n\t\t\t\tif ('cnvLossCutoff' in cnv) dsCnvCutoffs.cnvLossCutoff = cnv.cnvLossCutoff\n\t\t\t\tif ('cnvMaxLength' in cnv) dsCnvCutoffs.cnvMaxLength = cnv.cnvMaxLength\n\t\t\t\tconst cnvCutoffsByGene = cnv.cnvCutoffsByGene?.[tw.term.name]\n\t\t\t\tconst defaultCnvCutoffs = cnvCutoffsByGene || dsCnvCutoffs\n\t\t\t\ttw.q = Object.assign({}, defaultCnvCutoffs, tw.q)\n\t\t\t}\n\t\t}\n\t\t/* \n\t\t\tPre-fill the tw.type, since it's required for ROUTING to the\n\t\t\tcorrect fill() function. Tsc will be able to use tw.type as a \n\t\t\tdiscriminant property for the RawGvTW union type, enabling \n\t\t\tstatic type checks on the input raw tw.\n\n\t\t\tNOTE: tw.type is NOT required when calling a specialized fill() \n\t\t\tfunction directly, outside of TwRouter.fill(). The input tw.type\n\t\t\tdoes not have to be discriminated in that case.\n\t\t*/\n\t\ttw.type =\n\t\t\t!tw.q.type || tw.q.type == 'values'\n\t\t\t\t? 'GvValuesTW'\n\t\t\t\t: tw.q.type == 'predefined-groupset'\n\t\t\t\t? 'GvPredefinedGsTW'\n\t\t\t\t: tw.q.type == 'custom-groupset'\n\t\t\t\t? 'GvCustomGsTW'\n\t\t\t\t: tw.type\n\n\t\t/*\n\t\t\tFor each of fill() functions below:\n\t\t\t1. The `tw` argument must already have a tw.type string value, \n\t\t\t which corresponds to the RawGvTW* equivalent of the full GvTW* type \n\n\t\t\t2. The fill() function must fill-in any expected missing values,\n\t\t\t validate the tw.q shape at runtime, and throw on any error or mismatched expectation.\n\t\t\t Runtime validation is required because the input raw tw can come from anywhere,\n\t\t\t like term.bins.default, which is a runtime variable that is not possible to statically check.\n\n\t\t\t3. The filled-in tw, when returned, must be **coerced** to the full GvTW* type, \n\t\t\t in order to match the function signature's return type.\n\t\t*/\n\t\tswitch (tw.type) {\n\t\t\tcase 'GvValuesTW':\n\t\t\t\treturn await GvValues.fill(tw)\n\n\t\t\tcase 'GvPredefinedGsTW':\n\t\t\t\treturn await GvPredefinedGS.fill(tw, opts)\n\n\t\t\tcase 'GvCustomGsTW':\n\t\t\t\treturn await GvCustomGS.fill(tw)\n\n\t\t\tdefault:\n\t\t\t\tthrow `tw.type='${tw.type}' is not supported by GvBase.fill()`\n\t\t}\n\t}\n}\n\nexport class GvValues extends GvBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: GvValuesQ\n\t#tw: GvValuesTW\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: GvValuesTW, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t//this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\t// See the relevant comments in the GvBase.fill() function above\n\tstatic async fill(tw: RawGvValuesTW): Promise<GvValuesTW> {\n\t\tif (!tw.type) tw.type = 'GvValuesTW'\n\t\telse if (tw.type != 'GvValuesTW') throw `expecting tw.type='GvValuesTW', got '${tw.type}'`\n\t\tif (tw.term.type != 'geneVariant') throw `expecting tw.term.type='geneVariant', got '${tw.term.type}'`\n\t\tconst { term, q } = tw\n\t\tif (!q.type) q.type = 'values'\n\t\telse if (q.type != 'values') throw `expecting tw.q.type='values', got ${tw.q.type}`\n\t\tset_hiddenvalues(q, term)\n\t\treturn tw as GvValuesTW\n\t}\n}\n\nexport class GvPredefinedGS extends GvBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: GvPredefinedGsQ\n\tgroupset!: BaseGroupSet\n\t#tw: GvPredefinedGsTW\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: GvPredefinedGsTW, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t// this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tthis.#tw = tw\n\t\tObject.defineProperty(this, 'groupset', { value: this.#tw.term.groupsetting[this.#tw.q.predefined_groupset_idx] })\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\t// See the relevant comments in the GvBase.fill() function above\n\tstatic async fill(tw: RawGvPredefinedGsTW, opts: TwOpts = {}): Promise<GvPredefinedGsTW> {\n\t\tif (!tw.type) tw.type = 'GvPredefinedGsTW'\n\t\telse if (tw.type != 'GvPredefinedGsTW') throw `expecting tw.type='GvPredefinedGsTW', got '${tw.type}'`\n\n\t\tif (tw.term.type != 'geneVariant') throw `expecting tw.term.type='geneVariant', got '${tw.term.type}'`\n\t\tif (tw.q.type != 'predefined-groupset') throw `expecting tw.q.type='predefined-groupset', got '${tw.q.type}'`\n\t\tif (!Object.keys(tw.q).includes('predefined_groupset_idx')) tw.q.predefined_groupset_idx = 0\n\t\tif (!Number.isInteger(tw.q.predefined_groupset_idx)) throw 'invalid tw.q.predefined_groupset_idx'\n\n\t\t// get predefined groupsets\n\t\tawait getPredefinedGroupsets(tw.term, opts.vocabApi)\n\n\t\tconst { term, q } = tw\n\t\tif (!term.groupsetting?.lst?.length) throw 'term.groupsetting.lst[] is empty'\n\t\tif (q.dtLst?.length) {\n\t\t\t// query dts specified\n\t\t\t// select the groupset that has the query dts\n\t\t\tconst groupsetIdx = term.groupsetting.lst.findIndex(groupset => {\n\t\t\t\tconst dts = Number.isInteger(groupset.dt) ? [groupset.dt] : getDtsFromGroups(groupset.groups)\n\t\t\t\tif (!dts?.length) return false\n\t\t\t\tif (dts.length != q.dtLst?.length) return false\n\t\t\t\tif (dts.some(dt => !q.dtLst?.includes(dt))) return false\n\t\t\t\treturn true\n\t\t\t})\n\t\t\tif (groupsetIdx == -1) throw new Error('groupset with query dt(s) not found')\n\t\t\tq.predefined_groupset_idx = groupsetIdx\n\t\t} else {\n\t\t\t// query dts not specified\n\t\t\t// set the query dts to be the dts of the selected groupset\n\t\t\t// TODO: remove these type assertions\n\t\t\tconst idx = q.predefined_groupset_idx as number\n\t\t\tconst lst = term.groupsetting.lst as any[]\n\t\t\tconst groupset = lst[idx]\n\t\t\tq.dtLst = Number.isInteger(groupset.dt) ? [groupset.dt] : getDtsFromGroups(groupset.groups)\n\t\t}\n\t\tset_hiddenvalues(q, term)\n\t\treturn tw as GvPredefinedGsTW\n\t}\n\n\tgetTitleText() {\n\t\tconst gsname = this.term?.groupsetting?.lst?.[this.q.predefined_groupset_idx].name || ''\n\t\treturn `${this.term.name} ${gsname}`\n\t}\n}\n\nexport class GvCustomGS extends GvBase {\n\t// term, type, isAtomic, $id are set in ancestor base classes\n\tq: GvCustomGsQ\n\tgroupset!: BaseGroupSet\n\t#tw: GvCustomGsTW\n\t#opts: TwOpts\n\n\t// declare a constructor, to narrow the tw type\n\tconstructor(tw: GvCustomGsTW, opts: TwOpts = {}) {\n\t\tsuper(tw, opts)\n\t\t// this.term = tw.term // already set in base class\n\t\tthis.q = tw.q\n\t\tObject.defineProperty(this, 'groupset', { value: this.q.customset })\n\t\tthis.#tw = tw\n\t\tthis.#opts = opts\n\t}\n\n\tgetTw() {\n\t\treturn this.#tw\n\t}\n\n\t// See the relevant comments in the GvBase.fill() function above\n\tstatic async fill(tw: RawGvCustomGsTW): Promise<GvCustomGsTW> {\n\t\tif (!tw.type) tw.type = 'GvCustomGsTW'\n\t\telse if (tw.type != 'GvCustomGsTW') throw `expecting tw.type='GvCustomGsTW', got '${tw.type}'`\n\n\t\tif (tw.term.type != 'geneVariant') throw `expecting tw.term.type='geneVariant', got '${tw.term.type}'`\n\t\tif (tw.q.type != 'custom-groupset') throw `expecting tw.q.type='custom-groupset', got '${tw.q.type}'`\n\n\t\tconst { term, q } = tw\n\t\tif (!q.customset) throw 'missing tw.q.customset'\n\t\tif (!q.customset.groups.length) throw 'customset.groups[] is empty'\n\t\tif (!q.dtLst?.length) q.dtLst = getDtsFromGroups(q.customset.groups)\n\t\tset_hiddenvalues(q, term)\n\t\treturn tw as GvCustomGsTW\n\t}\n\n\tgetTitleText() {\n\t\treturn `${this.term.name} Custom Groups`\n\t}\n}\n\nasync function getPredefinedGroupsets(term: RawGvTerm, vocabApi: VocabApi) {\n\tif (!term.childTerms?.length) throw 'term.childTerms[] is missing'\n\t// build predefined groupsets based on child dt terms\n\tterm.groupsetting = { disabled: false }\n\tterm.groupsetting.lst = []\n\tfor (const dtTerm of term.childTerms) {\n\t\t// fill dt term values with mutation classes of gene in dataset\n\t\tawait getDtTermValues(dtTerm, vocabApi.state.termfilter?.filter, vocabApi)\n\t\tconst groupset: any = { name: dtTerm.name, dt: dtTerm.dt }\n\t\tif (dtTerm.origin) groupset.origin = dtTerm.origin\n\t\tif (dtTerm.dt == dtcnv) getCnvGroupset(groupset, dtTerm, term.name, vocabApi)\n\t\telse getNonCnvGroupset(groupset, dtTerm, term.name)\n\t\tterm.groupsetting.lst.push(groupset)\n\t}\n\n\tmayGetAllelicGroupset(term, vocabApi)\n\n\t// function to get cnv groupset\n\t// will route to appropriate function depending on mode of cnv data\n\tfunction getCnvGroupset(groupset, dtTerm, geneName, vocabApi) {\n\t\tconst cnv = vocabApi.termdbConfig.queries?.cnv\n\t\tif (!cnv) throw 'cnv query is missing'\n\t\tconst keys = Object.keys(cnv)\n\t\tconst isContinuous = keys.includes('cnvGainCutoff') || keys.includes('cnvLossCutoff')\n\t\tif (isContinuous) getContCnvGroupset(groupset, dtTerm, geneName, cnv)\n\t\telse getCatCnvGroupset(groupset, dtTerm, geneName)\n\t}\n\n\t// function to get cnv groupset for continuous cnv data\n\t// will compare gain/loss/neutral\n\tfunction getContCnvGroupset(groupset, dtTerm, geneName, cnv) {\n\t\tconst cnvDefault = cnv.cnvCutoffsByGene?.[dtTerm.parentTerm.name] || {\n\t\t\tcnvMaxLength: cnv.cnvMaxLength,\n\t\t\tcnvGainCutoff: cnv.cnvGainCutoff,\n\t\t\tcnvLossCutoff: cnv.cnvLossCutoff\n\t\t}\n\t\t// gain group\n\t\tconst gainGroup = {\n\t\t\tname: `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Gain (${dtTerm.origin})` : 'Gain'}`,\n\t\t\ttype: 'filter',\n\t\t\tfilter: getWrappedTvslst([\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: dtTerm,\n\t\t\t\t\t\tvalues: [],\n\t\t\t\t\t\tcontinuousCnv: true,\n\t\t\t\t\t\tcnvGainCutoff: cnvDefault.cnvGainCutoff,\n\t\t\t\t\t\tcnvLossCutoff: -99, // set to very low number to get samples with gain events\n\t\t\t\t\t\tcnvMaxLength: cnvDefault.cnvMaxLength,\n\t\t\t\t\t\tfractionOverlap: 0.8,\n\t\t\t\t\t\texcludeGeneName: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t])\n\t\t}\n\t\t// loss group\n\t\tconst lossGroup = {\n\t\t\tname: `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Loss (${dtTerm.origin})` : 'Loss'}`,\n\t\t\ttype: 'filter',\n\t\t\tfilter: getWrappedTvslst([\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: dtTerm,\n\t\t\t\t\t\tvalues: [],\n\t\t\t\t\t\tcontinuousCnv: true,\n\t\t\t\t\t\tcnvGainCutoff: 99, // set to very high number to get samples with loss events\n\t\t\t\t\t\tcnvLossCutoff: cnvDefault.cnvLossCutoff,\n\t\t\t\t\t\tcnvMaxLength: cnvDefault.cnvMaxLength,\n\t\t\t\t\t\tfractionOverlap: 0.8,\n\t\t\t\t\t\texcludeGeneName: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t])\n\t\t}\n\t\t// neutral group\n\t\tconst wtGroup = {\n\t\t\tname: `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Neutral (${dtTerm.origin})` : 'Neutral'}`,\n\t\t\ttype: 'filter',\n\t\t\tfilter: getWrappedTvslst([\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: dtTerm,\n\t\t\t\t\t\tvalues: [],\n\t\t\t\t\t\tcontinuousCnv: true,\n\t\t\t\t\t\tcnvWT: true,\n\t\t\t\t\t\tcnvGainCutoff: cnvDefault.cnvGainCutoff,\n\t\t\t\t\t\tcnvLossCutoff: cnvDefault.cnvLossCutoff,\n\t\t\t\t\t\tcnvMaxLength: cnvDefault.cnvMaxLength,\n\t\t\t\t\t\tfractionOverlap: 0.8,\n\t\t\t\t\t\texcludeGeneName: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t])\n\t\t}\n\t\tgroupset.groups = [gainGroup, lossGroup, wtGroup]\n\t\t// set color scale based on number of groups\n\t\tcolorScale = getColors(groupset.groups.length)\n\t\t// assign colors to each group\n\t\tfor (const group of groupset.groups) {\n\t\t\tgroup.color = rgb(colorScale(group.name)).formatHex()\n\t\t}\n\t}\n\n\t// function to get cnv groupset for categorical cnv data\n\t// will compare cnv categories present in the data\n\tfunction getCatCnvGroupset(groupset, dtTerm, geneName) {\n\t\tgroupset.groups = []\n\t\t// mutant values\n\t\tconst values = dtTerm.values as TermValues\n\t\tfor (const [k, v] of Object.entries(values)) {\n\t\t\tconst filter = getWrappedTvslst([\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: dtTerm,\n\t\t\t\t\t\tvalues: [{ key: k, label: v.label, value: k }],\n\t\t\t\t\t\tgenotype: 'variant',\n\t\t\t\t\t\tmcount: 'any',\n\t\t\t\t\t\texcludeGeneName: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t])\n\t\t\tconst name = `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `${v.label} (${dtTerm.origin})` : v.label}`\n\t\t\tconst color = mclass[v.key].color\n\t\t\tgroupset.groups.push({ name, type: 'filter', filter, color })\n\t\t}\n\t\t// wildtype value\n\t\tgroupset.groups.push({\n\t\t\tname: `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Wildtype (${dtTerm.origin})` : 'Wildtype'}`,\n\t\t\ttype: 'filter',\n\t\t\tfilter: getWrappedTvslst([\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: dtTerm,\n\t\t\t\t\t\tvalues: [],\n\t\t\t\t\t\tgenotype: 'wt',\n\t\t\t\t\t\texcludeGeneName: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]),\n\t\t\tcolor: mclass['WT'].color\n\t\t})\n\t}\n\n\t// function to get non-cnv (e.g. snv/indel, fusion, etc.) groupset\n\t// will compare mutant vs. wildtype\n\tfunction getNonCnvGroupset(groupset, dtTerm, geneName) {\n\t\tgroupset.groups = []\n\t\t// group 1: mutant\n\t\tconst grp1Name = `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Mutated (${dtTerm.origin})` : 'Mutated'}`\n\t\tconst values = dtTerm.values as TermValues\n\t\tconst grp1Tvs: any = {\n\t\t\tterm: dtTerm,\n\t\t\tvalues: Object.entries(values).map(([k, v]) => {\n\t\t\t\treturn { key: k, label: v.label, value: k }\n\t\t\t}),\n\t\t\tgenotype: 'variant',\n\t\t\tmcount: 'any',\n\t\t\texcludeGeneName: true\n\t\t}\n\t\tconst mafFilter = vocabApi.termdbConfig.queries?.snvindel?.mafFilter\n\t\tif (dtTerm.dt == dtsnvindel && mafFilter) {\n\t\t\tgrp1Tvs.mafFilter = mafFilter.filter\n\t\t}\n\t\tconst grp1Filter = getWrappedTvslst([{ type: 'tvs', tvs: grp1Tvs }])\n\t\tgroupset.groups.push({\n\t\t\tname: grp1Name,\n\t\t\ttype: 'filter',\n\t\t\tfilter: grp1Filter,\n\t\t\tcolor: '#e75480'\n\t\t})\n\t\t// group 2: wildtype\n\t\tconst grp2Name = `${geneName} ${dtTerm.name_noOrigin} ${dtTerm.origin ? `Wildtype (${dtTerm.origin})` : 'Wildtype'}`\n\t\tconst grp2Tvs = {\n\t\t\tterm: dtTerm,\n\t\t\tvalues: [],\n\t\t\tgenotype: 'wt',\n\t\t\texcludeGeneName: true\n\t\t}\n\t\tconst grp2Filter = getWrappedTvslst([{ type: 'tvs', tvs: grp2Tvs }])\n\t\tgroupset.groups.push({\n\t\t\tname: grp2Name,\n\t\t\ttype: 'filter',\n\t\t\tfilter: grp2Filter,\n\t\t\tcolor: mclass['WT'].color\n\t\t})\n\t}\n\n\t// build predefined groupset for biallelic vs. monoallelic alteration\n\tfunction mayGetAllelicGroupset(term, vocabApi) {\n\t\tif (!isEligibleForAllelicGroupset(term, vocabApi)) {\n\t\t\t// term and/or dataset is not eligible for building the groupset\n\t\t\treturn\n\t\t}\n\n\t\t// can build biallelic vs. monoallelic groupset\n\t\tconst snvIndelTerm = term.childTerms.find(t => t.dt == dtsnvindel)\n\t\tconst cnvTerm = term.childTerms.find(t => t.dt == dtcnv)\n\n\t\t// homozygous deletion tvs\n\t\tconst homoDel = {\n\t\t\ttype: 'tvs',\n\t\t\ttvs: {\n\t\t\t\tterm: cnvTerm,\n\t\t\t\tvalues: [],\n\t\t\t\tcontinuousCnv: true,\n\t\t\t\tcnvGainCutoff: 99, // set to very high number to get samples with loss events\n\t\t\t\tcnvLossCutoff: -1,\n\t\t\t\tcnvMaxLength: null,\n\t\t\t\texcludeGeneName: true\n\t\t\t}\n\t\t}\n\t\t// heterozygous deletion tvs\n\t\tconst hetDel = {\n\t\t\ttype: 'tvs',\n\t\t\ttvs: {\n\t\t\t\tterm: cnvTerm,\n\t\t\t\tvalues: [],\n\t\t\t\tcontinuousCnv: true,\n\t\t\t\tcnvGainCutoff: 99, // set to very high number to get samples with loss events\n\t\t\t\tcnvLossCutoff: -0.3,\n\t\t\t\tcnvMaxLength: null,\n\t\t\t\texcludeGeneName: true\n\t\t\t}\n\t\t}\n\t\t// homozygous mutated tvs\n\t\tconst mutatedValues = Object.entries(snvIndelTerm.values)\n\t\t\t.filter(([k, _v]) => k != 'Intron' && k != 'Utr3')\n\t\t\t.map(([k, v]: any) => {\n\t\t\t\treturn { key: k, label: v.label, value: k }\n\t\t\t})\n\t\tconst homoMut = {\n\t\t\ttype: 'tvs',\n\t\t\ttvs: {\n\t\t\t\tterm: snvIndelTerm,\n\t\t\t\tvalues: mutatedValues,\n\t\t\t\tgenotype: 'variant',\n\t\t\t\tmcount: 'any',\n\t\t\t\tmafFilter: getMafFilter('homo', vocabApi),\n\t\t\t\texcludeGeneName: true\n\t\t\t}\n\t\t}\n\t\t// heterozygous mutated tvs\n\t\tconst hetMut = {\n\t\t\ttype: 'tvs',\n\t\t\ttvs: {\n\t\t\t\tterm: snvIndelTerm,\n\t\t\t\tvalues: mutatedValues,\n\t\t\t\tgenotype: 'variant',\n\t\t\t\tmcount: 'all',\n\t\t\t\tmafFilter: getMafFilter('het', vocabApi),\n\t\t\t\texcludeGeneName: true\n\t\t\t}\n\t\t}\n\n\t\t// build bi-allelic and mono-allelic groups\n\t\tconst biallelicGroup: any = {\n\t\t\tname: 'Bi-allelic alteration',\n\t\t\ttype: 'filter',\n\t\t\tfilter: {\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tin: true,\n\t\t\t\tjoin: 'or',\n\t\t\t\tlst: [\n\t\t\t\t\thomoDel,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\t\tin: true,\n\t\t\t\t\t\tjoin: 'and',\n\t\t\t\t\t\tlst: [hetDel, hetMut]\n\t\t\t\t\t},\n\t\t\t\t\thomoMut\n\t\t\t\t]\n\t\t\t},\n\t\t\tcolor: '#d10000'\n\t\t}\n\t\tconst monoallelicGroup: any = {\n\t\t\tname: 'Mono-allelic alteration',\n\t\t\ttype: 'filter',\n\t\t\tfilter: {\n\t\t\t\ttype: 'tvslst',\n\t\t\t\tin: true,\n\t\t\t\tjoin: 'or',\n\t\t\t\tlst: [hetDel, hetMut]\n\t\t\t},\n\t\t\tcolor: '#7489d2'\n\t\t}\n\n\t\t// build groupset\n\t\tconst groupset: any = {\n\t\t\tname: 'Bi-/mono-allelic',\n\t\t\tgroups: [biallelicGroup, monoallelicGroup]\n\t\t}\n\n\t\tterm.groupsetting.lst.push(groupset)\n\t}\n}\n\n// determine if term/dataset is eligible for building bi-allelic vs. mono-allelic groupset\nexport function isEligibleForAllelicGroupset(term: RawGvTerm, vocabApi: VocabApi): boolean {\n\tconst queries = vocabApi.termdbConfig.queries\n\tif (!queries || !queries.snvindel || !queries.cnv) return false // dataset must have snvindel and cnv data\n\tif (!queries.snvindel?.mafFilter) return false // dataset must have a maf filter\n\tif (!('cnvGainCutoff' in queries.cnv) && !('cnvLossCutoff' in queries.cnv)) return false // cnv data must be continuous\n\tif (!term.childTerms) throw new Error('term.childTerms[] is missing')\n\tconst snvIndelTerm = term.childTerms.find(t => t.dt == dtsnvindel)\n\tconst cnvTerm = term.childTerms.find(t => t.dt == dtcnv)\n\tif (!snvIndelTerm || !cnvTerm) return false\n\tif (snvIndelTerm.origin || cnvTerm.origin) return false // different origins not supported (may support later)\n\treturn true\n}\n\n// build maf filter according to genotype (homozygous or heterozygous)\nfunction getMafFilter(genotype: string, vocabApi: any) {\n\tconst mafFilter = vocabApi.termdbConfig.queries.snvindel.mafFilter\n\tif (!mafFilter) throw new Error('mafFilter is missing')\n\tconst mafTerm = mafFilter.terms.find(t => t.default)\n\tif (!mafTerm) throw new Error('no default mafTerm found')\n\tif (genotype != 'homo' && genotype != 'het') throw new Error('unexpected genotype value')\n\n\tconst range =\n\t\tgenotype == 'homo'\n\t\t\t? {\n\t\t\t\t\tstart: 0.6,\n\t\t\t\t\tstartinclusive: true,\n\t\t\t\t\tstartunbounded: false,\n\t\t\t\t\tstopunbounded: true\n\t\t\t }\n\t\t\t: {\n\t\t\t\t\tstop: 0.6,\n\t\t\t\t\tstopinclusive: false,\n\t\t\t\t\tstartunbounded: true,\n\t\t\t\t\tstopunbounded: false\n\t\t\t }\n\n\treturn {\n\t\ttype: 'tvslst',\n\t\tjoin: '',\n\t\tin: true,\n\t\tlst: [\n\t\t\t{\n\t\t\t\ttype: 'tvs',\n\t\t\t\ttvs: {\n\t\t\t\t\tterm: mafTerm,\n\t\t\t\t\tranges: [range]\n\t\t\t\t}\n\t\t\t}\n\t\t]\n\t}\n}\n", "import type { TermWrapper } from '#types'\nimport type { TwOpts, TwBase } from './TwBase'\nimport { mayHydrateDictTwLst, get$id } from '#termsetting'\n// TODO: may convert these to dynamic imports\nimport { QualValues, QualPredefinedGS, QualCustomGS } from './qualitative.ts'\nimport { GvBase, GvValues, GvPredefinedGS, GvCustomGS } from './geneVariant.ts'\nimport { NumericBase, NumRegularBin, NumCustomBins, NumCont, NumSpline } from './numeric.ts'\nimport { CollectionBase, CollectionCont, CollectionQual } from './termCollection'\nimport * as tt from '#shared/terms.js'\n\nexport const routedTermTypes = new Set([\n\ttt.CATEGORICAL,\n\ttt.INTEGER,\n\ttt.FLOAT,\n\ttt.GENE_VARIANT,\n\ttt.GENE_EXPRESSION,\n\ttt.ISOFORM_EXPRESSION,\n\ttt.DATE,\n\ttt.METABOLITE_INTENSITY,\n\ttt.PROTEOME_ABUNDANCE,\n\ttt.SSGSEA,\n\ttt.SNP,\n\ttt.SINGLECELL_GENE_EXPRESSION,\n\ttt.SINGLECELL_CELLTYPE,\n\ttt.TERM_COLLECTION,\n\ttt.DNA_METHYLATION\n])\n\nexport type UseCase = {\n\ttarget: string\n\tdetail: string\n}\n\nexport type TwInitOpts = {\n\tuseCase?: UseCase\n}\n\nexport class TwRouter {\n\topts: any\n\n\tconstructor(opts) {\n\t\tthis.opts = opts\n\t}\n\n\tstatic init(tw: TermWrapper, opts: TwOpts = {}): TwBase {\n\t\tswitch (tw.type) {\n\t\t\tcase 'NumTWRegularBin':\n\t\t\t\treturn new NumRegularBin(tw, opts)\n\t\t\tcase 'NumTWCustomBin':\n\t\t\t\treturn new NumCustomBins(tw, opts)\n\t\t\tcase 'NumTWCont':\n\t\t\t\treturn new NumCont(tw, opts)\n\t\t\tcase 'NumTWSpline':\n\t\t\t\treturn new NumSpline(tw, opts)\n\n\t\t\tcase 'GvValuesTW':\n\t\t\t\treturn new GvValues(tw, opts)\n\t\t\tcase 'GvPredefinedGsTW':\n\t\t\t\treturn new GvPredefinedGS(tw, opts)\n\t\t\tcase 'GvCustomGsTW':\n\t\t\t\treturn new GvCustomGS(tw, opts)\n\n\t\t\tcase 'QualTWValues':\n\t\t\t\treturn new QualValues(tw, opts)\n\t\t\tcase 'QualTWPredefinedGS':\n\t\t\t\treturn new QualPredefinedGS(tw, opts)\n\t\t\tcase 'QualTWCustomGS':\n\t\t\t\treturn new QualCustomGS(tw, opts)\n\n\t\t\tcase 'TermCollectionTWCont':\n\t\t\t\treturn new CollectionCont(tw, opts)\n\t\t\tcase 'TermCollectionTWQual':\n\t\t\t\treturn new CollectionQual(tw, opts)\n\n\t\t\tdefault:\n\t\t\t\tthrow `unable to init(tw)`\n\t\t}\n\t}\n\n\tstatic async initRaw(rawTw /*: RawTW*/, opts: TwOpts = {}): Promise<TwBase> {\n\t\tconst tw = await TwRouter.fill(rawTw, opts)\n\t\tconst xtw = TwRouter.init(tw, opts)\n\t\tif (!xtw.$id) xtw.$id = await get$id(xtw.getMinCopy())\n\t\treturn xtw\n\t}\n\n\tstatic async fill(tw /*: RawTW*/, opts: TwOpts = {}): Promise<TermWrapper> {\n\t\tawait TwRouter.preprocess(tw, opts?.vocabApi)\n\t\tconst type = tw.term.type == 'float' || tw.term.type == 'integer' ? 'numeric' : tw.term.type\n\t\topts.defaultQ = opts.defaultQByTsHandler?.[type] || null\n\n\t\tswitch (tw.term.type) {\n\t\t\tcase 'categorical':\n\t\t\tcase tt.SINGLECELL_CELLTYPE:\n\t\t\tcase 'snp': {\n\t\t\t\tconst { QualitativeBase } = await import('./qualitative')\n\t\t\t\treturn await QualitativeBase.fill(tw, opts)\n\t\t\t}\n\n\t\t\tcase 'integer':\n\t\t\tcase 'float':\n\t\t\tcase 'geneExpression':\n\t\t\tcase 'isoformExpression':\n\t\t\tcase 'metaboliteIntensity':\n\t\t\tcase 'proteomeAbundance':\n\t\t\tcase 'date':\n\t\t\tcase 'ssGSEA':\n\t\t\tcase tt.SINGLECELL_GENE_EXPRESSION:\n\t\t\tcase 'dnaMethylation':\n\t\t\t\treturn await NumericBase.fill(tw, opts)\n\n\t\t\t// case 'condition':\n\t\t\t// \treturn\n\n\t\t\t// case 'survival':\n\t\t\t// \treturn\n\n\t\t\tcase 'geneVariant':\n\t\t\t\treturn await GvBase.fill(tw, opts)\n\n\t\t\tcase 'termCollection':\n\t\t\t\treturn await CollectionBase.fill(tw, opts)\n\n\t\t\tdefault:\n\t\t\t\tthrow `unrecognized tw.term?.type='${tw.term?.type}'`\n\t\t}\n\t}\n\n\t// can reuse this function to generate valid preprocessed tw\n\t// for term-type specific unit tests\n\tstatic async preprocess(tw /*: RawTW*/, vocabApi?: any) {\n\t\tconst keys = Object.keys(tw)\n\t\tif (!keys.length) throw `empty tw object`\n\t\tif (tw.id && !tw.term) {\n\t\t\t// for dev work, testing, and URLs, it's convenient to only specify tw.id for a dictionary tw,\n\t\t\t// must support creating a hydrated tw.term from a minimal dict tw\n\t\t\tawait mayHydrateDictTwLst([tw], vocabApi)\n\t\t\tdelete tw.id\n\t\t}\n\n\t\tif (!tw.q) tw.q = {}\n\t\tif (!tw.q.isAtomic) tw.q.isAtomic = true\n\t\tTwRouter.reshapeLegacyTw(tw)\n\t}\n\n\t// check for legacy tw structure that could be\n\t// present in old saved sessions\n\tstatic reshapeLegacyTw(tw) {\n\t\t// check for legacy q.groupsetting{}\n\t\tif (Object.keys(tw.q).includes('groupsetting')) {\n\t\t\tif (!tw.q.groupsetting.inuse) {\n\t\t\t\ttw.q.type = 'values'\n\t\t\t} else if (tw.q.type == 'predefined-groupset') {\n\t\t\t\ttw.q.predefined_groupset_idx = tw.q.groupsetting.predefined_groupset_idx\n\t\t\t} else if (tw.q.type == 'custom-groupset') {\n\t\t\t\ttw.q.customset = tw.q.groupsetting.customset\n\t\t\t} else {\n\t\t\t\tthrow 'invalid q.type'\n\t\t\t}\n\t\t\tdelete tw.q['groupsetting']\n\t\t}\n\t}\n}\n", "import type { QualQ, Q, RawValuesQ, RawGvQ, TermWrapper, RawTW, NumericQ, SnpsQ, Term } from '#types'\nimport type { VocabApi } from './types'\nimport { TwRouter, routedTermTypes, type TwBase } from '#tw'\n\n/*\n********************* EXPORTED\nfillTermWrapper()\n\tcall_fillTW\n\tmayValidateQmode\nset_hiddenvalues()\n*/\n\n// append the common ID substring,\n// so that the first characters of $id is more indexable\nconst idSuffix = `_ts_${(+new Date()).toString().slice(-8)}`\nlet $id = 0\n\nexport async function get$id(minTwCopy) {\n\tif (!minTwCopy) return <string>`${$id++}${idSuffix}`\n\tdelete minTwCopy.$id\n\tconst i = window.location.pathname == '/testrun.html' || window.location.pathname == '/puppet.html' ? '' : $id++\n\t// TODO: may need to distinguish between unique tw $id and id for caching server response\n\t// for now, just append unique $id++ to ensure unique $id\n\treturn await digestMessage(JSON.stringify(minTwCopy) + i)\n}\n\nconst encoder = new TextEncoder()\n\n// may replace with hash() helper from shared/utils\nexport async function digestMessage(message) {\n\tconst msgUint8 = encoder.encode(message) // encode as (utf-8) Uint8Array\n\tconst hashBuffer = await crypto.subtle.digest('SHA-1', msgUint8) // hash the message\n\tconst hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array\n\tconst hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string\n\treturn hexToBase64(hashHex).replace('=', '-') // shorten from 40 to 28 chars\n}\n\nfunction hexToBase64(hexStr) {\n\treturn btoa(\n\t\t[...hexStr].reduce(\n\t\t\t(acc, _, i) => (acc += !((i - 1) & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : ''),\n\t\t\t''\n\t\t)\n\t)\n}\n\nexport function getPillNameDefault(self, d: any) {\n\tif (!self.opts.abbrCutoff) return d.name\n\treturn d.name.length <= self.opts.abbrCutoff + 2\n\t\t? d.name\n\t\t: '<label title=\"' + d.name + '\">' + d.name.substring(0, self.opts.abbrCutoff) + '...' + '</label>'\n}\n\n/* For some plots that can have multiple terms of the same ID,\nbut with different q{}, we can assign and use $id to\ndisambiguate which tw data to update and associate with\na rendered element such as a pill or a matrix row\n\ntw: termWrapper = {id, term{}, q{}}\nvocabApi\ndefaultQByTsHandler{}\n\tsupply the optional default q{}\n\tvalue is { condition: {mode:'binary'}, ... }\n\twith term types as keys\n*/\n\ntype DefaultQByTsHandler = {\n\tcategorical?: QualQ\n\tnumeric?: NumericQ\n\tsnplst?: SnpsQ\n}\n\nexport async function fillTwLst(\n\ttwlst: RawTW[], //TwLst,\n\tvocabApi: VocabApi,\n\tdefaultQByTsHandler?: DefaultQByTsHandler\n): Promise<void> {\n\tawait mayHydrateDictTwLst(twlst, vocabApi)\n\tconst promises: Promise<TermWrapper | TwBase>[] = []\n\tfor (const tw of twlst) {\n\t\tpromises.push(fillTermWrapper(tw, vocabApi, defaultQByTsHandler))\n\t}\n\tawait Promise.all(promises)\n}\n\n// fill in tw.term{} from a dehydrated state\n// a dictionary tw can be simply expressed as {id:str} and this function will fill in the term object.\n// a non-dict term will always have a term object, so this function will not be applied to non-dict term\nexport async function mayHydrateDictTwLst(twlst: RawTW[], vocabApi: VocabApi) {\n\tconst ids: string[] = []\n\tfor (const tw of twlst) {\n\t\tif (tw.term) continue\n\t\tif (tw.id === undefined || tw.id === '') throw '.id is required'\n\t\tids.push(tw.id)\n\t}\n\tconst terms = ids.length ? await vocabApi.getTerms(ids) : {}\n\tfor (const id of ids) {\n\t\tif (!terms[id]) throw `missing dictionary term for id=${id}`\n\t\tfor (const tw of twlst) {\n\t\t\tif (tw.id && tw.id in terms) tw.term = terms[tw.id]\n\t\t}\n\t}\n}\n\n// add migrated tw fillers here, by term.type\n\nasync function mayUseTwRouterFill(\n\ttw: RawTW, //TermWrapper,\n\tvocabApi: VocabApi,\n\tdefaultQByTsHandler?: DefaultQByTsHandler\n): Promise<TermWrapper | false | TwBase> {\n\tif (!routedTermTypes.has(tw.term?.type || '')) return false\n\tif (tw.constructor.name != 'Object') return tw as TermWrapper\n\tconst xtw = await TwRouter.initRaw(tw, { vocabApi, defaultQByTsHandler })\n\n\t// NOTE: while the tw refactor is not done for all term types and q.types/modes,\n\t// there will be some code duplication between TwRouter and the legacy code;\n\t// the latter will be deleted once the refactor/migration is done\n\t// fill-in the tw argument since consumer code may not be expecting a returned tw\n\tObject.assign(tw, xtw)\n\tmayValidateQmode(tw)\n\t// // this should be moved to the term-type specific handler??\n\tif (!tw.$id) tw.$id = await get$id(vocabApi.getTwMinCopy(tw))\n\tif (tw.q) tw.q.isAtomic = true\n\t// safe to return the xtw, it's compatible with either\n\t// code that expects literal tw or class instance tw\n\treturn xtw\n}\n\nexport async function fillTermWrapper(\n\ttw: RawTW, //TermWrapper,\n\tvocabApi: VocabApi,\n\tdefaultQByTsHandler?: DefaultQByTsHandler\n): Promise<TermWrapper | TwBase> {\n\ttw.isAtomic = true\n\tif (!tw.term && tw.id) {\n\t\t// hydrate tw.term using tw.id\n\t\tawait mayHydrateDictTwLst([tw], vocabApi)\n\t}\n\n\tconst xtw = await mayUseTwRouterFill(tw, vocabApi, defaultQByTsHandler)\n\tif (xtw) return xtw\n\n\t// tw.id is no longer needed\n\tdelete tw.id\n\tif (!tw.q) (tw.q as any) = {} as any\n\t;(tw.q as any).isAtomic = true\n\t// check for legacy tw structure\n\tcheckLegacyTw(tw)\n\t// call term-type specific logic to fill tw\n\tawait call_fillTW(tw, vocabApi, defaultQByTsHandler)\n\tmayValidateQmode(tw)\n\t// compute $id after tw is filled\n\tif (!tw.$id) tw.$id = await get$id(vocabApi.getTwMinCopy(tw))\n\treturn tw as TermWrapper\n}\n\n// check for legacy tw structure that could be\n// present in old saved sessions\nfunction checkLegacyTw(tw) {\n\t// check for legacy q.groupsetting{}\n\tif (Object.keys(tw.q).includes('groupsetting')) {\n\t\tif (tw.q['groupsetting']['inuse']) {\n\t\t\tif (tw.q.type == 'predefined-groupset') {\n\t\t\t\ttw.q['predefined_groupset_idx'] = tw.q['groupsetting']['predefined_groupset_idx']\n\t\t\t} else if (tw.q.type == 'custom-groupset') {\n\t\t\t\ttw.q['customset'] = tw.q['groupsetting']['customset']\n\t\t\t} else {\n\t\t\t\tthrow 'invalid q.type'\n\t\t\t}\n\t\t} else {\n\t\t\ttw.q.type = 'values'\n\t\t}\n\t\tdelete tw.q['groupsetting']\n\t}\n}\n\nexport async function call_fillTW(tw: RawTW, vocabApi: VocabApi, defaultQByTsHandler?: DefaultQByTsHandler) {\n\t// repeating this logic from fillTermWrapper(), since call_fillTW() may be called directly\n\t// TODO: may deprecate call_fillTW() once all term types have been migrated to xtw\n\tif (await mayUseTwRouterFill(tw, vocabApi, defaultQByTsHandler)) return\n\n\tif (!tw.$id) tw.$id = await get$id(vocabApi.getTwMinCopy(tw))\n\tconst t = tw.term?.type || ''\n\tconst type = t == 'float' || t == 'integer' || t == 'date' ? 'numeric' : (t as string)\n\tlet _\n\tif (tw.term?.type) {\n\t\ttry {\n\t\t\t_ = await import(`./handlers/${type}.ts`)\n\t\t} catch (_e) {\n\t\t\tthrow `Type ${type} does not exist`\n\t\t}\n\t} else throw `Type not defined for ${JSON.stringify(tw)}`\n\tawait _.fillTW(tw, vocabApi, defaultQByTsHandler ? defaultQByTsHandler[type] : null)\n}\n\nfunction mayValidateQmode(tw: RawTW) {\n\tif (!tw.q) return\n\tif (!('mode' in tw.q)) {\n\t\t// at this stage q.mode is allowed to be missing and will not validate\n\t\treturn\n\t}\n\t// q.mode is set. here will validate\n\tif (typeof tw.q.mode != 'string') throw 'q.mode not string'\n\t// if (tw.q.mode == '') throw 'q.mode is empty string' //No longer required with typescript\n\t// handler code should implement term type-specific validations\n\t// e.g. to prevent cases such as mode=continuous for categorical term\n}\n\n// TODO: create and use a RawQ type that combines all raw q types\nexport function set_hiddenvalues(q: Q | RawValuesQ | RawGvQ, term: Term) {\n\tif (!q.hiddenValues) {\n\t\tq.hiddenValues = {}\n\t\t// by default, fill-in with uncomputable values\n\t\tif (term.values) {\n\t\t\tfor (const k in term.values) {\n\t\t\t\tif (term.values[k].uncomputable) q.hiddenValues[k] = 1\n\t\t\t}\n\t\t}\n\t}\n}\n", "export const balanced = (\n a: string | RegExp,\n b: string | RegExp,\n str: string,\n) => {\n const ma = a instanceof RegExp ? maybeMatch(a, str) : a\n const mb = b instanceof RegExp ? maybeMatch(b, str) : b\n\n const r = ma !== null && mb != null && range(ma, mb, str)\n\n return (\n r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + ma.length, r[1]),\n post: str.slice(r[1] + mb.length),\n }\n )\n}\n\nconst maybeMatch = (reg: RegExp, str: string) => {\n const m = str.match(reg)\n return m ? m[0] : null\n}\n\nexport const range = (\n a: string,\n b: string,\n str: string,\n): undefined | [number, number] => {\n let begs: number[],\n beg: number | undefined,\n left: number,\n right: number | undefined = undefined,\n result: undefined | [number, number]\n let ai = str.indexOf(a)\n let bi = str.indexOf(b, ai + 1)\n let i = ai\n\n if (ai >= 0 && bi > 0) {\n if (a === b) {\n return [ai, bi]\n }\n begs = []\n left = str.length\n\n while (i >= 0 && !result) {\n if (i === ai) {\n begs.push(i)\n ai = str.indexOf(a, i + 1)\n } else if (begs.length === 1) {\n const r = begs.pop()\n if (r !== undefined) result = [r, bi]\n } else {\n beg = begs.pop()\n if (beg !== undefined && beg < left) {\n left = beg\n right = bi\n }\n\n bi = str.indexOf(b, i + 1)\n }\n\n i = ai < bi && ai >= 0 ? ai : bi\n }\n\n if (begs.length && right !== undefined) {\n result = [left, right]\n }\n }\n\n return result\n}\n", "import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\nfunction numeric(str: string) {\n return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n return str\n .replace(slashPattern, escSlash)\n .replace(openPattern, escOpen)\n .replace(closePattern, escClose)\n .replace(commaPattern, escComma)\n .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n return str\n .replace(escSlashPattern, '\\\\')\n .replace(escOpenPattern, '{')\n .replace(escClosePattern, '}')\n .replace(escCommaPattern, ',')\n .replace(escPeriodPattern, '.')\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n if (!str) {\n return ['']\n }\n\n const parts: string[] = []\n const m = balanced('{', '}', str)\n\n if (!m) {\n return str.split(',')\n }\n\n const { pre, body, post } = m\n const p = pre.split(',')\n\n p[p.length - 1] += '{' + body + '}'\n const postParts = parseCommaParts(post)\n if (post.length) {\n ;(p[p.length - 1] as string) += postParts.shift()\n p.push.apply(p, postParts)\n }\n\n parts.push.apply(parts, p)\n\n return parts\n}\n\nexport type BraceExpansionOptions = {\n max?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n if (!str) {\n return []\n }\n\n const { max = EXPANSION_MAX } = options\n\n // I don't know why Bash 4.3 does this, but it does.\n // Anything starting with {} will have the first two bytes preserved\n // but *only* at the top level, so {},a}b will not expand to anything,\n // but a{},b}c will be expanded to [a}c,abc].\n // One could argue that this is a bug in Bash, but since the goal of\n // this module is to match Bash's rules, we escape a leading {}\n if (str.slice(0, 2) === '{}') {\n str = '\\\\{\\\\}' + str.slice(2)\n }\n\n return expand_(escapeBraces(str), max, true).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n return i <= y\n}\n\nfunction gte(i: number, y: number) {\n return i >= y\n}\n\nfunction expand_(str: string, max: number, isTop: boolean): string[] {\n /** @type {string[]} */\n const expansions: string[] = []\n\n const m = balanced('{', '}', str)\n if (!m) return [str]\n\n // no need to expand pre, since it is guaranteed to be free of brace-sets\n const pre = m.pre\n const post: string[] = m.post.length ? expand_(m.post, max, false) : ['']\n\n if (/\\$$/.test(m.pre)) {\n for (let k = 0; k < post.length && k < max; k++) {\n const expansion = pre + '{' + m.body + '}' + post[k]\n expansions.push(expansion)\n }\n } else {\n const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n m.body,\n )\n const isSequence = isNumericSequence || isAlphaSequence\n const isOptions = m.body.indexOf(',') >= 0\n if (!isSequence && !isOptions) {\n // {a},b}\n if (m.post.match(/,(?!,).*\\}/)) {\n str = m.pre + '{' + m.body + escClose + m.post\n return expand_(str, max, true)\n }\n return [str]\n }\n\n let n: string[]\n if (isSequence) {\n n = m.body.split(/\\.\\./)\n } else {\n n = parseCommaParts(m.body)\n if (n.length === 1 && n[0] !== undefined) {\n // x{{a,b}}y ==> x{a}y x{b}y\n n = expand_(n[0], max, false).map(embrace)\n //XXX is this necessary? Can't seem to hit it in tests.\n /* c8 ignore start */\n if (n.length === 1) {\n return post.map(p => m.pre + n[0] + p)\n }\n /* c8 ignore stop */\n }\n }\n\n // at this point, n is the parts, and we know it's not a comma set\n // with a single entry.\n let N: string[]\n\n if (isSequence && n[0] !== undefined && n[1] !== undefined) {\n const x = numeric(n[0])\n const y = numeric(n[1])\n const width = Math.max(n[0].length, n[1].length)\n let incr =\n n.length === 3 && n[2] !== undefined ?\n Math.max(Math.abs(numeric(n[2])), 1)\n : 1\n let test = lte\n const reverse = y < x\n if (reverse) {\n incr *= -1\n test = gte\n }\n const pad = n.some(isPadded)\n\n N = []\n\n for (let i = x; test(i, y); i += incr) {\n let c\n if (isAlphaSequence) {\n c = String.fromCharCode(i)\n if (c === '\\\\') {\n c = ''\n }\n } else {\n c = String(i)\n if (pad) {\n const need = width - c.length\n if (need > 0) {\n const z = new Array(need + 1).join('0')\n if (i < 0) {\n c = '-' + z + c.slice(1)\n } else {\n c = z + c\n }\n }\n }\n }\n N.push(c)\n }\n } else {\n N = []\n\n for (let j = 0; j < n.length; j++) {\n N.push.apply(N, expand_(n[j] as string, max, false))\n }\n }\n\n for (let j = 0; j < N.length; j++) {\n for (let k = 0; k < post.length && expansions.length < max; k++) {\n const expansion = pre + N[j] + post[k]\n if (!isTop || isSequence || expansion) {\n expansions.push(expansion)\n }\n }\n }\n }\n\n return expansions\n}\n", "const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: unknown) => void = (\n pattern: unknown,\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n", "// translate the various posix character classes into unicode properties\n// this works across all unicode locales\n\n// { <posix class>: [<translation>, /u flag required, negated]\nconst posixClasses: { [k: string]: [e: string, u: boolean, n?: boolean] } =\n {\n '[:alnum:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}', true],\n '[:alpha:]': ['\\\\p{L}\\\\p{Nl}', true],\n '[:ascii:]': ['\\\\x' + '00-\\\\x' + '7f', false],\n '[:blank:]': ['\\\\p{Zs}\\\\t', true],\n '[:cntrl:]': ['\\\\p{Cc}', true],\n '[:digit:]': ['\\\\p{Nd}', true],\n '[:graph:]': ['\\\\p{Z}\\\\p{C}', true, true],\n '[:lower:]': ['\\\\p{Ll}', true],\n '[:print:]': ['\\\\p{C}', true],\n '[:punct:]': ['\\\\p{P}', true],\n '[:space:]': ['\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f', true],\n '[:upper:]': ['\\\\p{Lu}', true],\n '[:word:]': ['\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}', true],\n '[:xdigit:]': ['A-Fa-f0-9', false],\n }\n\n// only need to escape a few things inside of brace expressions\n// escapes: [ \\ ] -\nconst braceEscape = (s: string) => s.replace(/[[\\]\\\\-]/g, '\\\\$&')\n// escape all regexp magic characters\nconst regexpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// everything has already been escaped, we just have to join\nconst rangesToString = (ranges: string[]): string => ranges.join('')\n\nexport type ParseClassResult = [\n src: string,\n uFlag: boolean,\n consumed: number,\n hasMagic: boolean,\n]\n\n// takes a glob string at a posix brace expression, and returns\n// an equivalent regular expression source, and boolean indicating\n// whether the /u flag needs to be applied, and the number of chars\n// consumed to parse the character class.\n// This also removes out of order ranges, and returns ($.) if the\n// entire class just no good.\nexport const parseClass = (\n glob: string,\n position: number,\n): ParseClassResult => {\n const pos = position\n /* c8 ignore start */\n if (glob.charAt(pos) !== '[') {\n throw new Error('not in a brace expression')\n }\n /* c8 ignore stop */\n const ranges: string[] = []\n const negs: string[] = []\n\n let i = pos + 1\n let sawStart = false\n let uflag = false\n let escaping = false\n let negate = false\n let endPos = pos\n let rangeStart = ''\n WHILE: while (i < glob.length) {\n const c = glob.charAt(i)\n if ((c === '!' || c === '^') && i === pos + 1) {\n negate = true\n i++\n continue\n }\n\n if (c === ']' && sawStart && !escaping) {\n endPos = i + 1\n break\n }\n\n sawStart = true\n if (c === '\\\\') {\n if (!escaping) {\n escaping = true\n i++\n continue\n }\n // escaped \\ char, fall through and treat like normal char\n }\n if (c === '[' && !escaping) {\n // either a posix class, a collation equivalent, or just a [\n for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {\n if (glob.startsWith(cls, i)) {\n // invalid, [a-[] is fine, but not [a-[:alpha]]\n if (rangeStart) {\n return ['$.', false, glob.length - pos, true]\n }\n i += cls.length\n if (neg) negs.push(unip)\n else ranges.push(unip)\n uflag = uflag || u\n continue WHILE\n }\n }\n }\n\n // now it's just a normal character, effectively\n escaping = false\n if (rangeStart) {\n // throw this range away if it's not valid, but others\n // can still match.\n if (c > rangeStart) {\n ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c))\n } else if (c === rangeStart) {\n ranges.push(braceEscape(c))\n }\n rangeStart = ''\n i++\n continue\n }\n\n // now might be the start of a range.\n // can be either c-d or c-] or c<more...>] or c] at this point\n if (glob.startsWith('-]', i + 1)) {\n ranges.push(braceEscape(c + '-'))\n i += 2\n continue\n }\n if (glob.startsWith('-', i + 1)) {\n rangeStart = c\n i += 2\n continue\n }\n\n // not the start of a range, just a single character\n ranges.push(braceEscape(c))\n i++\n }\n\n if (endPos < i) {\n // didn't see the end of the class, not a valid class,\n // but might still be valid as a literal match.\n return ['', false, 0, false]\n }\n\n // if we got no ranges and no negates, then we have a range that\n // cannot possibly match anything, and that poisons the whole glob\n if (!ranges.length && !negs.length) {\n return ['$.', false, glob.length - pos, true]\n }\n\n // if we got one positive range, and it's a single character, then that's\n // not actually a magic pattern, it's just that one literal character.\n // we should not treat that as \"magic\", we should just return the literal\n // character. [_] is a perfectly valid way to escape glob magic chars.\n if (\n negs.length === 0 &&\n ranges.length === 1 &&\n /^\\\\?.$/.test(ranges[0]) &&\n !negate\n ) {\n const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]\n return [regexpEscape(r), false, endPos - pos, false]\n }\n\n const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'\n const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'\n const comb =\n ranges.length && negs.length ? '(' + sranges + '|' + snegs + ')'\n : ranges.length ? sranges\n : snegs\n\n return [comb, uflag, endPos - pos, true]\n}\n", "import type { MinimatchOptions } from './index.js'\n\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then\n * square-bracket escapes are removed, but not backslash escapes.\n *\n * For example, it will turn the string `'[*]'` into `*`, but it will not\n * turn `'\\\\*'` into `'*'`, because `\\` is a path separator in\n * `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n *\n * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be\n * unescaped.\n */\n\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = true,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\])\\]/g, '$1$2')\n .replace(/\\\\([^/])/g, '$1')\n }\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\{}])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\{}])\\]/g, '$1$2')\n .replace(/\\\\([^/{}])/g, '$1')\n}\n", "// parse a single path portion\n\nimport { parseClass } from './brace-expressions.js'\nimport type { MinimatchOptions, MMRegExp } from './index.js'\nimport { unescape } from './unescape.js'\n\n// classes [] are handled by the parseClass method\n// for positive extglobs, we sub-parse the contents, and combine,\n// with the appropriate regexp close.\n// for negative extglobs, we sub-parse the contents, but then\n// have to include the rest of the pattern, then the parent, etc.,\n// as the thing that cannot be because RegExp negative lookaheads\n// are different from globs.\n//\n// So for example:\n// a@(i|w!(x|y)z|j)b => ^a(i|w((!?(x|y)zb).*)z|j)b$\n// 1 2 3 4 5 6 1 2 3 46 5 6\n//\n// Assembling the extglob requires not just the negated patterns themselves,\n// but also anything following the negative patterns up to the boundary\n// of the current pattern, plus anything following in the parent pattern.\n//\n//\n// So, first, we parse the string into an AST of extglobs, without turning\n// anything into regexps yet.\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y']}, 'z'], ['j']]}, 'b']\n//\n// Then, for all the negative extglobs, we append whatever comes after in\n// each parent as their tail\n//\n// ['a', {@ [['i'], ['w', {!['x', 'y'], 'z', 'b'}, 'z'], ['j']]}, 'b']\n//\n// Lastly, we turn each of these pieces into a regexp, and join\n//\n// v----- .* because there's more following,\n// v v otherwise, .+ because it must be\n// v v *something* there.\n// ['^a', {@ ['i', 'w(?:(!?(?:x|y).*zb$).*)z', 'j' ]}, 'b$']\n// copy what follows into here--^^^^^\n// ['^a', '(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)', 'b$']\n// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']\n\nexport type ExtglobType = '!' | '?' | '+' | '*' | '@'\nconst types = new Set<ExtglobType>(['!', '?', '+', '*', '@'])\nconst isExtglobType = (c: string | null): c is ExtglobType =>\n types.has(c as ExtglobType)\nconst isExtglobAST = (c: AST): c is AST & { type: ExtglobType } =>\n isExtglobType(c.type)\n\n// Map of which extglob types can adopt the children of a nested extglob\n//\n// anything but ! can adopt a matching type:\n// +(a|+(b|c)|d) => +(a|b|c|d)\n// *(a|*(b|c)|d) => *(a|b|c|d)\n// @(a|@(b|c)|d) => @(a|b|c|d)\n// ?(a|?(b|c)|d) => ?(a|b|c|d)\n//\n// * can adopt anything, because 0 or repetition is allowed\n// *(a|?(b|c)|d) => *(a|b|c|d)\n// *(a|+(b|c)|d) => *(a|b|c|d)\n// *(a|@(b|c)|d) => *(a|b|c|d)\n//\n// + can adopt @, because 1 or repetition is allowed\n// +(a|@(b|c)|d) => +(a|b|c|d)\n//\n// + and @ CANNOT adopt *, because 0 would be allowed\n// +(a|*(b|c)|d) => would match \"\", on *(b|c)\n// @(a|*(b|c)|d) => would match \"\", on *(b|c)\n//\n// + and @ CANNOT adopt ?, because 0 would be allowed\n// +(a|?(b|c)|d) => would match \"\", on ?(b|c)\n// @(a|?(b|c)|d) => would match \"\", on ?(b|c)\n//\n// ? can adopt @, because 0 or 1 is allowed\n// ?(a|@(b|c)|d) => ?(a|b|c|d)\n//\n// ? and @ CANNOT adopt * or +, because >1 would be allowed\n// ?(a|*(b|c)|d) => would match bbb on *(b|c)\n// @(a|*(b|c)|d) => would match bbb on *(b|c)\n// ?(a|+(b|c)|d) => would match bbb on +(b|c)\n// @(a|+(b|c)|d) => would match bbb on +(b|c)\n//\n// ! CANNOT adopt ! (nothing else can either)\n// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)\n//\n// ! can adopt @\n// !(a|@(b|c)|d) => !(a|b|c|d)\n//\n// ! CANNOT adopt *\n// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed\n//\n// ! CANNOT adopt +\n// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed\n//\n// ! CANNOT adopt ?\n// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match \"x\"\nconst adoptionMap = new Map<ExtglobType, ExtglobType[]>([\n ['!', ['@']],\n ['?', ['?', '@']],\n ['@', ['@']],\n ['*', ['*', '+', '?', '@']],\n ['+', ['+', '@']],\n])\n\n// nested extglobs that can be adopted in, but with the addition of\n// a blank '' element.\nconst adoptionWithSpaceMap = new Map<ExtglobType, ExtglobType[]>([\n ['!', ['?']],\n ['@', ['?']],\n ['+', ['?', '*']],\n])\n\n// union of the previous two maps\nconst adoptionAnyMap = new Map<ExtglobType, ExtglobType[]>([\n ['!', ['?', '@']],\n ['?', ['?', '@']],\n ['@', ['?', '@']],\n ['*', ['*', '+', '?', '@']],\n ['+', ['+', '@', '?', '*']],\n])\n\n// Extglobs that can take over their parent if they are the only child\n// the key is parent, value maps child to resulting extglob parent type\n// '@' is omitted because it's a special case. An `@` extglob with a single\n// member can always be usurped by that subpattern.\nconst usurpMap = new Map<\n ExtglobType,\n Map<ExtglobType | null, ExtglobType | null>\n>([\n ['!', new Map([['!', '@']])],\n [\n '?',\n new Map([\n ['*', '*'],\n ['+', '*'],\n ]),\n ],\n [\n '@',\n new Map([\n ['!', '!'],\n ['?', '?'],\n ['@', '@'],\n ['*', '*'],\n ['+', '+'],\n ]),\n ],\n [\n '+',\n new Map([\n ['?', '*'],\n ['*', '*'],\n ]),\n ],\n])\n\n// Patterns that get prepended to bind to the start of either the\n// entire string, or just a single path portion, to prevent dots\n// and/or traversal patterns, when needed.\n// Exts don't need the ^ or / bit, because the root binds that already.\nconst startNoTraversal = '(?!(?:^|/)\\\\.\\\\.?(?:$|/))'\nconst startNoDot = '(?!\\\\.)'\n\n// characters that indicate a start of pattern needs the \"no dots\" bit,\n// because a dot *might* be matched. ( is not in the list, because in\n// the case of a child extglob, it will handle the prevention itself.\nconst addPatternStart = new Set(['[', '.'])\n// cases where traversal is A-OK, no dot prevention needed\nconst justDots = new Set(['..', '.'])\nconst reSpecials = new Set('().*{}+?[]^$\\\\!')\nconst regExpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\n// any single thing other than /\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n// use + when we need to ensure that *something* matches, because the * is\n// the only thing in the path portion.\nconst starNoEmpty = qmark + '+?'\n\n// remove the \\ chars that we added if we end up doing a nonmagic compare\n// const deslash = (s: string) => s.replace(/\\\\(.)/g, '$1')\n\nlet ID = 0\nexport class AST {\n type: ExtglobType | null\n readonly #root: AST\n\n #hasMagic?: boolean\n #uflag: boolean = false\n #parts: (string | AST)[] = []\n #parent?: AST\n #parentIndex: number\n #negs: AST[]\n #filledNegs: boolean = false\n #options: MinimatchOptions\n #toString?: string\n // set to true if it's an extglob with no children\n // (which really means one child of '')\n #emptyExt: boolean = false\n id = ++ID\n\n get depth(): number {\n return (this.#parent?.depth ?? -1) + 1\n }\n\n [Symbol.for('nodejs.util.inspect.custom')]() {\n return {\n '@@type': 'AST',\n id: this.id,\n type: this.type,\n root: this.#root.id,\n parent: this.#parent?.id,\n depth: this.depth,\n partsLength: this.#parts.length,\n parts: this.#parts,\n }\n }\n\n constructor(\n type: ExtglobType | null,\n parent?: AST,\n options: MinimatchOptions = {},\n ) {\n this.type = type\n // extglobs are inherently magical\n if (type) this.#hasMagic = true\n this.#parent = parent\n this.#root = this.#parent ? this.#parent.#root : this\n this.#options = this.#root === this ? options : this.#root.#options\n this.#negs = this.#root === this ? [] : this.#root.#negs\n if (type === '!' && !this.#root.#filledNegs) this.#negs.push(this)\n this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0\n }\n\n get hasMagic(): boolean | undefined {\n /* c8 ignore start */\n if (this.#hasMagic !== undefined) return this.#hasMagic\n /* c8 ignore stop */\n for (const p of this.#parts) {\n if (typeof p === 'string') continue\n if (p.type || p.hasMagic) return (this.#hasMagic = true)\n }\n // note: will be undefined until we generate the regexp src and find out\n return this.#hasMagic\n }\n\n // reconstructs the pattern\n toString(): string {\n return (\n this.#toString !== undefined ? this.#toString\n : !this.type ?\n (this.#toString = this.#parts.map(p => String(p)).join(''))\n : (this.#toString =\n this.type +\n '(' +\n this.#parts.map(p => String(p)).join('|') +\n ')')\n )\n }\n\n #fillNegs() {\n /* c8 ignore start */\n if (this !== this.#root) throw new Error('should only call on root')\n if (this.#filledNegs) return this\n /* c8 ignore stop */\n\n // call toString() once to fill this out\n this.toString()\n this.#filledNegs = true\n let n: AST | undefined\n while ((n = this.#negs.pop())) {\n if (n.type !== '!') continue\n // walk up the tree, appending everthing that comes AFTER parentIndex\n let p: AST | undefined = n\n let pp = p.#parent\n while (pp) {\n for (\n let i = p.#parentIndex + 1;\n !pp.type && i < pp.#parts.length;\n i++\n ) {\n for (const part of n.#parts) {\n /* c8 ignore start */\n if (typeof part === 'string') {\n throw new Error('string part in extglob AST??')\n }\n /* c8 ignore stop */\n part.copyIn(pp.#parts[i])\n }\n }\n p = pp\n pp = p.#parent\n }\n }\n return this\n }\n\n push(...parts: (string | AST)[]) {\n for (const p of parts) {\n if (p === '') continue\n /* c8 ignore start */\n if (\n typeof p !== 'string' &&\n !(p instanceof AST && p.#parent === this)\n ) {\n throw new Error('invalid part: ' + p)\n }\n /* c8 ignore stop */\n this.#parts.push(p)\n }\n }\n\n toJSON() {\n const ret: unknown[] =\n this.type === null ?\n this.#parts\n .slice()\n .map(p => (typeof p === 'string' ? p : p.toJSON()))\n : [this.type, ...this.#parts.map(p => (p as AST).toJSON())]\n if (this.isStart() && !this.type) ret.unshift([])\n if (\n this.isEnd() &&\n (this === this.#root ||\n (this.#root.#filledNegs && this.#parent?.type === '!'))\n ) {\n ret.push({})\n }\n return ret\n }\n\n isStart(): boolean {\n if (this.#root === this) return true\n // if (this.type) return !!this.#parent?.isStart()\n if (!this.#parent?.isStart()) return false\n if (this.#parentIndex === 0) return true\n // if everything AHEAD of this is a negation, then it's still the \"start\"\n const p = this.#parent\n for (let i = 0; i < this.#parentIndex; i++) {\n const pp = p.#parts[i]\n if (!(pp instanceof AST && pp.type === '!')) {\n return false\n }\n }\n return true\n }\n\n isEnd(): boolean {\n if (this.#root === this) return true\n if (this.#parent?.type === '!') return true\n if (!this.#parent?.isEnd()) return false\n if (!this.type) return this.#parent?.isEnd()\n // if not root, it'll always have a parent\n /* c8 ignore start */\n const pl = this.#parent ? this.#parent.#parts.length : 0\n /* c8 ignore stop */\n return this.#parentIndex === pl - 1\n }\n\n copyIn(part: AST | string) {\n if (typeof part === 'string') this.push(part)\n else this.push(part.clone(this))\n }\n\n clone(parent: AST) {\n const c = new AST(this.type, parent)\n for (const p of this.#parts) {\n c.copyIn(p)\n }\n return c\n }\n\n static #parseAST(\n str: string,\n ast: AST,\n pos: number,\n opt: MinimatchOptions,\n extDepth: number,\n ): number {\n const maxDepth = opt.maxExtglobRecursion ?? 2\n let escaping = false\n let inBrace = false\n let braceStart = -1\n let braceNeg = false\n if (ast.type === null) {\n // outside of a extglob, append until we find a start\n let i = pos\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n // we don't have to check for adoption here, because that's\n // done at the other recursion point.\n const doRecurse =\n !opt.noext &&\n isExtglobType(c) &&\n str.charAt(i) === '(' &&\n extDepth <= maxDepth\n if (doRecurse) {\n ast.push(acc)\n acc = ''\n const ext = new AST(c, ast)\n i = AST.#parseAST(str, ext, i, opt, extDepth + 1)\n ast.push(ext)\n continue\n }\n acc += c\n }\n ast.push(acc)\n return i\n }\n\n // some kind of extglob, pos is at the (\n // find the next | or )\n let i = pos + 1\n let part = new AST(null, ast)\n const parts: AST[] = []\n let acc = ''\n while (i < str.length) {\n const c = str.charAt(i++)\n // still accumulate escapes at this point, but we do ignore\n // starts that are escaped\n if (escaping || c === '\\\\') {\n escaping = !escaping\n acc += c\n continue\n }\n\n if (inBrace) {\n if (i === braceStart + 1) {\n if (c === '^' || c === '!') {\n braceNeg = true\n }\n } else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {\n inBrace = false\n }\n acc += c\n continue\n } else if (c === '[') {\n inBrace = true\n braceStart = i\n braceNeg = false\n acc += c\n continue\n }\n\n const doRecurse =\n !opt.noext &&\n isExtglobType(c) &&\n str.charAt(i) === '(' &&\n /* c8 ignore start - the maxDepth is sufficient here */\n (extDepth <= maxDepth || (ast && ast.#canAdoptType(c)))\n /* c8 ignore stop */\n if (doRecurse) {\n const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1\n part.push(acc)\n acc = ''\n const ext = new AST(c, part)\n part.push(ext)\n i = AST.#parseAST(str, ext, i, opt, extDepth + depthAdd)\n continue\n }\n if (c === '|') {\n part.push(acc)\n acc = ''\n parts.push(part)\n part = new AST(null, ast)\n continue\n }\n if (c === ')') {\n if (acc === '' && ast.#parts.length === 0) {\n ast.#emptyExt = true\n }\n part.push(acc)\n acc = ''\n ast.push(...parts, part)\n return i\n }\n acc += c\n }\n\n // unfinished extglob\n // if we got here, it was a malformed extglob! not an extglob, but\n // maybe something else in there.\n ast.type = null\n ast.#hasMagic = undefined\n ast.#parts = [str.substring(pos - 1)]\n return i\n }\n\n #canAdoptWithSpace(child?: AST | string): child is AST & {\n type: null\n parts: [AST & { type: ExtglobType }]\n } {\n return this.#canAdopt(child, adoptionWithSpaceMap)\n }\n\n #canAdopt(\n child?: AST | string,\n map: Map<ExtglobType, ExtglobType[]> = adoptionMap,\n ): child is AST & {\n type: null\n parts: [AST & { type: ExtglobType }]\n } {\n if (\n !child ||\n typeof child !== 'object' ||\n child.type !== null ||\n child.#parts.length !== 1 ||\n this.type === null\n ) {\n return false\n }\n const gc = child.#parts[0]\n if (!gc || typeof gc !== 'object' || gc.type === null) {\n return false\n }\n return (this as AST & { type: ExtglobType }).#canAdoptType(\n gc.type,\n map,\n )\n }\n #canAdoptType(\n c: string,\n map: Map<ExtglobType, ExtglobType[]> = adoptionAnyMap,\n ): c is ExtglobType {\n return !!map.get(this.type as ExtglobType)?.includes(c as ExtglobType)\n }\n\n #adoptWithSpace(\n this: AST & { type: ExtglobType },\n child: AST & {\n type: null\n },\n index: number,\n ) {\n const gc = child.#parts[0] as AST & { type: ExtglobType }\n const blank = new AST(null, gc, this.options)\n blank.#parts.push('')\n gc.push(blank)\n this.#adopt(child, index)\n }\n\n #adopt(\n child: AST & {\n type: null\n },\n index: number,\n ) {\n const gc = child.#parts[0] as AST & { type: ExtglobType }\n this.#parts.splice(index, 1, ...gc.#parts)\n for (const p of gc.#parts) {\n if (typeof p === 'object') p.#parent = this\n }\n this.#toString = undefined\n }\n\n #canUsurpType(c: string): boolean {\n const m = usurpMap.get(this.type as ExtglobType)\n return !!m?.has(c as ExtglobType)\n }\n\n #canUsurp(child?: AST | string): child is AST & {\n type: null\n parts: [AST & { type: ExtglobType }]\n } {\n if (\n !child ||\n typeof child !== 'object' ||\n child.type !== null ||\n child.#parts.length !== 1 ||\n this.type === null ||\n this.#parts.length !== 1\n ) {\n return false\n }\n const gc = child.#parts[0]\n if (!gc || typeof gc !== 'object' || gc.type === null) {\n return false\n }\n return (this as AST & { type: ExtglobType }).#canUsurpType(gc.type)\n }\n\n #usurp(this: AST & { type: ExtglobType }, child: AST & { type: null }) {\n const m = usurpMap.get(this.type as ExtglobType)\n const gc = child.#parts[0] as AST & { type: ExtglobType }\n const nt = m?.get(gc.type)\n /* c8 ignore start - impossible */\n if (!nt) return false\n /* c8 ignore stop */\n this.#parts = gc.#parts\n for (const p of this.#parts) {\n if (typeof p === 'object') {\n p.#parent = this\n }\n }\n this.type = nt\n this.#toString = undefined\n this.#emptyExt = false\n }\n\n static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n const ast = new AST(null, undefined, options)\n AST.#parseAST(pattern, ast, 0, options, 0)\n return ast\n }\n\n // returns the regular expression if there's magic, or the unescaped\n // string if not.\n toMMPattern(): MMRegExp | string {\n // should only be called on root\n /* c8 ignore start */\n if (this !== this.#root) return this.#root.toMMPattern()\n /* c8 ignore stop */\n const glob = this.toString()\n const [re, body, hasMagic, uflag] = this.toRegExpSource()\n // if we're in nocase mode, and not nocaseMagicOnly, then we do\n // still need a regular expression if we have to case-insensitively\n // match capital/lowercase characters.\n const anyMagic =\n hasMagic ||\n this.#hasMagic ||\n (this.#options.nocase &&\n !this.#options.nocaseMagicOnly &&\n glob.toUpperCase() !== glob.toLowerCase())\n if (!anyMagic) {\n return body\n }\n\n const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '')\n return Object.assign(new RegExp(`^${re}$`, flags), {\n _src: re,\n _glob: glob,\n })\n }\n\n get options() {\n return this.#options\n }\n\n // returns the string match, the regexp source, whether there's magic\n // in the regexp (so a regular expression is required) and whether or\n // not the uflag is needed for the regular expression (for posix classes)\n // TODO: instead of injecting the start/end at this point, just return\n // the BODY of the regexp, along with the start/end portions suitable\n // for binding the start/end in either a joined full-path makeRe context\n // (where we bind to (^|/), or a standalone matchPart context (where\n // we bind to ^, and not /). Otherwise slashes get duped!\n //\n // In part-matching mode, the start is:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: ^(?!\\.\\.?$)\n // - if dots allowed or not possible: ^\n // - if dots possible and not allowed: ^(?!\\.)\n // end is:\n // - if not isEnd(): nothing\n // - else: $\n //\n // In full-path matching mode, we put the slash at the START of the\n // pattern, so start is:\n // - if first pattern: same as part-matching mode\n // - if not isStart(): nothing\n // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/))\n // - if dots allowed or not possible: /\n // - if dots possible and not allowed: /(?!\\.)\n // end is:\n // - if last pattern, same as part-matching mode\n // - else nothing\n //\n // Always put the (?:$|/) on negated tails, though, because that has to be\n // there to bind the end of the negated pattern portion, and it's easier to\n // just stick it in now rather than try to inject it later in the middle of\n // the pattern.\n //\n // We can just always return the same end, and leave it up to the caller\n // to know whether it's going to be used joined or in parts.\n // And, if the start is adjusted slightly, can do the same there:\n // - if not isStart: nothing\n // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$)\n // - if dots allowed or not possible: (?:/|^)\n // - if dots possible and not allowed: (?:/|^)(?!\\.)\n //\n // But it's better to have a simpler binding without a conditional, for\n // performance, so probably better to return both start options.\n //\n // Then the caller just ignores the end if it's not the first pattern,\n // and the start always gets applied.\n //\n // But that's always going to be $ if it's the ending pattern, or nothing,\n // so the caller can just attach $ at the end of the pattern when building.\n //\n // So the todo is:\n // - better detect what kind of start is needed\n // - return both flavors of starting pattern\n // - attach $ at the end of the pattern when creating the actual RegExp\n //\n // Ah, but wait, no, that all only applies to the root when the first pattern\n // is not an extglob. If the first pattern IS an extglob, then we need all\n // that dot prevention biz to live in the extglob portions, because eg\n // +(*|.x*) can match .xy but not .yx.\n //\n // So, return the two flavors if it's #root and the first child is not an\n // AST, otherwise leave it to the child AST to handle it, and there,\n // use the (?:^|/) style of start binding.\n //\n // Even simplified further:\n // - Since the start for a join is eg /(?!\\.) and the start for a part\n // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root\n // or start or whatever) and prepend ^ or / at the Regexp construction.\n toRegExpSource(\n allowDot?: boolean,\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n const dot = allowDot ?? !!this.#options.dot\n if (this.#root === this) {\n this.#flatten()\n this.#fillNegs()\n }\n if (!isExtglobAST(this)) {\n const noEmpty =\n this.isStart() &&\n this.isEnd() &&\n !this.#parts.some(s => typeof s !== 'string')\n const src = this.#parts\n .map(p => {\n const [re, _, hasMagic, uflag] =\n typeof p === 'string' ?\n AST.#parseGlob(p, this.#hasMagic, noEmpty)\n : p.toRegExpSource(allowDot)\n this.#hasMagic = this.#hasMagic || hasMagic\n this.#uflag = this.#uflag || uflag\n return re\n })\n .join('')\n\n let start = ''\n if (this.isStart()) {\n if (typeof this.#parts[0] === 'string') {\n // this is the string that will match the start of the pattern,\n // so we need to protect against dots and such.\n\n // '.' and '..' cannot match unless the pattern is that exactly,\n // even if it starts with . or dot:true is set.\n const dotTravAllowed =\n this.#parts.length === 1 && justDots.has(this.#parts[0])\n if (!dotTravAllowed) {\n const aps = addPatternStart\n // check if we have a possibility of matching . or ..,\n // and prevent that.\n const needNoTrav =\n // dots are allowed, and the pattern starts with [ or .\n (dot && aps.has(src.charAt(0))) ||\n // the pattern starts with \\., and then [ or .\n (src.startsWith('\\\\.') && aps.has(src.charAt(2))) ||\n // the pattern starts with \\.\\., and then [ or .\n (src.startsWith('\\\\.\\\\.') && aps.has(src.charAt(4)))\n // no need to prevent dots if it can't match a dot, or if a\n // sub-pattern will be preventing it anyway.\n const needNoDot = !dot && !allowDot && aps.has(src.charAt(0))\n\n start =\n needNoTrav ? startNoTraversal\n : needNoDot ? startNoDot\n : ''\n }\n }\n }\n\n // append the \"end of path portion\" pattern to negation tails\n let end = ''\n if (\n this.isEnd() &&\n this.#root.#filledNegs &&\n this.#parent?.type === '!'\n ) {\n end = '(?:$|\\\\/)'\n }\n const final = start + src + end\n return [\n final,\n unescape(src),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n // We need to calculate the body *twice* if it's a repeat pattern\n // at the start, once in nodot mode, then again in dot mode, so a\n // pattern like *(?) can match 'x.y'\n\n const repeated = this.type === '*' || this.type === '+'\n // some kind of extglob\n const start = this.type === '!' ? '(?:(?!(?:' : '(?:'\n let body = (this as AST & { type: ExtglobType }).#partsToRegExp(dot)\n\n if (this.isStart() && this.isEnd() && !body && this.type !== '!') {\n // invalid extglob, has to at least be *something* present, if it's\n // the entire path portion.\n const s = this.toString()\n const me = this as AST\n me.#parts = [s]\n me.type = null\n me.#hasMagic = undefined\n return [s, unescape(this.toString()), false, false]\n }\n\n let bodyDotAllowed =\n !repeated || allowDot || dot || !startNoDot ?\n ''\n : this.#partsToRegExp(true)\n if (bodyDotAllowed === body) {\n bodyDotAllowed = ''\n }\n if (bodyDotAllowed) {\n body = `(?:${body})(?:${bodyDotAllowed})*?`\n }\n\n // an empty !() is exactly equivalent to a starNoEmpty\n let final = ''\n if (this.type === '!' && this.#emptyExt) {\n final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty\n } else {\n const close =\n this.type === '!' ?\n // !() must match something,but !(x) can match ''\n '))' +\n (this.isStart() && !dot && !allowDot ? startNoDot : '') +\n star +\n ')'\n : this.type === '@' ? ')'\n : this.type === '?' ? ')?'\n : this.type === '+' && bodyDotAllowed ? ')'\n : this.type === '*' && bodyDotAllowed ? `)?`\n : `)${this.type}`\n final = start + body + close\n }\n return [\n final,\n unescape(body),\n (this.#hasMagic = !!this.#hasMagic),\n this.#uflag,\n ]\n }\n\n #flatten() {\n if (!isExtglobAST(this)) {\n for (const p of this.#parts) {\n if (typeof p === 'object') {\n p.#flatten()\n }\n }\n } else {\n // do up to 10 passes to flatten as much as possible\n let iterations = 0\n let done = false\n do {\n done = true\n for (let i = 0; i < this.#parts.length; i++) {\n const c = this.#parts[i]\n if (typeof c === 'object') {\n c.#flatten()\n if (this.#canAdopt(c)) {\n done = false\n this.#adopt(c, i)\n } else if (this.#canAdoptWithSpace(c)) {\n done = false\n ;(this as AST & { type: ExtglobType }).#adoptWithSpace(c, i)\n } else if (this.#canUsurp(c)) {\n done = false\n ;(this as AST & { type: ExtglobType }).#usurp(c)\n }\n }\n }\n } while (!done && ++iterations < 10)\n }\n this.#toString = undefined\n }\n\n #partsToRegExp(this: AST & { type: ExtglobType }, dot: boolean) {\n return this.#parts\n .map(p => {\n // extglob ASTs should only contain parent ASTs\n /* c8 ignore start */\n if (typeof p === 'string') {\n throw new Error('string type in extglob ast??')\n }\n /* c8 ignore stop */\n // can ignore hasMagic, because extglobs are already always magic\n const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot)\n this.#uflag = this.#uflag || uflag\n return re\n })\n .filter(p => !(this.isStart() && this.isEnd()) || !!p)\n .join('|')\n }\n\n static #parseGlob(\n glob: string,\n hasMagic: boolean | undefined,\n noEmpty: boolean = false,\n ): [re: string, body: string, hasMagic: boolean, uflag: boolean] {\n let escaping = false\n let re = ''\n let uflag = false\n // multiple stars that aren't globstars coalesce into one *\n let inStar = false\n for (let i = 0; i < glob.length; i++) {\n const c = glob.charAt(i)\n if (escaping) {\n escaping = false\n re += (reSpecials.has(c) ? '\\\\' : '') + c\n continue\n }\n if (c === '*') {\n if (inStar) continue\n inStar = true\n re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star\n hasMagic = true\n continue\n } else {\n inStar = false\n }\n if (c === '\\\\') {\n if (i === glob.length - 1) {\n re += '\\\\\\\\'\n } else {\n escaping = true\n }\n continue\n }\n if (c === '[') {\n const [src, needUflag, consumed, magic] = parseClass(glob, i)\n if (consumed) {\n re += src\n uflag = uflag || needUflag\n i += consumed - 1\n hasMagic = hasMagic || magic\n continue\n }\n }\n if (c === '?') {\n re += qmark\n hasMagic = true\n continue\n }\n re += regExpEscape(c)\n }\n return [re, unescape(glob), !!hasMagic, uflag]\n }\n}\n", "import type { MinimatchOptions } from './index.js'\n\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n *\n * If the {@link MinimatchOptions.magicalBraces} option is used,\n * then braces (`{` and `}`) will be escaped.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]{}]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\{}]/g, '\\\\$&')\n }\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n", "import { expand } from 'brace-expansion'\nimport { assertValidPattern } from './assert-valid-pattern.js'\nimport type { ExtglobType } from './ast.js'\nimport { AST } from './ast.js'\nimport { escape } from './escape.js'\nimport { unescape } from './unescape.js'\n\nexport type Platform =\n | 'aix'\n | 'android'\n | 'darwin'\n | 'freebsd'\n | 'haiku'\n | 'linux'\n | 'openbsd'\n | 'sunos'\n | 'win32'\n | 'cygwin'\n | 'netbsd'\n\nexport interface MinimatchOptions {\n /** do not expand `{x,y}` style braces */\n nobrace?: boolean\n /** do not treat patterns starting with `#` as a comment */\n nocomment?: boolean\n /** do not treat patterns starting with `!` as a negation */\n nonegate?: boolean\n /** print LOTS of debugging output */\n debug?: boolean\n /** treat `**` the same as `*` */\n noglobstar?: boolean\n /** do not expand extglobs like `+(a|b)` */\n noext?: boolean\n /** return the pattern if nothing matches */\n nonull?: boolean\n /** treat `\\\\` as a path separator, not an escape character */\n windowsPathsNoEscape?: boolean\n /**\n * inverse of {@link MinimatchOptions.windowsPathsNoEscape}\n * @deprecated\n */\n allowWindowsEscape?: boolean\n /**\n * Compare a partial path to a pattern. As long as the parts\n * of the path that are present are not contradicted by the\n * pattern, it will be treated as a match. This is useful in\n * applications where you're walking through a folder structure,\n * and don't yet have the full path, but want to ensure that you\n * do not walk down paths that can never be a match.\n */\n partial?: boolean\n /** allow matches that start with `.` even if the pattern does not */\n dot?: boolean\n /** ignore case */\n nocase?: boolean\n /** ignore case only in wildcard patterns */\n nocaseMagicOnly?: boolean\n /** consider braces to be \"magic\" for the purpose of `hasMagic` */\n magicalBraces?: boolean\n /**\n * If set, then patterns without slashes will be matched\n * against the basename of the path if it contains slashes.\n * For example, `a?b` would match the path `/xyz/123/acb`, but\n * not `/xyz/acb/123`.\n */\n matchBase?: boolean\n /** invert the results of negated matches */\n flipNegate?: boolean\n /** do not collapse multiple `/` into a single `/` */\n preserveMultipleSlashes?: boolean\n /**\n * A number indicating the level of optimization that should be done\n * to the pattern prior to parsing and using it for matches.\n */\n optimizationLevel?: number\n /** operating system platform */\n platform?: Platform\n /**\n * When a pattern starts with a UNC path or drive letter, and in\n * `nocase:true` mode, do not convert the root portions of the\n * pattern into a case-insensitive regular expression, and instead\n * leave them as strings.\n *\n * This is the default when the platform is `win32` and\n * `nocase:true` is set.\n */\n windowsNoMagicRoot?: boolean\n /**\n * max number of `{...}` patterns to expand. Default 100_000.\n */\n braceExpandMax?: number\n /**\n * Max number of non-adjacent `**` patterns to recursively walk down.\n *\n * The default of 200 is almost certainly high enough for most purposes,\n * and can handle absurdly excessive patterns.\n */\n maxGlobstarRecursion?: number\n\n /**\n * Max depth to traverse for nested extglobs like `*(a|b|c)`\n *\n * Default is 2, which is quite low, but any higher value\n * swiftly results in punishing performance impacts. Note\n * that this is *not* relevant when the globstar types can\n * be safely coalesced into a single set.\n *\n * For example, `*(a|@(b|c)|d)` would be flattened into\n * `*(a|b|c|d)`. Thus, many common extglobs will retain good\n * performance and never hit this limit, even if they are\n * excessively deep and complicated.\n *\n * If the limit is hit, then the extglob characters are simply\n * not parsed, and the pattern effectively switches into\n * `noextglob: true` mode for the contents of that nested\n * sub-pattern. This will typically _not_ result in a match,\n * but is considered a valid trade-off for security and\n * performance.\n */\n maxExtglobRecursion?: number\n}\n\nexport const minimatch = (\n p: string,\n pattern: string,\n options: MinimatchOptions = {},\n) => {\n assertValidPattern(pattern)\n\n // shortcut: comments match nothing.\n if (!options.nocomment && pattern.charAt(0) === '#') {\n return false\n }\n\n return new Minimatch(pattern, options).match(p)\n}\n\n// Optimized checking for the most common glob patterns.\nconst starDotExtRE = /^\\*+([^+@!?*[(]*)$/\nconst starDotExtTest = (ext: string) => (f: string) =>\n !f.startsWith('.') && f.endsWith(ext)\nconst starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)\nconst starDotExtTestNocase = (ext: string) => {\n ext = ext.toLowerCase()\n return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)\n}\nconst starDotExtTestNocaseDot = (ext: string) => {\n ext = ext.toLowerCase()\n return (f: string) => f.toLowerCase().endsWith(ext)\n}\nconst starDotStarRE = /^\\*+\\.\\*+$/\nconst starDotStarTest = (f: string) =>\n !f.startsWith('.') && f.includes('.')\nconst starDotStarTestDot = (f: string) =>\n f !== '.' && f !== '..' && f.includes('.')\nconst dotStarRE = /^\\.\\*+$/\nconst dotStarTest = (f: string) =>\n f !== '.' && f !== '..' && f.startsWith('.')\nconst starRE = /^\\*+$/\nconst starTest = (f: string) => f.length !== 0 && !f.startsWith('.')\nconst starTestDot = (f: string) =>\n f.length !== 0 && f !== '.' && f !== '..'\nconst qmarksRE = /^\\?+([^+@!?*[(]*)?$/\nconst qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {\n const noext = qmarksTestNoExt([$0])\n if (!ext) return noext\n ext = ext.toLowerCase()\n return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {\n const noext = qmarksTestNoExtDot([$0])\n if (!ext) return noext\n ext = ext.toLowerCase()\n return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)\n}\nconst qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {\n const noext = qmarksTestNoExtDot([$0])\n return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {\n const noext = qmarksTestNoExt([$0])\n return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)\n}\nconst qmarksTestNoExt = ([$0]: RegExpMatchArray) => {\n const len = $0.length\n return (f: string) => f.length === len && !f.startsWith('.')\n}\nconst qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {\n const len = $0.length\n return (f: string) => f.length === len && f !== '.' && f !== '..'\n}\n\n/* c8 ignore start */\nconst defaultPlatform: Platform = (\n typeof process === 'object' && process ?\n (typeof process.env === 'object' &&\n process.env &&\n process.env.__MINIMATCH_TESTING_PLATFORM__) ||\n process.platform\n : 'posix') as Platform\n\nexport type Sep = '\\\\' | '/'\n\nconst path: { [k: string]: { sep: Sep } } = {\n win32: { sep: '\\\\' },\n posix: { sep: '/' },\n}\n/* c8 ignore stop */\n\nexport const sep =\n defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep\nminimatch.sep = sep\n\nexport const GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed. Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\/|^)\\\\.).)*?'\n\nexport const filter =\n (pattern: string, options: MinimatchOptions = {}) =>\n (p: string) =>\n minimatch(p, pattern, options)\nminimatch.filter = filter\n\nconst ext = (a: MinimatchOptions, b: MinimatchOptions = {}) =>\n Object.assign({}, a, b)\n\nexport const defaults = (def: MinimatchOptions): typeof minimatch => {\n if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n return minimatch\n }\n\n const orig = minimatch\n\n const m = (p: string, pattern: string, options: MinimatchOptions = {}) =>\n orig(p, pattern, ext(def, options))\n\n return Object.assign(m, {\n Minimatch: class Minimatch extends orig.Minimatch {\n constructor(pattern: string, options: MinimatchOptions = {}) {\n super(pattern, ext(def, options))\n }\n static defaults(options: MinimatchOptions) {\n return orig.defaults(ext(def, options)).Minimatch\n }\n },\n\n AST: class AST extends orig.AST {\n /* c8 ignore start */\n constructor(\n type: ExtglobType | null,\n parent?: AST,\n options: MinimatchOptions = {},\n ) {\n super(type, parent, ext(def, options))\n }\n /* c8 ignore stop */\n\n static fromGlob(pattern: string, options: MinimatchOptions = {}) {\n return orig.AST.fromGlob(pattern, ext(def, options))\n }\n },\n\n unescape: (\n s: string,\n options: Pick<\n MinimatchOptions,\n 'windowsPathsNoEscape' | 'magicalBraces'\n > = {},\n ) => orig.unescape(s, ext(def, options)),\n\n escape: (\n s: string,\n options: Pick<\n MinimatchOptions,\n 'windowsPathsNoEscape' | 'magicalBraces'\n > = {},\n ) => orig.escape(s, ext(def, options)),\n\n filter: (pattern: string, options: MinimatchOptions = {}) =>\n orig.filter(pattern, ext(def, options)),\n\n defaults: (options: MinimatchOptions) =>\n orig.defaults(ext(def, options)),\n\n makeRe: (pattern: string, options: MinimatchOptions = {}) =>\n orig.makeRe(pattern, ext(def, options)),\n\n braceExpand: (pattern: string, options: MinimatchOptions = {}) =>\n orig.braceExpand(pattern, ext(def, options)),\n\n match: (\n list: string[],\n pattern: string,\n options: MinimatchOptions = {},\n ) => orig.match(list, pattern, ext(def, options)),\n\n sep: orig.sep,\n GLOBSTAR: GLOBSTAR as typeof GLOBSTAR,\n })\n}\nminimatch.defaults = defaults\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nexport const braceExpand = (\n pattern: string,\n options: MinimatchOptions = {},\n) => {\n assertValidPattern(pattern)\n\n // Thanks to Yeting Li <https://github.com/yetingli> for\n // improving this regexp to avoid a ReDOS vulnerability.\n if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n // shortcut. no need to expand.\n return [pattern]\n }\n\n return expand(pattern, { max: options.braceExpandMax })\n}\nminimatch.braceExpand = braceExpand\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion. Otherwise, any series\n// of * is equivalent to a single *. Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\n\nexport const makeRe = (pattern: string, options: MinimatchOptions = {}) =>\n new Minimatch(pattern, options).makeRe()\nminimatch.makeRe = makeRe\n\nexport const match = (\n list: string[],\n pattern: string,\n options: MinimatchOptions = {},\n) => {\n const mm = new Minimatch(pattern, options)\n list = list.filter(f => mm.match(f))\n if (mm.options.nonull && !list.length) {\n list.push(pattern)\n }\n return list\n}\nminimatch.match = match\n\n// replace stuff like \\* with *\nconst globMagic = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/\nconst regExpEscape = (s: string) =>\n s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nexport type MMRegExp = RegExp & {\n _src?: string\n _glob?: string\n}\n\nexport type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR\nexport type ParseReturn = ParseReturnFiltered | false\n\nexport class Minimatch {\n options: MinimatchOptions\n set: ParseReturnFiltered[][]\n pattern: string\n\n windowsPathsNoEscape: boolean\n nonegate: boolean\n negate: boolean\n comment: boolean\n empty: boolean\n preserveMultipleSlashes: boolean\n partial: boolean\n globSet: string[]\n globParts: string[][]\n nocase: boolean\n\n isWindows: boolean\n platform: Platform\n windowsNoMagicRoot: boolean\n maxGlobstarRecursion: number\n\n regexp: false | null | MMRegExp\n constructor(pattern: string, options: MinimatchOptions = {}) {\n assertValidPattern(pattern)\n\n options = options || {}\n this.options = options\n this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200\n this.pattern = pattern\n this.platform = options.platform || defaultPlatform\n this.isWindows = this.platform === 'win32'\n // avoid the annoying deprecation flag lol\n const awe = ('allowWindow' + 'sEscape') as keyof MinimatchOptions\n this.windowsPathsNoEscape =\n !!options.windowsPathsNoEscape || options[awe] === false\n if (this.windowsPathsNoEscape) {\n this.pattern = this.pattern.replace(/\\\\/g, '/')\n }\n this.preserveMultipleSlashes = !!options.preserveMultipleSlashes\n this.regexp = null\n this.negate = false\n this.nonegate = !!options.nonegate\n this.comment = false\n this.empty = false\n this.partial = !!options.partial\n this.nocase = !!this.options.nocase\n this.windowsNoMagicRoot =\n options.windowsNoMagicRoot !== undefined ?\n options.windowsNoMagicRoot\n : !!(this.isWindows && this.nocase)\n\n this.globSet = []\n this.globParts = []\n this.set = []\n\n // make the set of regexps etc.\n this.make()\n }\n\n hasMagic(): boolean {\n if (this.options.magicalBraces && this.set.length > 1) {\n return true\n }\n for (const pattern of this.set) {\n for (const part of pattern) {\n if (typeof part !== 'string') return true\n }\n }\n return false\n }\n\n debug(..._: unknown[]) {}\n\n make() {\n const pattern = this.pattern\n const options = this.options\n\n // empty patterns and comments match nothing.\n if (!options.nocomment && pattern.charAt(0) === '#') {\n this.comment = true\n return\n }\n\n if (!pattern) {\n this.empty = true\n return\n }\n\n // step 1: figure out negation, etc.\n this.parseNegate()\n\n // step 2: expand braces\n this.globSet = [...new Set(this.braceExpand())]\n\n if (options.debug) {\n //oxlint-disable-next-line no-console\n this.debug = (...args: unknown[]) => console.error(...args)\n }\n\n this.debug(this.pattern, this.globSet)\n\n // step 3: now we have a set, so turn each one into a series of\n // path-portion matching patterns.\n // These will be regexps, except in the case of \"**\", which is\n // set to the GLOBSTAR object for globstar behavior,\n // and will not contain any / characters\n //\n // First, we preprocess to make the glob pattern sets a bit simpler\n // and deduped. There are some perf-killing patterns that can cause\n // problems with a glob walk, but we can simplify them down a bit.\n const rawGlobParts = this.globSet.map(s => this.slashSplit(s))\n this.globParts = this.preprocess(rawGlobParts)\n this.debug(this.pattern, this.globParts)\n\n // glob --> regexps\n let set = this.globParts.map((s, _, __) => {\n if (this.isWindows && this.windowsNoMagicRoot) {\n // check if it's a drive or unc path.\n const isUNC =\n s[0] === '' &&\n s[1] === '' &&\n (s[2] === '?' || !globMagic.test(s[2])) &&\n !globMagic.test(s[3])\n const isDrive = /^[a-z]:/i.test(s[0])\n if (isUNC) {\n return [\n ...s.slice(0, 4),\n ...s.slice(4).map(ss => this.parse(ss)),\n ]\n } else if (isDrive) {\n return [s[0], ...s.slice(1).map(ss => this.parse(ss))]\n }\n }\n return s.map(ss => this.parse(ss))\n })\n\n this.debug(this.pattern, set)\n\n // filter out everything that didn't compile properly.\n this.set = set.filter(\n s => s.indexOf(false) === -1,\n ) as ParseReturnFiltered[][]\n\n // do not treat the ? in UNC paths as magic\n if (this.isWindows) {\n for (let i = 0; i < this.set.length; i++) {\n const p = this.set[i]\n if (\n p[0] === '' &&\n p[1] === '' &&\n this.globParts[i][2] === '?' &&\n typeof p[3] === 'string' &&\n /^[a-z]:$/i.test(p[3])\n ) {\n p[2] = '?'\n }\n }\n }\n\n this.debug(this.pattern, this.set)\n }\n\n // various transforms to equivalent pattern sets that are\n // faster to process in a filesystem walk. The goal is to\n // eliminate what we can, and push all ** patterns as far\n // to the right as possible, even if it increases the number\n // of patterns that we have to process.\n preprocess(globParts: string[][]) {\n // if we're not in globstar mode, then turn ** into *\n if (this.options.noglobstar) {\n for (const partset of globParts) {\n for (let j = 0; j < partset.length; j++) {\n if (partset[j] === '**') {\n partset[j] = '*'\n }\n }\n }\n }\n\n const { optimizationLevel = 1 } = this.options\n\n if (optimizationLevel >= 2) {\n // aggressive optimization for the purpose of fs walking\n globParts = this.firstPhasePreProcess(globParts)\n globParts = this.secondPhasePreProcess(globParts)\n } else if (optimizationLevel >= 1) {\n // just basic optimizations to remove some .. parts\n globParts = this.levelOneOptimize(globParts)\n } else {\n // just collapse multiple ** portions into one\n globParts = this.adjascentGlobstarOptimize(globParts)\n }\n\n return globParts\n }\n\n // just get rid of adjascent ** portions\n adjascentGlobstarOptimize(globParts: string[][]) {\n return globParts.map(parts => {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let i = gs\n while (parts[i + 1] === '**') {\n i++\n }\n if (i !== gs) {\n parts.splice(gs, i - gs)\n }\n }\n return parts\n })\n }\n\n // get rid of adjascent ** and resolve .. portions\n levelOneOptimize(globParts: string[][]) {\n return globParts.map(parts => {\n parts = parts.reduce((set: string[], part) => {\n const prev = set[set.length - 1]\n if (part === '**' && prev === '**') {\n return set\n }\n if (part === '..') {\n if (prev && prev !== '..' && prev !== '.' && prev !== '**') {\n set.pop()\n return set\n }\n }\n set.push(part)\n return set\n }, [])\n return parts.length === 0 ? [''] : parts\n })\n }\n\n levelTwoFileOptimize(parts: string | string[]) {\n if (!Array.isArray(parts)) {\n parts = this.slashSplit(parts)\n }\n let didSomething: boolean = false\n\n do {\n didSomething = false\n // <pre>/<e>/<rest> -> <pre>/<rest>\n if (!this.preserveMultipleSlashes) {\n for (let i = 1; i < parts.length - 1; i++) {\n const p = parts[i]\n // don't squeeze out UNC patterns\n if (i === 1 && p === '' && parts[0] === '') continue\n if (p === '.' || p === '') {\n didSomething = true\n parts.splice(i, 1)\n i--\n }\n }\n if (\n parts[0] === '.' &&\n parts.length === 2 &&\n (parts[1] === '.' || parts[1] === '')\n ) {\n didSomething = true\n parts.pop()\n }\n }\n\n // <pre>/<p>/../<rest> -> <pre>/<rest>\n let dd: number = 0\n while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n const p = parts[dd - 1]\n if (\n p &&\n p !== '.' &&\n p !== '..' &&\n p !== '**' &&\n !(this.isWindows && /^[a-z]:$/i.test(p))\n ) {\n didSomething = true\n parts.splice(dd - 1, 2)\n dd -= 2\n }\n }\n } while (didSomething)\n return parts.length === 0 ? [''] : parts\n }\n\n // First phase: single-pattern processing\n // <pre> is 1 or more portions\n // <rest> is 1 or more portions\n // <p> is any portion other than ., .., '', or **\n // <e> is . or ''\n //\n // **/.. is *brutal* for filesystem walking performance, because\n // it effectively resets the recursive walk each time it occurs,\n // and ** cannot be reduced out by a .. pattern part like a regexp\n // or most strings (other than .., ., and '') can be.\n //\n // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}\n // <pre>/<e>/<rest> -> <pre>/<rest>\n // <pre>/<p>/../<rest> -> <pre>/<rest>\n // **/**/<rest> -> **/<rest>\n //\n // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow\n // this WOULD be allowed if ** did follow symlinks, or * didn't\n firstPhasePreProcess(globParts: string[][]) {\n let didSomething = false\n do {\n didSomething = false\n // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}\n for (let parts of globParts) {\n let gs: number = -1\n while (-1 !== (gs = parts.indexOf('**', gs + 1))) {\n let gss: number = gs\n while (parts[gss + 1] === '**') {\n // <pre>/**/**/<rest> -> <pre>/**/<rest>\n gss++\n }\n // eg, if gs is 2 and gss is 4, that means we have 3 **\n // parts, and can remove 2 of them.\n if (gss > gs) {\n parts.splice(gs + 1, gss - gs)\n }\n\n let next = parts[gs + 1]\n const p = parts[gs + 2]\n const p2 = parts[gs + 3]\n if (next !== '..') continue\n if (\n !p ||\n p === '.' ||\n p === '..' ||\n !p2 ||\n p2 === '.' ||\n p2 === '..'\n ) {\n continue\n }\n didSomething = true\n // edit parts in place, and push the new one\n parts.splice(gs, 1)\n const other = parts.slice(0)\n other[gs] = '**'\n globParts.push(other)\n gs--\n }\n\n // <pre>/<e>/<rest> -> <pre>/<rest>\n if (!this.preserveMultipleSlashes) {\n for (let i = 1; i < parts.length - 1; i++) {\n const p = parts[i]\n // don't squeeze out UNC patterns\n if (i === 1 && p === '' && parts[0] === '') continue\n if (p === '.' || p === '') {\n didSomething = true\n parts.splice(i, 1)\n i--\n }\n }\n if (\n parts[0] === '.' &&\n parts.length === 2 &&\n (parts[1] === '.' || parts[1] === '')\n ) {\n didSomething = true\n parts.pop()\n }\n }\n\n // <pre>/<p>/../<rest> -> <pre>/<rest>\n let dd: number = 0\n while (-1 !== (dd = parts.indexOf('..', dd + 1))) {\n const p = parts[dd - 1]\n if (p && p !== '.' && p !== '..' && p !== '**') {\n didSomething = true\n const needDot = dd === 1 && parts[dd + 1] === '**'\n const splin = needDot ? ['.'] : []\n parts.splice(dd - 1, 2, ...splin)\n if (parts.length === 0) parts.push('')\n dd -= 2\n }\n }\n }\n } while (didSomething)\n\n return globParts\n }\n\n // second phase: multi-pattern dedupes\n // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>\n // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>\n // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>\n //\n // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>\n // ^-- not valid because ** doens't follow symlinks\n secondPhasePreProcess(globParts: string[][]): string[][] {\n for (let i = 0; i < globParts.length - 1; i++) {\n for (let j = i + 1; j < globParts.length; j++) {\n const matched = this.partsMatch(\n globParts[i],\n globParts[j],\n !this.preserveMultipleSlashes,\n )\n if (matched) {\n globParts[i] = []\n globParts[j] = matched\n break\n }\n }\n }\n return globParts.filter(gs => gs.length)\n }\n\n partsMatch(\n a: string[],\n b: string[],\n emptyGSMatch: boolean = false,\n ): false | string[] {\n let ai = 0\n let bi = 0\n let result: string[] = []\n let which: string = ''\n while (ai < a.length && bi < b.length) {\n if (a[ai] === b[bi]) {\n result.push(which === 'b' ? b[bi] : a[ai])\n ai++\n bi++\n } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {\n result.push(a[ai])\n ai++\n } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {\n result.push(b[bi])\n bi++\n } else if (\n a[ai] === '*' &&\n b[bi] &&\n (this.options.dot || !b[bi].startsWith('.')) &&\n b[bi] !== '**'\n ) {\n if (which === 'b') return false\n which = 'a'\n result.push(a[ai])\n ai++\n bi++\n } else if (\n b[bi] === '*' &&\n a[ai] &&\n (this.options.dot || !a[ai].startsWith('.')) &&\n a[ai] !== '**'\n ) {\n if (which === 'a') return false\n which = 'b'\n result.push(b[bi])\n ai++\n bi++\n } else {\n return false\n }\n }\n // if we fall out of the loop, it means they two are identical\n // as long as their lengths match\n return a.length === b.length && result\n }\n\n parseNegate() {\n if (this.nonegate) return\n\n const pattern = this.pattern\n let negate = false\n let negateOffset = 0\n\n for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n negate = !negate\n negateOffset++\n }\n\n if (negateOffset) this.pattern = pattern.slice(negateOffset)\n this.negate = negate\n }\n\n // set partial to true to test if, for example,\n // \"/a/b\" matches the start of \"/*/b/*/d\"\n // Partial means, if you run out of file before you run\n // out of pattern, then that's fine, as long as all\n // the parts match.\n matchOne(\n file: string[],\n pattern: ParseReturn[],\n partial: boolean = false,\n ) {\n let fileStartIndex = 0\n let patternStartIndex = 0\n\n // UNC paths like //?/X:/... can match X:/... and vice versa\n // Drive letters in absolute drive or unc paths are always compared\n // case-insensitively.\n if (this.isWindows) {\n const fileDrive =\n typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0])\n const fileUNC =\n !fileDrive &&\n file[0] === '' &&\n file[1] === '' &&\n file[2] === '?' &&\n /^[a-z]:$/i.test(file[3])\n\n const patternDrive =\n typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0])\n const patternUNC =\n !patternDrive &&\n pattern[0] === '' &&\n pattern[1] === '' &&\n pattern[2] === '?' &&\n typeof pattern[3] === 'string' &&\n /^[a-z]:$/i.test(pattern[3])\n\n const fdi =\n fileUNC ? 3\n : fileDrive ? 0\n : undefined\n const pdi =\n patternUNC ? 3\n : patternDrive ? 0\n : undefined\n if (typeof fdi === 'number' && typeof pdi === 'number') {\n const [fd, pd]: [string, string] = [\n file[fdi],\n pattern[pdi] as string,\n ]\n // start matching at the drive letter index of each\n if (fd.toLowerCase() === pd.toLowerCase()) {\n pattern[pdi] = fd\n patternStartIndex = pdi\n fileStartIndex = fdi\n }\n }\n }\n\n // resolve and reduce . and .. portions in the file as well.\n // don't need to do the second phase, because it's only one string[]\n const { optimizationLevel = 1 } = this.options\n if (optimizationLevel >= 2) {\n file = this.levelTwoFileOptimize(file)\n }\n\n if (pattern.includes(GLOBSTAR)) {\n return this.#matchGlobstar(\n file,\n pattern,\n partial,\n fileStartIndex,\n patternStartIndex,\n )\n }\n\n return this.#matchOne(\n file,\n pattern,\n partial,\n fileStartIndex,\n patternStartIndex,\n )\n }\n\n #matchGlobstar(\n file: string[],\n pattern: ParseReturn[],\n partial: boolean,\n fileIndex: number,\n patternIndex: number,\n ) {\n // split the pattern into head, tail, and middle of ** delimited parts\n const firstgs = pattern.indexOf(GLOBSTAR, patternIndex)\n const lastgs = pattern.lastIndexOf(GLOBSTAR)\n\n // split the pattern up into globstar-delimited sections\n // the tail has to be at the end, and the others just have\n // to be found in order from the head.\n const [head, body, tail] =\n partial ?\n [\n pattern.slice(patternIndex, firstgs),\n pattern.slice(firstgs + 1),\n [],\n ]\n : [\n pattern.slice(patternIndex, firstgs),\n pattern.slice(firstgs + 1, lastgs),\n pattern.slice(lastgs + 1),\n ]\n\n // check the head, from the current file/pattern index.\n if (head.length) {\n const fileHead = file.slice(fileIndex, fileIndex + head.length)\n if (!this.#matchOne(fileHead, head, partial, 0, 0)) {\n return false\n }\n fileIndex += head.length\n patternIndex += head.length\n }\n // now we know the head matches!\n\n // if the last portion is not empty, it MUST match the end\n // check the tail\n let fileTailMatch: number = 0\n if (tail.length) {\n // if head + tail > file, then we cannot possibly match\n if (tail.length + fileIndex > file.length) return false\n\n // try to match the tail\n let tailStart = file.length - tail.length\n if (this.#matchOne(file, tail, partial, tailStart, 0)) {\n fileTailMatch = tail.length\n } else {\n // affordance for stuff like a/**/* matching a/b/\n // if the last file portion is '', and there's more to the pattern\n // then try without the '' bit.\n if (\n file[file.length - 1] !== '' ||\n fileIndex + tail.length === file.length\n ) {\n return false\n }\n tailStart--\n if (!this.#matchOne(file, tail, partial, tailStart, 0)) {\n return false\n }\n fileTailMatch = tail.length + 1\n }\n }\n\n // now we know the tail matches!\n\n // the middle is zero or more portions wrapped in **, possibly\n // containing more ** sections.\n // so a/**/b/**/c/**/d has become **/b/**/c/**\n // if it's empty, it means a/**/b, just verify we have no bad dots\n // if there's no tail, so it ends on /**, then we must have *something*\n // after the head, or it's not a matc\n if (!body.length) {\n let sawSome = !!fileTailMatch\n for (let i = fileIndex; i < file.length - fileTailMatch; i++) {\n const f = String(file[i])\n sawSome = true\n if (\n f === '.' ||\n f === '..' ||\n (!this.options.dot && f.startsWith('.'))\n ) {\n return false\n }\n }\n // in partial mode, we just need to get past all file parts\n return partial || sawSome\n }\n\n // now we know that there's one or more body sections, which can\n // be matched anywhere from the 0 index (because the head was pruned)\n // through to the length-fileTailMatch index.\n // split the body up into sections, and note the minimum index it can\n // be found at (start with the length of all previous segments)\n // [section, before, after]\n const bodySegments: [ParseReturn[], number][] = [[[], 0]]\n let currentBody: [ParseReturn[], number] = bodySegments[0]\n let nonGsParts = 0\n const nonGsPartsSums: number[] = [0]\n for (const b of body) {\n if (b === GLOBSTAR) {\n nonGsPartsSums.push(nonGsParts)\n currentBody = [[], 0]\n bodySegments.push(currentBody)\n } else {\n currentBody[0].push(b)\n nonGsParts++\n }\n }\n let i = bodySegments.length - 1\n const fileLength = file.length - fileTailMatch\n for (const b of bodySegments) {\n b[1] = fileLength - ((nonGsPartsSums[i--] as number) + b[0].length)\n }\n\n return !!this.#matchGlobStarBodySections(\n file,\n bodySegments,\n fileIndex,\n 0,\n partial,\n 0,\n !!fileTailMatch,\n )\n }\n\n // return false for \"nope, not matching\"\n // return null for \"not matching, cannot keep trying\"\n #matchGlobStarBodySections(\n file: string[],\n // pattern section, last possible position for it\n bodySegments: [ParseReturn[], number][],\n fileIndex: number,\n bodyIndex: number,\n partial: boolean,\n globStarDepth: number,\n sawTail: boolean,\n ): boolean | null {\n // take the first body segment, and walk from fileIndex to its \"after\"\n // value at the end\n // If it doesn't match at that position, we increment, until we hit\n // that final possible position, and give up.\n // If it does match, then advance and try to rest.\n // If any of them fail we keep walking forward.\n // this is still a bit recursively painful, but it's more constrained\n // than previous implementations, because we never test something that\n // can't possibly be a valid matching condition.\n const bs = bodySegments[bodyIndex]\n if (!bs) {\n // just make sure that there's no bad dots\n for (let i = fileIndex; i < file.length; i++) {\n sawTail = true\n const f = file[i]\n if (\n f === '.' ||\n f === '..' ||\n (!this.options.dot && f.startsWith('.'))\n ) {\n return false\n }\n }\n return sawTail\n }\n\n // have a non-globstar body section to test\n const [body, after] = bs\n while (fileIndex <= after) {\n const m = this.#matchOne(\n file.slice(0, fileIndex + body.length),\n body,\n partial,\n fileIndex,\n 0,\n )\n // if limit exceeded, no match. intentional false negative,\n // acceptable break in correctness for security.\n if (m && globStarDepth < this.maxGlobstarRecursion) {\n // match! see if the rest match. if so, we're done!\n const sub = this.#matchGlobStarBodySections(\n file,\n bodySegments,\n fileIndex + body.length,\n bodyIndex + 1,\n partial,\n globStarDepth + 1,\n sawTail,\n )\n if (sub !== false) {\n return sub\n }\n }\n const f = file[fileIndex]\n if (\n f === '.' ||\n f === '..' ||\n (!this.options.dot && f.startsWith('.'))\n ) {\n return false\n }\n\n fileIndex++\n }\n // walked off. no point continuing\n return partial || null\n }\n\n #matchOne(\n file: string[],\n pattern: ParseReturn[],\n partial: boolean,\n fileIndex: number,\n patternIndex: number,\n ) {\n let fi: number\n let pi: number\n let pl: number\n let fl: number\n for (\n fi = fileIndex,\n pi = patternIndex,\n fl = file.length,\n pl = pattern.length;\n fi < fl && pi < pl;\n fi++, pi++\n ) {\n this.debug('matchOne loop')\n let p = pattern[pi]\n let f = file[fi]\n\n this.debug(pattern, p, f)\n\n // should be impossible.\n // some invalid regexp stuff in the set.\n /* c8 ignore start */\n if (p === false || p === GLOBSTAR) {\n return false\n }\n /* c8 ignore stop */\n\n // something other than **\n // non-magic patterns just have to match exactly\n // patterns with magic have been turned into regexps.\n let hit: boolean\n if (typeof p === 'string') {\n hit = f === p\n this.debug('string match', p, f, hit)\n } else {\n hit = p.test(f)\n this.debug('pattern match', p, f, hit)\n }\n\n if (!hit) return false\n }\n\n // Note: ending in / means that we'll get a final \"\"\n // at the end of the pattern. This can only match a\n // corresponding \"\" at the end of the file.\n // If the file ends in /, then it can only match a\n // a pattern that ends in /, unless the pattern just\n // doesn't have any more for it. But, a/b/ should *not*\n // match \"a/b/*\", even though \"\" matches against the\n // [^/]*? pattern, except in partial mode, where it might\n // simply not be reached yet.\n // However, a/b/ should still satisfy a/*\n\n // now either we fell off the end of the pattern, or we're done.\n if (fi === fl && pi === pl) {\n // ran out of pattern and filename at the same time.\n // an exact hit!\n return true\n } else if (fi === fl) {\n // ran out of file, but still had pattern left.\n // this is ok if we're doing the match as part of\n // a glob fs traversal.\n return partial\n } else if (pi === pl) {\n // ran out of pattern, still have file left.\n // this is only acceptable if we're on the very last\n // empty segment of a file with a trailing slash.\n // a/* should match a/b/\n return fi === fl - 1 && file[fi] === ''\n\n /* c8 ignore start */\n } else {\n // should be unreachable.\n throw new Error('wtf?')\n }\n /* c8 ignore stop */\n }\n\n braceExpand() {\n return braceExpand(this.pattern, this.options)\n }\n\n parse(pattern: string): ParseReturn {\n assertValidPattern(pattern)\n\n const options = this.options\n\n // shortcuts\n if (pattern === '**') return GLOBSTAR\n if (pattern === '') return ''\n\n // far and away, the most common glob pattern parts are\n // *, *.*, and *.<ext> Add a fast check method for those.\n let m: RegExpMatchArray | null\n let fastTest: null | ((f: string) => boolean) = null\n if ((m = pattern.match(starRE))) {\n fastTest = options.dot ? starTestDot : starTest\n } else if ((m = pattern.match(starDotExtRE))) {\n fastTest = (\n options.nocase ?\n options.dot ?\n starDotExtTestNocaseDot\n : starDotExtTestNocase\n : options.dot ? starDotExtTestDot\n : starDotExtTest)(m[1])\n } else if ((m = pattern.match(qmarksRE))) {\n fastTest = (\n options.nocase ?\n options.dot ?\n qmarksTestNocaseDot\n : qmarksTestNocase\n : options.dot ? qmarksTestDot\n : qmarksTest)(m)\n } else if ((m = pattern.match(starDotStarRE))) {\n fastTest = options.dot ? starDotStarTestDot : starDotStarTest\n } else if ((m = pattern.match(dotStarRE))) {\n fastTest = dotStarTest\n }\n\n const re = AST.fromGlob(pattern, this.options).toMMPattern()\n if (fastTest && typeof re === 'object') {\n // Avoids overriding in frozen environments\n Reflect.defineProperty(re, 'test', { value: fastTest })\n }\n return re\n }\n\n makeRe() {\n if (this.regexp || this.regexp === false) return this.regexp\n\n // at this point, this.set is a 2d array of partial\n // pattern strings, or \"**\".\n //\n // It's better to use .match(). This function shouldn't\n // be used, really, but it's pretty convenient sometimes,\n // when you just want to work with a regex.\n const set = this.set\n\n if (!set.length) {\n this.regexp = false\n return this.regexp\n }\n const options = this.options\n\n const twoStar =\n options.noglobstar ? star\n : options.dot ? twoStarDot\n : twoStarNoDot\n const flags = new Set(options.nocase ? ['i'] : [])\n\n // regexpify non-globstar patterns\n // if ** is only item, then we just do one twoStar\n // if ** is first, and there are more, prepend (\\/|twoStar\\/)? to next\n // if ** is last, append (\\/twoStar|) to previous\n // if ** is in the middle, append (\\/|\\/twoStar\\/) to previous\n // then filter out GLOBSTAR symbols\n let re = set\n .map(pattern => {\n const pp: (string | typeof GLOBSTAR)[] = pattern.map(p => {\n if (p instanceof RegExp) {\n for (const f of p.flags.split('')) flags.add(f)\n }\n return (\n typeof p === 'string' ? regExpEscape(p)\n : p === GLOBSTAR ? GLOBSTAR\n : p._src\n )\n }) as (string | typeof GLOBSTAR)[]\n pp.forEach((p, i) => {\n const next = pp[i + 1]\n const prev = pp[i - 1]\n if (p !== GLOBSTAR || prev === GLOBSTAR) {\n return\n }\n if (prev === undefined) {\n if (next !== undefined && next !== GLOBSTAR) {\n pp[i + 1] = '(?:\\\\/|' + twoStar + '\\\\/)?' + next\n } else {\n pp[i] = twoStar\n }\n } else if (next === undefined) {\n pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + ')?'\n } else if (next !== GLOBSTAR) {\n pp[i - 1] = prev + '(?:\\\\/|\\\\/' + twoStar + '\\\\/)' + next\n pp[i + 1] = GLOBSTAR\n }\n })\n const filtered = pp.filter(p => p !== GLOBSTAR)\n\n // For partial matches, we need to make the pattern match\n // any prefix of the full path. We do this by generating\n // alternative patterns that match progressively longer prefixes.\n if (this.partial && filtered.length >= 1) {\n const prefixes: string[] = []\n for (let i = 1; i <= filtered.length; i++) {\n prefixes.push(filtered.slice(0, i).join('/'))\n }\n return '(?:' + prefixes.join('|') + ')'\n }\n\n return filtered.join('/')\n })\n .join('|')\n\n // need to wrap in parens if we had more than one thing with |,\n // otherwise only the first will be anchored to ^ and the last to $\n const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']\n // must match entire pattern\n // ending in a * or ** will make it less strict.\n re = '^' + open + re + close + '$'\n\n // In partial mode, '/' should always match as it's a valid prefix for any pattern\n if (this.partial) {\n re = '^(?:\\\\/|' + open + re.slice(1, -1) + close + ')$'\n }\n\n // can match anything, as long as it's not this.\n if (this.negate) re = '^(?!' + re + ').+$'\n\n try {\n this.regexp = new RegExp(re, [...flags].join(''))\n /* c8 ignore start */\n } catch {\n // should be impossible\n this.regexp = false\n }\n /* c8 ignore stop */\n return this.regexp\n }\n\n slashSplit(p: string) {\n // if p starts with // on windows, we preserve that\n // so that UNC paths aren't broken. Otherwise, any number of\n // / characters are coalesced into one, unless\n // preserveMultipleSlashes is set to true.\n if (this.preserveMultipleSlashes) {\n return p.split('/')\n } else if (this.isWindows && /^\\/\\/[^/]+/.test(p)) {\n // add an extra '' for the one we lose\n return ['', ...p.split(/\\/+/)]\n } else {\n return p.split(/\\/+/)\n }\n }\n\n match(f: string, partial = this.partial) {\n this.debug('match', f, this.pattern)\n // short-circuit in the case of busted things.\n // comments, etc.\n if (this.comment) {\n return false\n }\n if (this.empty) {\n return f === ''\n }\n\n if (f === '/' && partial) {\n return true\n }\n\n const options = this.options\n\n // windows: need to use /, not \\\n if (this.isWindows) {\n f = f.split('\\\\').join('/')\n }\n\n // treat the test path as a set of pathparts.\n const ff = this.slashSplit(f)\n this.debug(this.pattern, 'split', ff)\n\n // just ONE of the pattern sets in this.set needs to match\n // in order for it to be valid. If negating, then just one\n // match means that we have failed.\n // Either way, return on the first hit.\n\n const set = this.set\n this.debug(this.pattern, 'set', set)\n\n // Find the basename of the path by looking for the last non-empty segment\n let filename: string = ff[ff.length - 1]\n if (!filename) {\n for (let i = ff.length - 2; !filename && i >= 0; i--) {\n filename = ff[i]\n }\n }\n\n for (const pattern of set) {\n let file = ff\n if (options.matchBase && pattern.length === 1) {\n file = [filename]\n }\n const hit = this.matchOne(file, pattern, partial)\n if (hit) {\n if (options.flipNegate) {\n return true\n }\n return !this.negate\n }\n }\n\n // didn't get any hits. this is success if it's a negative\n // pattern, failure otherwise.\n if (options.flipNegate) {\n return false\n }\n return this.negate\n }\n\n static defaults(def: MinimatchOptions) {\n return minimatch.defaults(def).Minimatch\n }\n}\n/* c8 ignore start */\nexport { AST } from './ast.js'\nexport { escape } from './escape.js'\nexport { unescape } from './unescape.js'\n/* c8 ignore stop */\nminimatch.AST = AST\nminimatch.Minimatch = Minimatch\nminimatch.escape = escape\nminimatch.unescape = unescape\n", "import { select, type BaseType } from 'd3-selection'\nimport type { TermSetting } from './TermSetting.ts'\n\ntype TermsSettingViewOpts = {\n\ttermsetting: TermSetting\n}\n\nexport class TermSettingView {\n\ttermsetting: TermSetting\n\n\t_exitPill: (elem: HTMLElement) => void\n\t_updatePill: (elem: HTMLElement) => void\n\t_enterPill: (elem: HTMLElement) => void\n\n\tconstructor(opts: TermsSettingViewOpts) {\n\t\tthis.termsetting = opts.termsetting\n\t\tthis.initUI()\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst view = this\n\t\t// these methods are required to correctly handle the `this` == HTMLElement context as used by d3-selection,\n\t\t// while also keeping the `this` method reference to the view instance\n\t\tthis._exitPill = function (this: HTMLElement) {\n\t\t\tview.exitPill(this)\n\t\t}\n\t\tthis._updatePill = function (this: HTMLElement) {\n\t\t\tview.updatePill(this)\n\t\t}\n\t\tthis._enterPill = function (this: HTMLElement) {\n\t\t\tview.enterPill(this)\n\t\t}\n\t}\n\n\tinitUI() {\n\t\tconst self = this.termsetting\n\t\t// run only once, upon init\n\t\tif (self.opts.$id) {\n\t\t\tself.dom.tip.d.attr('id', self.opts.$id + '-ts-tip')\n\t\t}\n\n\t\tif (!self.dom.holder) return // toggle the display of pilldiv and nopilldiv with availability of this.term\n\t\tself.dom.holder.style('position', 'relative')\n\n\t\tself.dom.nopilldiv = self.dom.holder\n\t\t\t.append('div')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.on('click', event => self.actions.clickNoPillDiv(event))\n\t\t\t.on(`keyup.sjpp-termdb`, event => {\n\t\t\t\tif (event.key == 'Enter') self.api.showTree(self.dom.nopilldiv.node(), event)\n\t\t\t})\n\n\t\tself.dom.pilldiv = self.dom.holder.append('div')\n\n\t\tself.dom.loadingdiv = self.dom.holder\n\t\t\t.append('div')\n\t\t\t.style('display', 'none')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('max-width', '150px')\n\t\t\t.style('white-space', 'wrap')\n\t\t\t.style('vertical-align', 'top')\n\n\t\t// nopilldiv - placeholder label\n\t\tif (self.placeholder) {\n\t\t\tself.dom.nopilldiv\n\t\t\t\t.append('div')\n\t\t\t\t.html(self.placeholder)\n\t\t\t\t.attr('class', 'sja_clbtext2')\n\t\t\t\t.style('padding', '3px 6px 3px 6px')\n\t\t\t\t.style('display', 'inline-block')\n\t\t}\n\n\t\t// nopilldiv - plus button\n\t\tif (self.opts.placeholderIcon) {\n\t\t\t// margin & hover are applied so this icon looks identical to a pill without distracting visual diff on adding/removing tw; however the ts_pill class cannot be used for breaking termsetting ci test\n\t\t\tself.dom.nopilldiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_filter_tag_btn add_term_btn')\n\t\t\t\t.attr('data-testid', 'sjpp-tw-addTermBtn-' + (self.opts.testids?.suffix || ''))\n\t\t\t\t.style('padding', '3px 6px')\n\t\t\t\t.style('margin', '2px')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('border-radius', '6px')\n\t\t\t\t.text(self.opts.placeholderIcon)\n\t\t\t\t.on('mouseover', e => (e.target.style.opacity = 0.8))\n\t\t\t\t.on('mouseout', e => (e.target.style.opacity = 1))\n\t\t}\n\n\t\tself.dom.btnDiv = self.dom.holder.append('div')\n\t\tself.dom.content_holder = select(self.dom.holder.node().parentNode).append('div')\n\t}\n\n\tasync updateUI() {\n\t\tconst self = this.termsetting\n\n\t\tself.dom.btnDiv.selectAll('*').remove() //remove info button\n\t\tself.dom.content_holder.selectAll('*').remove() //remove info content\n\n\t\tif (!self.term) {\n\t\t\t// no term\n\t\t\tself.dom.nopilldiv.style('display', 'inline-block')\n\t\t\tself.dom.pilldiv.style('display', 'none')\n\t\t\tself.dom.btnDiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\n\t\t// has term\n\t\t// add info button for terms with meta data\n\t\tif (self.term.hashtmldetail) {\n\t\t\tif (self.opts.buttons && !self.opts.buttons.includes('info')) self.opts.buttons.unshift('info')\n\t\t\telse self.opts.buttons = ['info']\n\t\t} else {\n\t\t\tself.opts.buttons = []\n\t\t}\n\n\t\tif (self.opts.buttons.length) {\n\t\t\tself.dom.btnDiv\n\t\t\t\t.selectAll('div')\n\t\t\t\t.data(self.opts.buttons)\n\t\t\t\t.enter()\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('padding', '0px 5px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.style('color', '#999')\n\t\t\t\t.style('font-size', '.8em')\n\t\t\t\t.html((d: string) => d.toUpperCase())\n\t\t\t\t.on('click', (event: any, d: string) => {\n\t\t\t\t\tif (d == 'delete') self.actions.removeTerm()\n\t\t\t\t\telse if (d == 'replace') {\n\t\t\t\t\t\tself.api.showTree(event.target, event)\n\t\t\t\t\t} else throw 'unknown button'\n\t\t\t\t})\n\n\t\t\t// render info button only if term has html details\n\t\t\tif (self.term.hashtmldetail) {\n\t\t\t\tconst infoIcon_div = self.dom.btnDiv.selectAll('div').filter(function (this: BaseType) {\n\t\t\t\t\treturn select(this).text() === 'INFO'\n\t\t\t\t})\n\n\t\t\t\t// TODO: modify termInfoInit() to display term info in tip rather than in div\n\t\t\t\t// can be content_tip: self.dom.tip.d to separate it from content_holder\n\t\t\t\tconst termInfo = await import('../termdb/termInfo.js')\n\t\t\t\ttermInfo.termInfoInit({\n\t\t\t\t\tvocabApi: self.opts.vocabApi,\n\t\t\t\t\ticon_holder: infoIcon_div,\n\t\t\t\t\tcontent_holder: self.dom.content_holder,\n\t\t\t\t\tid: self.term.id,\n\t\t\t\t\tstate: { term: self.term }\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tself.dom.nopilldiv.style('display', 'none')\n\t\tself.dom.pilldiv.style('display', self.opts.buttons ? 'inline-block' : 'block')\n\t\tself.dom.btnDiv.style('display', self.opts.buttons ? 'inline-block' : 'none')\n\n\t\t//Gene expression terms do not have an id. Use the name if an id is not available.\n\t\tconst pills = self.dom.pilldiv.selectAll('.ts_pill').data([self.term], (d: any) => d.id || d.name)\n\n\t\t// this exit is really nice\n\t\tpills.exit().each(this._exitPill)\n\n\t\tpills.transition().duration(200).each(this._updatePill)\n\n\t\tpills\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'ts_pill')\n\t\t\t.style('display', 'grid')\n\t\t\t.style('grid-template-columns', 'auto')\n\t\t\t.style('grid-template-areas', '\"left right\"')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.style('margin', '2px')\n\t\t\t.on('click', (event, clickedElem, menuHolder) => self.api.showMenu(event, clickedElem, menuHolder))\n\t\t\t.transition()\n\t\t\t.duration(200)\n\t\t\t.each(this._enterPill)\n\t}\n\n\tenterPill(elem) {\n\t\tconst self = this.termsetting\n\t\tconst one_term_div = select(elem)\n\n\t\t// left half of blue pill\n\t\tself.dom.pill_termname = one_term_div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'term_name_btn sja_filter_tag_btn')\n\t\t\t.attr('data-testid', 'sjpp-tw-pillBtn-' + (self.opts.testids?.suffix || ''))\n\t\t\t.attr('tabindex', 0)\n\t\t\t.style('display', 'flex')\n\t\t\t.style('grid-area', 'left')\n\t\t\t.style('position', 'relative')\n\t\t\t.style('align-items', 'center')\n\t\t\t.style('padding', '3px 6px 3px 6px')\n\t\t\t.style('border-radius', '6px')\n\t\t\t.html(d => self.handler.getPillName(d))\n\t\t\t.on(`keyup.sjpp-termdb`, event => {\n\t\t\t\tif (event.key == 'Enter') event.target.click()\n\t\t\t})\n\n\t\tthis.updatePill(elem)\n\t}\n\n\tasync updatePill(elem) {\n\t\tconst self = this.termsetting\n\t\t// decide if to show/hide the right half based on term status, and modify pill\n\t\tconst one_term_div = select(elem)\n\n\t\tconst pillstat: { text: string; bgcolor?: string } = self.handler.getPillStatus() || { text: '' }\n\t\t// { text, bgcolor }\n\n\t\tself.dom.pill_termname\n\t\t\t.style('border-radius', pillstat.text ? '6px 0 0 6px' : '6px')\n\t\t\t.html(d => self.handler.getPillName(d))\n\n\t\tconst pill_settingSummary = one_term_div\n\t\t\t.selectAll('.ts_summary_btn')\n\t\t\t// bind d.txt to dom, is important in making sure the same text label won't trigger the dom update\n\t\t\t.data(pillstat.text ? [{ txt: pillstat.text }] : [], (d: any) => d.txt as string)\n\n\t\t// because of using d.txt of binding data, exitPill cannot be used here\n\t\t// as two different labels will create the undesirable effect of two right halves\n\t\tpill_settingSummary.exit().remove()\n\n\t\tconst righthalf = pill_settingSummary\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'ts_summary_btn sja_filter_tag_btn')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('grid-area', 'right')\n\t\t\t.style('position', 'relative')\n\t\t\t.style('align-items', 'center')\n\t\t\t.style('padding', '3px 6px 3px 6px')\n\t\t\t.style('border-radius', '0 6px 6px 0')\n\t\t\t.style('font-style', 'italic')\n\t\t\t.html((d: any) => d.txt)\n\t\t\t.style('opacity', 0)\n\t\t\t.transition()\n\t\t\t.duration(200)\n\t\t\t.style('opacity', 1)\n\n\t\tif (pillstat.bgcolor) {\n\t\t\trighthalf.transition().duration(200).style('background-color', pillstat.bgcolor)\n\t\t}\n\t}\n\n\texitPill(elem) {\n\t\tselect(elem).style('opacity', 1).transition().duration(this.termsetting.durations.exit).style('opacity', 0).remove()\n\t}\n}\n", "import type { TermSetting } from './TermSetting.ts'\nimport { Menu } from '#dom'\nimport { get$id } from './utils.ts'\n\nexport class TermSettingActions {\n\ttermsetting: TermSetting\n\n\tconstructor(opts) {\n\t\tthis.termsetting = opts.termsetting\n\t}\n\n\tremoveTerm() {\n\t\tthis.termsetting.opts.callback(null)\n\t}\n\n\tasync cancelGroupsetting() {\n\t\tconst self = this.termsetting\n\t\tself.opts.callback({\n\t\t\tid: self.term.id,\n\t\t\tterm: self.term,\n\t\t\tq: { mode: 'discrete', type: 'values', isAtomic: true }\n\t\t})\n\t}\n\n\tasync clickNoPillDiv(event) {\n\t\tconst self = this.termsetting\n\t\t// support various behaviors upon clicking nopilldiv\n\t\tif (!self.noTermPromptOptions || self.noTermPromptOptions.length == 0) {\n\t\t\t// show tree to select a dictionary term\n\t\t\tawait self.api.showTree(self.dom.nopilldiv.node(), event)\n\t\t\treturn\n\t\t}\n\t\tself.dom.tip.clear().showunder(self.dom.nopilldiv.node())\n\t\t// create small menu, one option for each ele in noTermPromptOptions[]\n\t\tconst optionTip = new Menu()\n\t\tfor (const option of self.noTermPromptOptions) {\n\t\t\t// {isDictionary, termtype, text, html, q{}}\n\t\t\tconst item = self.dom.tip.d\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t\t.on('click', async event => {\n\t\t\t\t\toptionTip.clear().hide()\n\t\t\t\t\tif (option.invalid) {\n\t\t\t\t\t\t// invalid option, display message\n\t\t\t\t\t\toptionTip\n\t\t\t\t\t\t\t.show(event.clientX, event.clientY)\n\t\t\t\t\t\t\t.d.append('div')\n\t\t\t\t\t\t\t.text(option.invalidMsg || '')\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tself.dom.tip.clear()\n\t\t\t\t\tif (option.isDictionary) {\n\t\t\t\t\t\tawait self.api.showTree(self.dom.tip.d.node(), event)\n\t\t\t\t\t} else if (option.termtype) {\n\t\t\t\t\t\t// pass in default q{} to customize settings in edit menu\n\t\t\t\t\t\tif (option.q) self.q = structuredClone(option.q)\n\t\t\t\t\t\tawait self.setHandler(option.termtype)\n\t\t\t\t\t\tif (!self.$id) self.$id = await get$id(self.vocabApi.getTwMinCopy({ term: self.term, q: self.q }))\n\t\t\t\t\t\tself.handler!.showEditMenu(self.dom.tip.d)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow 'termtype missing'\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\tif (option.text) item.text(option.text)\n\t\t\telse if (option.html) item.html(option.html)\n\t\t}\n\t\t// load the input ui for this term type\n\t}\n}\n\n// // do not consider irrelevant q attributes when\n// // computing the deep equality of two term.q's\n// function equivalentQs(q0: Q, q1: Q) {\n// \tconst qlst = [q0, q1].map(q => JSON.parse(JSON.stringify(q)))\n// \tfor (const q of qlst) {\n// \t\tdelete q.binLabelFormatter\n// \t\tif (q.reuseId === 'Default') delete q.reuseId\n// \t\t// TODO: may need to delete non-relevant q attributes\n// \t\t// when setting defaults in regression.inputs.term.js\n// \t\tif (q.mode === 'continuous') delete q.mode\n// \t\tif (q.mode === 'discrete' && q.type == 'custom-bin' && q.lst) {\n// \t\t\tfor (const bin of q.lst) {\n// \t\t\t\tdelete bin.range\n// \t\t\t}\n// \t\t}\n// \t}\n// \treturn deepEqual(qlst[0], qlst[1])\n// }\n", "import type {\n\tTermSettingOpts,\n\tPillData,\n\tUseCase,\n\tSampleCountsEntry,\n\tNoTermPromptOptsEntry,\n\tVocabApi,\n\tHandler\n} from './types'\nimport type { TermSettingApi } from './TermSettingApi.ts'\nimport type { Term, Filter, Q, TermWrapper } from '#types'\nimport { TwBase /*CatValues, CatPredefinedGS, CatCustomGS*/ } from '#tw'\nimport { Menu } from '#dom'\nimport { TermTypes, isDictionaryType } from '#shared/terms.js'\nimport { minimatch } from 'minimatch'\nimport { HandlerBase } from './HandlerBase.ts'\nimport { TermSettingView } from './TermSettingView.ts'\nimport { TermSettingActions } from './TermSettingActions.ts'\n\ntype MenuOptions = string // 'edit|replace|save|remove|reuse'\ntype MenuLayout = 'vertical' | 'horizontal'\ntype CustomMenuOptions = { label: string; callback: (tw: TermWrapper) => void }\n\nconst defaultOpts = {\n\tmenuOptions: 'edit' satisfies MenuOptions,\n\tmenuLayout: 'vertical' satisfies MenuLayout,\n\tcustomMenuOptions: [] satisfies CustomMenuOptions[]\n}\n\nexport class TermSetting {\n\topts: any // Required<TermSettingOpts>\n\tvocabApi: VocabApi\n\tdom: {\n\t\t[name: string]: any // d3-selection\n\t} // Dom //opts.holder is required\n\n\t//Optional opts, hence undefined type\n\tactiveCohort?: number\n\tplaceholder?: string\n\tdurations: { exit: number } = { exit: 0 }\n\tdisable_terms?: Term[] = []\n\tusecase?: UseCase\n\tabbrCutoff?: number\n\t$id?: string\n\tsampleCounts?: SampleCountsEntry[]\n\tnoTermPromptOptions?: NoTermPromptOptsEntry[]\n\n\t//Optional opts in script, not init()\n\tdoNotHideTipInMain: boolean = false\n\n\t//Created\n\thasError: boolean = false\n\tapi: TermSettingApi\n\tnumqByTermIdModeType: { [twId: string]: { [mode: string]: any /* should be numeric q */ } } = {}\n\n\t//tw: TermWrapper\n\tview: TermSettingView\n\tactions: TermSettingActions\n\n\thandler: Handler\n\thandlerByType: {\n\t\t[termType: string]: any // TODO: define handler api\n\t} = {}\n\t// showTree: any\n\t// showGeneSearch: any\n\t// showMenu: any\n\t// initUI: any\n\t// updateUI: any\n\n\t//Pill data\n\ttw!: TwBase //CatValues | CatPredefinedGS | CatCustomGS\n\tterm: any\n\tq!: Q\n\tdata: any\n\terror: string | undefined\n\tfilter: Filter | undefined\n\tgroups?: any\n\n\tconstructor(opts: TermSettingOpts) {\n\t\tthis.opts = this.validateOpts(opts)\n\t\tthis.api = opts.api\n\t\tthis.vocabApi = opts.vocabApi\n\t\tthis.dom = this.getDom(opts)\n\n\t\tthis.activeCohort = opts.activeCohort\n\t\tthis.placeholder = opts.placeholder as string\n\t\tthis.durations = { exit: 0 }\n\t\tthis.disable_terms = opts.disable_terms\n\t\tthis.usecase = opts.usecase\n\t\tthis.abbrCutoff = opts.abbrCutoff\n\t\t// default handler\n\t\tthis.handler = new HandlerBase({ termsetting: this })\n\t\tthis.handlerByType.default = this.handler\n\t\t//this.tw = opts.tw\n\t\tthis.actions = new TermSettingActions({ termsetting: this })\n\t\tthis.view = new TermSettingView({ termsetting: this })\n\t}\n\n\tvalidateOpts(_opts: TermSettingOpts) {\n\t\tconst o = {\n\t\t\t...defaultOpts,\n\t\t\t..._opts\n\t\t}\n\t\tif (!o.holder && o.renderAs != 'none') throw '.holder missing'\n\t\tif (typeof o.callback != 'function') throw '.callback() is not a function'\n\t\tif (!o.vocabApi) throw '.vocabApi missing'\n\t\tif (typeof o.vocabApi != 'object') throw '.vocabApi{} is not object'\n\t\tif ('placeholder' in o && !o.placeholder && 'placeholderIcon' in o && !o.placeholderIcon)\n\t\t\tthrow 'must specify a non-empty opts.placeholder and/or .placeholderIcon'\n\t\tif (!('placeholder' in o)) o.placeholder = 'Select term '\n\t\tif (!('placeholderIcon' in o)) o.placeholderIcon = '+'\n\t\tif (!Number.isInteger(o.abbrCutoff)) o.abbrCutoff = 18 //set the default to 18\n\t\tthis.validateMenuOptions(o)\n\t\tif (!o.numericEditMenuVersion) o.numericEditMenuVersion = ['discrete']\n\t\tthis.mayValidate_noTermPromptOptions(o)\n\t\treturn o\n\t}\n\n\tgetDom(opts) {\n\t\tconst tip =\n\t\t\topts.tip ||\n\t\t\tnew Menu({\n\t\t\t\tpadding: '0px',\n\t\t\t\tparent_menu: this.opts.holder && this.opts.holder.node() && this.opts.holder.node().closest('.sja_menu_div')\n\t\t\t})\n\n\t\treturn {\n\t\t\tholder: opts.holder,\n\t\t\ttip,\n\t\t\t// tip2 is for showing inside tip, e.g. in snplocus UI\n\t\t\ttip2: new Menu({\n\t\t\t\tpadding: '0px',\n\t\t\t\tparent_menu: tip.d.node()\n\t\t\t})\n\t\t}\n\t}\n\n\tvalidateMainData(d: PillData) {\n\t\tif (d.term) {\n\t\t\t// term is optional\n\t\t\tif (!d.term.type) throw 'data.term.type missing'\n\t\t\t// hardcode non\n\t\t\tif (isDictionaryType(d.term.type)) {\n\t\t\t\tif (!d.term.id && d.term.type != TermTypes.SAMPLELST && d.term.type != TermTypes.TERM_COLLECTION)\n\t\t\t\t\tthrow 'data.term.id missing'\n\t\t\t\tif (!d.term.name) throw 'data.term.name missing'\n\t\t\t}\n\t\t}\n\t\tif (!d.q) d.q = {}\n\t\tif (typeof d.q != 'object') throw 'data.q{} is not object'\n\t\tif (d.disable_terms) {\n\t\t\tif (!Array.isArray(d.disable_terms)) throw 'data.disable_terms[] is not array'\n\t\t}\n\t\tthis.mayValidate_noTermPromptOptions(d)\n\t}\n\n\tvalidateMenuOptions(o: TermSettingOpts) {\n\t\tif (!o.menuOptions) o.menuOptions = defaultOpts.menuOptions\n\t\t// support legacy options, now converted to use glob-style pattern matching\n\t\tif (o.menuOptions == 'all') o.menuOptions = '*'\n\t\t// skip reuse option\n\t\tfor (const opt of ['edit', /*'reuse',*/ 'replace', 'remove']) {\n\t\t\tif (minimatch(opt, o.menuOptions)) return // matched at least one menu option\n\t\t}\n\t\tthrow `no matches found for termsetting opts.menuOptions='${o.menuOptions}'`\n\t}\n\n\tmayValidate_noTermPromptOptions(o) {\n\t\t//: TermSettingOpts | PillData) {\n\t\tif (!o.noTermPromptOptions) return\n\t\tif (!Array.isArray(o.noTermPromptOptions)) throw 'noTermPromptOptions[] is not array'\n\t\t// allow empty array\n\t\tfor (const t of o.noTermPromptOptions) {\n\t\t\tif (t.isDictionary) {\n\t\t\t\t// allowed\n\t\t\t} else {\n\t\t\t\t// otherwise, must be a non-dict term type\n\t\t\t\tif (!t.termtype) throw 'element of noTermPromptOptions[] missing both isDictionary=true and .termtype'\n\t\t\t}\n\t\t\tif (!t.text && !t.html) throw 'element of noTermPromptOptions[] missing both .text and .html'\n\t\t\tif (t.q && typeof t.q != 'object') throw 'type.q{} is not object'\n\t\t}\n\t\tthis.noTermPromptOptions = o.noTermPromptOptions\n\t}\n\n\tasync setHandler(termtype: string | undefined | null, tw?: TermWrapper) {\n\t\tif (tw instanceof TwBase) {\n\t\t\tswitch (tw.type) {\n\t\t\t\tcase 'QualTWValues':\n\t\t\t\tcase 'QualTWPredefinedGS':\n\t\t\t\tcase 'QualTWCustomGS': {\n\t\t\t\t\t/* commenting out, otherwise may reuse handler with stale termsetting instance\n\t\t\t\t\t(e.g. categorical term as independent variable in regression -> apply groupsetting -> re-open edit menu -> incorrect groupsetting\n\t\t\t\t\tbecause getGroups() from QualValues is used instead of getGroups() from QualCustomGS)\n\t\t\t\t\tif (this.handlerByType.qualitative) {\n\t\t\t\t\t\tthis.handler = this.handlerByType.qualitative\n\t\t\t\t\t\treturn\n\t\t\t\t\t}*/\n\t\t\t\t\tconst { GroupSet } = await import('./handlers/qualitative.ts')\n\t\t\t\t\tthis.handler = new GroupSet({ termsetting: this })\n\t\t\t\t\tthis.handlerByType.qualitative = this.handler\n\t\t\t\t\treturn\n\t\t\t\t\t//break\n\t\t\t\t}\n\t\t\t\tcase 'NumTWRegularBin':\n\t\t\t\tcase 'NumTWCustomBin':\n\t\t\t\tcase 'NumTWCont':\n\t\t\t\tcase 'NumTWBinary':\n\t\t\t\tcase 'NumTWSpline': {\n\t\t\t\t\tif (this.handlerByType.numeric) {\n\t\t\t\t\t\tthis.handler = this.handlerByType.numeric\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst { NumericHandler } = await import('./handlers/NumericHandler.ts')\n\t\t\t\t\tthis.handler = new NumericHandler({ termsetting: this })\n\t\t\t\t\tthis.handlerByType.numeric = this.handler\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tcase 'TermCollectionTWQual':\n\t\t\t\tcase 'TermCollectionTWCont': {\n\t\t\t\t\tconst { TermCollectionHandler } = await import('./handlers/termCollection.ts')\n\t\t\t\t\tthis.handler = new TermCollectionHandler({ termsetting: this })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// TODO: should reinstate throw once all migrated tw's have strict handlers for each tw type\n\t\t\t\tdefault:\n\t\t\t\t\tthrow `unsupported tw.type='${tw.type}'`\n\t\t\t}\n\t\t\t//return\n\t\t}\n\n\t\t// TODO: should use TwRouter here??? or expect tw to be already filled-in/instantiated???\n\t\tif (!termtype) {\n\t\t\tthis.handler = this.handlerByType.default as Handler\n\t\t\treturn\n\t\t}\n\t\tconst type = termtype == 'integer' || termtype == 'float' || termtype == 'date' ? 'numeric' : termtype // 'categorical', 'condition', 'survival', etc\n\t\tif (!this.handlerByType[type]) {\n\t\t\ttry {\n\t\t\t\tconst _ = await import(`./handlers/${type}.ts`)\n\t\t\t\tthis.handlerByType[type] = await _.getHandler(this)\n\t\t\t} catch (e) {\n\t\t\t\tthrow `error with handler='./handlers/${type}.ts': ${e}`\n\t\t\t}\n\t\t}\n\t\tthis.handler = this.handlerByType[type] as Handler\n\t}\n\n\tdestroy() {\n\t\tthis.dom.holder.remove()\n\t\tthis.dom.tip.destroy()\n\t\tthis.dom.tip2.destroy()\n\t}\n}\n", "import type { TermSettingOpts } from './types'\nimport { TermSetting } from './TermSetting.ts'\nimport type { Term, TermWrapper, Filter } from '#types'\nimport { call_fillTW, get$id, fillTermWrapper } from './utils.ts'\nimport { minimatch } from 'minimatch'\n// import { isNumericTerm } from '#shared/terms.js'\nimport { copyMerge, deepEqual, sleep } from '#rx'\nimport { select } from 'd3-selection'\nimport { TwRouter, QualitativeBase, NumericBase, routedTermTypes } from '#tw'\n\nexport const termsettingInit = opts => {\n\t// TODO: may convert to async-await as needed to initialize,\n\t// if ever an async TermSettingApi.init() static method is created\n\treturn new TermSettingApi(opts)\n}\n\nconst testClickTermDelay = 0 // 5000\n\nexport class TermSettingApi {\n\t#termsetting: TermSetting\n\tInner?: TermSetting\n\tloadingMasks: any[] = []\n\n\tconstructor(opts: TermSettingOpts) {\n\t\topts.api = this\n\t\tif (opts.loadingMasks) this.loadingMasks.push(...opts.loadingMasks)\n\t\tthis.#termsetting = new TermSetting(opts)\n\t\t// to be used for test-code only\n\t\tif (opts.debug) this.Inner = this.#termsetting\n\t}\n\n\tasync main(data: any = {}) {\n\t\tconst self = this.#termsetting\n\t\ttry {\n\t\t\tif (self.doNotHideTipInMain) {\n\t\t\t\t// single use: if true then delete\n\t\t\t\tself.doNotHideTipInMain = false\n\t\t\t} else {\n\t\t\t\tself.dom.tip.hide()\n\t\t\t}\n\t\t\tself.hasError = false\n\t\t\tdelete self.error\n\t\t\tself.validateMainData(data)\n\t\t\t// TODO: use routedTermTypes.has(data.term?.type) instead of just categorical\n\t\t\tif (\n\t\t\t\t!data.tw &&\n\t\t\t\t(QualitativeBase.termTypes.has(data.term?.type) ||\n\t\t\t\t\tNumericBase.termTypes.has(data.term?.type) ||\n\t\t\t\t\tdata.term?.type == 'termCollection')\n\t\t\t) {\n\t\t\t\tdata.tw = await TwRouter.initRaw({ term: data.term, q: data.q }, { vocabApi: self.vocabApi })\n\t\t\t}\n\t\t\tself.tw = data.tw\n\t\t\t// may need original values for comparing edited settings\n\t\t\tself.data = data //as PillData\n\t\t\t// term is read-only if it comes from state, let it remain read-only\n\t\t\tself.term = data.term as Term\n\t\t\tself.q = JSON.parse(JSON.stringify(data.q)) // q{} will be altered here and must not be read-only\n\t\t\tif ('$id' in data) self.$id = data.$id\n\t\t\tif ('disable_terms' in data) self.disable_terms = data.disable_terms\n\t\t\tif ('filter' in data) self.filter = data.filter as Filter\n\t\t\tif ('activeCohort' in data) self.activeCohort = data.activeCohort\n\t\t\tif ('sampleCounts' in data) self.sampleCounts = data.sampleCounts\n\t\t\tif ('menuOptions' in data) self.opts.menuOptions = data.menuOptions\n\t\t\tawait self.setHandler(self.term ? self.term.type : null, data.tw)\n\t\t\tif (data.term && self.handler && self.handler.validateQ) self.handler.validateQ(data)\n\t\t\tif (self.handler.postMain) await self.handler.postMain()\n\t\t\tif (self.opts.renderAs != 'none') self.view.updateUI()\n\t\t} catch (e) {\n\t\t\tself.hasError = true\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync runCallback(overrideTw = null) {\n\t\tconst self = this.#termsetting\n\t\t/* optional termwrapper (tw) to override attributes of self.term{} and self.q{}\n\t\tthe override tw serves the \"atypical\" termsetting usage\n\t\tas used in snplocus block pan/zoom update in regression.results.js\n\t\t*/\n\t\tconst arg: any = self.term ? { term: self.term, q: self.q, isAtomic: true } : {}\n\t\targ.$id = '$id' in this ? this.$id : await get$id(arg)\n\t\tif (arg.q?.reuseId && arg.q.reuseId === self.data.q?.reuseId) {\n\t\t\tif (!deepEqual(arg.q, self.data.q)) {\n\t\t\t\tdelete arg.q.reuseId\n\t\t\t\tdelete arg.q.name\n\t\t\t}\n\t\t}\n\t\tconst otw = overrideTw ? JSON.parse(JSON.stringify(overrideTw)) : {}\n\t\tconst tw = overrideTw ? copyMerge(JSON.stringify(arg), otw) : arg\n\t\tif (routedTermTypes.has(tw.term.type)) self.tw = await TwRouter.initRaw(tw, self.opts)\n\t\tif (self.opts.callback) self.opts.callback(tw)\n\t}\n\n\tasync showTree(holder, event: MouseEvent | undefined) {\n\t\tconst self = this.#termsetting\n\t\tself.dom.tip.clear()\n\t\tif (holder)\n\t\t\tself.dom.tip.showunder(\n\t\t\t\tholder instanceof Element ? holder : this instanceof Element ? this : self.dom.holder.node()\n\t\t\t)\n\t\telse self.dom.tip.show(event!.clientX, event!.clientY)\n\t\tif (!self.usecase) self.usecase = { target: 'default' }\n\t\tconst termdb = await import('../termdb/app.js')\n\t\ttermdb.appInit({\n\t\t\tholder: self.dom.tip.d,\n\t\t\tvocabApi: self.vocabApi,\n\t\t\tstate: {\n\t\t\t\tactiveCohort: self.activeCohort,\n\t\t\t\ttermfilter: self.vocabApi.state?.termfilter,\n\t\t\t\ttree: {\n\t\t\t\t\tusecase: self.usecase\n\t\t\t\t}\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tdisable_terms: self.disable_terms,\n\t\t\t\tclick_term: async t => {\n\t\t\t\t\tself.dom.nopilldiv.style('display', 'none')\n\t\t\t\t\tself.dom.pilldiv.style('display', 'none')\n\t\t\t\t\tself.dom.loadingdiv.text('Loading ...').style('display', 'inline-block')\n\t\t\t\t\tself.dom.tip.hide()\n\t\t\t\t\tthis.toggleOptionalLoadingMasks('')\n\t\t\t\t\tif (testClickTermDelay) await sleep(testClickTermDelay)\n\n\t\t\t\t\tlet tw\n\t\t\t\t\tif (t.term) tw = t as TermWrapper\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst term = t as Term\n\t\t\t\t\t\ttw = { term, q: { isAtomic: true }, isAtomic: true }\n\t\t\t\t\t}\n\n\t\t\t\t\tif (self.opts.customFillTw) tw = self.opts.customFillTw(tw)\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttw = await fillTermWrapper(tw, self.vocabApi, self.opts.defaultQ4fillTW)\n\t\t\t\t\t\t// tw is now furbished\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tif (this.isAbortError(e)) {\n\t\t\t\t\t\t\tself.dom.loadingdiv.text('')\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst msg = e.message || e.error || e\n\t\t\t\t\t\t\tself.dom.loadingdiv.text(`Error loading term ${self.handler?.getPillName?.(tw.term)}: ${msg}`)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tself.dom.nopilldiv.style('display', !self.term ? 'inline-block' : 'none')\n\t\t\t\t\t\tself.dom.pilldiv.style('display', self.term ? 'block' : 'none')\n\t\t\t\t\t\tthis.toggleOptionalLoadingMasks('none')\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tself.opts.callback!(tw)\n\t\t\t\t\tself.dom.loadingdiv.style('display', 'none')\n\t\t\t\t\tself.dom.nopilldiv.style('display', !self.term ? 'inline-block' : 'none')\n\t\t\t\t\tself.dom.pilldiv.style('display', self.term ? 'block' : 'none')\n\t\t\t\t\tthis.toggleOptionalLoadingMasks('none')\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\t// TODO: move this method to TermSetting class\n\tshowMenu(event: MouseEvent, clickedElem = null, menuHolder = null) {\n\t\tconst self = this.#termsetting\n\t\tconst tip = self.dom.tip\n\t\ttip.clear()\n\t\t// self.dom.holder really is set to clickedElem because\n\t\t// handler showEditMenu() use if for tip.showunder(self.dom.holder)\n\t\tif (self.opts.renderAs == 'none' && clickedElem) self.dom.holder = select(clickedElem)\n\t\tif (self.dom.holder) {\n\t\t\tconst elem = self.dom.holder?.node()\n\t\t\tif (elem) tip.showunder(elem)\n\t\t\telse tip.show(event.clientX, event.clientY)\n\t\t}\n\n\t\ttype opt = { label: string; callback: (f?: any) => void }\n\t\tconst options: opt[] = []\n\t\tconst q = self.q as any\n\n\t\tif (q.type == 'predefined-groupset' || q.type == 'custom-groupset') {\n\t\t\t// term is using groupsetting\n\t\t\t// should provide option to cancel it\n\t\t\tif (q.mode != 'binary' && self.term.type != 'geneVariant') {\n\t\t\t\t// mode=binary will never use groupsetting\n\t\t\t\t// geneVariant term can cancel groupsetting within edit menu\n\t\t\t\toptions.push({ label: 'Cancel grouping', callback: () => self.actions.cancelGroupsetting() } as opt)\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tself.q &&\n\t\t\t!self.term.groupsetting?.disabled &&\n\t\t\tself.term.type != 'survival' &&\n\t\t\tminimatch('edit', self.opts.menuOptions)\n\t\t) {\n\t\t\t// hide edit option for survival term because its showEditMenu() is disabled\n\t\t\toptions.push({\n\t\t\t\tlabel: 'Edit',\n\t\t\t\tcallback: async div => {\n\t\t\t\t\tif (self.data.editMsg) {\n\t\t\t\t\t\tdiv.append('div').style('margin', '10px').html(self.data.editMsg)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait self.handler.showEditMenu(div.append('div'))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} as opt)\n\t\t}\n\n\t\tif (self.term.type == 'geneVariant' && 'type' in self.q && self.q.type == 'predefined-groupset') {\n\t\t\t// display predefined groupsets of geneVariant term\n\t\t\t// for quick access\n\t\t\tconst groupsets = self.term.groupsetting?.lst\n\t\t\tif (!groupsets || !groupsets.length) throw 'predefined groupsets not found'\n\t\t\tfor (const [i, groupset] of groupsets.entries()) {\n\t\t\t\toptions.push({\n\t\t\t\t\tlabel: groupset.name,\n\t\t\t\t\tcallback: async () => {\n\t\t\t\t\t\tconst tw: any = {\n\t\t\t\t\t\t\ttype: 'GvPredefinedGsTW',\n\t\t\t\t\t\t\tisAtomic: true,\n\t\t\t\t\t\t\tterm: self.term,\n\t\t\t\t\t\t\tq: { type: 'predefined-groupset', predefined_groupset_idx: i, isAtomic: true }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait call_fillTW(tw, self.vocabApi)\n\t\t\t\t\t\tself.opts.callback(tw)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Restored the reuse menu option for now, due to failing integration tests that will require more code changes to fix\n\t\t// Instead of deleting the reuse code, may move the Reuse to the edit menu for recovering saved grouping/bin config\n\t\t// if (minimatch('reuse', self.opts.menuOptions)) {\n\t\t// \toptions.push({ label: 'Reuse', callback: self.showReuseMenu } as opt)\n\t\t// }\n\n\t\tif (minimatch('replace', self.opts.menuOptions)) {\n\t\t\toptions.push({\n\t\t\t\tlabel: 'Replace',\n\t\t\t\tcallback: (event, d) => {\n\t\t\t\t\tthis.showTree(event, d)\n\t\t\t\t}\n\t\t\t} as opt)\n\t\t}\n\n\t\tif (minimatch('remove', self.opts.menuOptions)) {\n\t\t\toptions.push({ label: 'Remove', callback: () => self.actions.removeTerm() } as opt)\n\t\t}\n\n\t\tif (self.opts.customMenuOptions) options.push(...self.opts.customMenuOptions)\n\n\t\tconst activeMenu = menuHolder || tip.d\n\t\tactiveMenu\n\t\t\t.selectAll('div')\n\t\t\t.data(options)\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('tabindex', (d, i) => i + 1)\n\t\t\t.style('display', self.opts.menuLayout == 'horizontal' ? 'inline-block' : 'block')\n\t\t\t.text((d: opt) => d.label)\n\t\t\t.on('click', (event: MouseEvent, d: opt) => {\n\t\t\t\tself.dom.tip.clear()\n\t\t\t\td.callback(self.dom.tip.d)\n\t\t\t})\n\t\t\t.on('keyup', event => {\n\t\t\t\tif (event.key == 'Enter') event.target.click()\n\t\t\t})\n\n\t\tactiveMenu.select('.sja_menuoption').node()?.focus()\n\t\t//self.showFullMenu(tip.d, self.opts.menuOptions)\n\t}\n\n\t// TODO: move this method to TermSetting class\n\tshowGeneSearch(clickedElem: Element | null, event: MouseEvent) {\n\t\tconst self = this.#termsetting\n\t\tself.dom.tip.clear()\n\t\tif (clickedElem)\n\t\t\tself.dom.tip.showunder(\n\t\t\t\tclickedElem instanceof Element ? clickedElem : this instanceof Element ? this : self.dom.holder.node()\n\t\t\t)\n\t\telse self.dom.tip.show(event.clientX, event.clientY)\n\n\t\tconst selectedGenes = new Set()\n\t\tconst searchDiv = self.dom.tip.d.append('div').style('padding', '5px')\n\t\tconst label = searchDiv.append('label')\n\t\tlabel.append('span').text('Search: ')\n\t\tconst input = label\n\t\t\t.append('input')\n\t\t\t.attr('type', 'text')\n\t\t\t.on('input', async () => {\n\t\t\t\tconst str = input.property('value')\n\t\t\t\tconst cohortStr = self.opts.vocabApi.termdbConfig.selectCohort.values[self.activeCohort || 0].keys\n\t\t\t\t\t.slice()\n\t\t\t\t\t.sort()\n\t\t\t\t\t.join(',')\n\n\t\t\t\ttry {\n\t\t\t\t\tconst results = !str ? { lst: [] } : await self.vocabApi.findTerm(str, cohortStr, self.usecase as any, 'gene')\n\t\t\t\t\tresultsDiv.selectAll('*').remove()\n\t\t\t\t\tresultsDiv\n\t\t\t\t\t\t.selectAll('div')\n\t\t\t\t\t\t.data(results.lst.filter((g: any) => !selectedGenes.has(g)))\n\t\t\t\t\t\t.enter()\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.attr('class', 'ts_pill sja_filter_tag_btn sja_tree_click_term')\n\t\t\t\t\t\t.style('display', 'block')\n\t\t\t\t\t\t.style('margin', '2px 3px')\n\t\t\t\t\t\t.style('width', 'fit-content')\n\t\t\t\t\t\t.text((gene: any) => gene.name)\n\t\t\t\t\t\t.on('click', async (gene: any) => {\n\t\t\t\t\t\t\tself.dom.tip.hide()\n\t\t\t\t\t\t\tthis.runCallback({\n\t\t\t\t\t\t\t\tterm: {\n\t\t\t\t\t\t\t\t\tname: gene.name,\n\t\t\t\t\t\t\t\t\ttype: 'geneVariant'\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tq: {\n\t\t\t\t\t\t\t\t\texclude: []\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} as any) // TODO: fix type\n\t\t\t\t\t\t})\n\t\t\t\t} catch (e) {\n\t\t\t\t\talert('Search error: ' + e)\n\t\t\t\t}\n\t\t\t})\n\n\t\tconst resultsDiv = self.dom.tip.d\n\t\t\t.append('div')\n\t\t\t.style('margin', '5px')\n\t\t\t.style('padding-left', '5px')\n\t\t\t.style('border-left', '2px solid #ccc')\n\t}\n\n\thasError() {\n\t\treturn this.#termsetting.hasError\n\t}\n\n\tvalidateQ(d /*: PillData*/) {\n\t\tconst self = this.#termsetting\n\t\tif (!self.handler?.validateQ) return\n\t\ttry {\n\t\t\tself.handler.validateQ(d)\n\t\t} catch (e) {\n\t\t\tthis.#termsetting.hasError = true\n\t\t\tthrow e\n\t\t}\n\t}\n\n\ttoggleOptionalLoadingMasks(display = '') {\n\t\tif (!this.loadingMasks) return\n\t\tfor (const m of this.loadingMasks) {\n\t\t\tm.style('display', display || '')\n\t\t}\n\t}\n\n\tisAbortError(e) {\n\t\tif (e instanceof DOMException) return e.name === 'AbortError'\n\t\tif (typeof e === 'object' && e !== null && e.name === 'AbortError') return true\n\t\tif (typeof e == 'string') return e.includes('stale sequenceId') || e.includes('AbortError')\n\t\treturn false\n\t}\n\n\tdestroy() {\n\t\tthis.#termsetting.destroy()\n\t}\n}\n", "import type { TermWrapper, Term } from '#types'\nimport type { MassAppApi, MassState } from '#mass/types/mass'\nimport { termsettingInit } from '#termsetting'\nimport { select } from 'd3-selection'\nimport type { MultiTermWrapperDom, MultiTermWrapperUIOpts } from './types/MultiTermWrapperEditUI'\n\n/** Creates a UI for users to select pills and edit the term\n * before submitting or dispatching an action.\n *\n * If editing the pill is not needed, use termdb.appInit() instead.\n *\n * The caller is responsible for handling the returned terms.\n * (i.e. any app actions). */\nexport class MultiTermWrapperEditUI {\n\treadonly type = 'multiTermEditUI'\n\tapp: MassAppApi\n\tbuttonLabel: string\n\tcallback: (terms: any) => void\n\tcustomInputs?: object\n\tdisable_terms: Term[]\n\tdom: MultiTermWrapperDom\n\theaderText: string\n\tinputListLength: number\n\tmaxNum: number\n\tstate?: MassState\n\ttwList: TermWrapper[]\n\tupdate: any\n\n\tconstructor(opts: MultiTermWrapperUIOpts) {\n\t\tthis.app = opts.app\n\t\tthis.callback = opts.callback\n\t\tconst holder = opts.holder.attr('data-testid', 'sjpp-multi-tw-edit-ui')\n\t\tconst header = holder\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-edit-ui-header')\n\t\t\t.style('display', 'block')\n\t\t\t.style('padding', '10px')\n\t\tconst tws = holder.append('div').style('display', 'block').style('margin-left', '10px')\n\t\tconst submitDiv = holder\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-edit-ui-submit')\n\t\t\t.style('display', 'block')\n\t\t\t.style('padding', '10px')\n\t\t\t.style('margin-left', '5px')\n\t\tthis.dom = {\n\t\t\tholder,\n\t\t\theader,\n\t\t\ttws,\n\t\t\tsubmitBtn: submitDiv.append('button').style('display', 'inline-block'),\n\t\t\tfooter: submitDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-edit-ui-footer')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin-left', '10px')\n\t\t}\n\t\tthis.twList = opts.twList || []\n\t\t//Determines if the user can submit or not\n\t\t//If >0, can submit to remove terms\n\t\t//If == 0, user must select a term to submit\n\t\tthis.inputListLength = this.twList.length\n\t\tthis.buttonLabel = opts.buttonLabel || 'Submit'\n\t\tthis.maxNum = opts.maxNum || Infinity\n\t\tthis.headerText = opts.headerText || ''\n\t\tthis.customInputs = opts.customInputs || {}\n\t\tthis.disable_terms = opts.disable_terms || []\n\t\tif (opts.state) this.state = opts.state\n\n\t\tsetRenderers(this)\n\t}\n\n\tasync renderUI() {\n\t\tthis.dom.header.style('font-style', 'italic').style('opacity', 0.7).text(this.headerText)\n\n\t\tthis.dom.submitBtn.text(this.buttonLabel).on('click', () => {\n\t\t\tthis.callback(this.twList)\n\t\t})\n\n\t\tthis.update(this)\n\t}\n\n\tasync getNewPill(d, div) {\n\t\t//Do not allow users to select the same term more than once\n\t\t//Combine with specified disable_terms from the caller\n\t\tconst disable_terms = [...this.disable_terms, ...this.twList.map(tw => tw.term)]\n\t\tconst _opts = {\n\t\t\tabbrCutoff: 50,\n\t\t\tdebug: this.app.opts?.debug,\n\t\t\tdisable_terms,\n\t\t\tgenomeObj: this.app.opts.genome,\n\t\t\tholder: div,\n\t\t\tmenuOptions: '!replace',\n\t\t\tnumericEditMenuVersion: ['continuous', 'discrete'],\n\t\t\tplaceholder: 'Add term',\n\t\t\tvocabApi: this.app.vocabApi,\n\t\t\tcallback: (tw: any) => {\n\t\t\t\t/** Make a copy of the twList. When the edit UI is opened\n\t\t\t\t * with a list of terms, the object is sealed.*/\n\t\t\t\tconst twListCopy = this.twList.slice(0)\n\t\t\t\tconst idx = twListCopy.findIndex(t => t.$id === d.tw.$id)\n\t\t\t\tif (idx !== -1 && !tw?.term) {\n\t\t\t\t\ttwListCopy.splice(idx, 1)\n\t\t\t\t} else if (idx == -1) {\n\t\t\t\t\ttw.$id = d.tw.$id\n\t\t\t\t\ttwListCopy.push(tw)\n\t\t\t\t} else twListCopy[idx] = tw\n\t\t\t\tthis.twList = twListCopy\n\t\t\t\tthis.update(this)\n\t\t\t}\n\t\t} as any\n\n\t\tif (this.state) {\n\t\t\t_opts.activeCohort = this.state.activeCohort\n\t\t}\n\n\t\tif (this.app.opts?.genome) {\n\t\t\t_opts.genomeObj = this.app.opts.genome\n\t\t}\n\t\tconst termsettingOpts = Object.assign({}, _opts, this.customInputs)\n\t\tconst pill = await termsettingInit(termsettingOpts)\n\t\treturn pill\n\t}\n\n\tasync renderTerm(d, numericOpts = false) {\n\t\tif (!d?.pill) return\n\t\tconst pillOps = this.getPillOpts(d, numericOpts)\n\t\tawait d.pill.main(pillOps)\n\t}\n\n\tgetPillOpts(d, numericOpts) {\n\t\tconst pillOps: any = {\n\t\t\tterm: d.tw.term,\n\t\t\tq: d.tw.q\n\t\t}\n\t\tif (d.tw.$id) pillOps.$id = d.tw.$id\n\t\tif (this.state) {\n\t\t\tpillOps.activeCohort = this.state.activeCohort\n\t\t\tpillOps.filter = this.state?.termfilter?.filter\n\t\t}\n\t\tif (numericOpts) {\n\t\t\tpillOps.numericEditMenuVersion = ['continuous', 'discrete']\n\t\t}\n\t\treturn pillOps\n\t}\n}\n\nfunction setRenderers(self) {\n\tself.update = () => {\n\t\tself.dom.tws.selectAll('div').remove()\n\t\tconst twListCopy = self.twList.map(tw => {\n\t\t\treturn { tw }\n\t\t})\n\n\t\tif (twListCopy.length < self.maxNum) {\n\t\t\t/** Insert a blank tw to trigger a new termsetting init\n\t\t\t * until limit is reached */\n\t\t\ttwListCopy.push({ tw: { $id: Math.random().toString() } } as any)\n\t\t}\n\t\tconst tws = self.dom.tws.selectAll(':scope>.sjpp-edit-ui-pill').data(twListCopy, d => d.tw?.$id)\n\t\ttws.exit().remove()\n\t\ttws.each(self.renderTerm)\n\t\ttws.enter().append('div').attr('class', 'sjpp-edit-ui-pill').each(self.addTerm)\n\n\t\t//Disable submit if user did not remove terms from input list and did not select any terms\n\t\tself.dom.submitBtn.property('disabled', self.twList.length === 0 && self.inputListLength == 0)\n\t\t//Show message if terms are removed or if list is empty\n\t\tself.dom.footer.text(\n\t\t\t`${\n\t\t\t\tself.twList.length === 0 && self.inputListLength > 0 ? `Terms removed` : `${self.twList.length} terms selected`\n\t\t\t}`\n\t\t)\n\t}\n\n\tself.addTerm = async function (d) {\n\t\tconst div = select(this)\n\t\td.pill = await self.getNewPill(d, div)\n\t\tself.renderTerm(d, true)\n\t}\n}\n", "import { keyupEnter } from '#src/client'\n\n/*\nconfigure numeric axis\n* automatic\n* fixed min and max\n* percentile max\n\n\narg{}\n\n- holder\n\trequired\n\n- callback({})\n\trequired\n\tcallback parameter should be one of following 3:\n\t{auto:1}\n\t{fixed:{ min:, max:}}\n\t{percentile:}\n\n- setting{}\n\toptional\n\tone of the 3 callback() parameters to populate the ui\n\n- noPercentile:true\n\tif set, do not allow setting percentile\n*/\n\nexport function makeNumericAxisConfig({ holder, callback, setting, noPercentile }) {\n\tif (!holder) throw 'no holder'\n\tif (typeof callback != 'function') throw 'callback not function'\n\n\tif (!setting) setting = { auto: 1 }\n\tif (setting.auto) {\n\t} else if (setting.fixed) {\n\t\tif (!Number.isFinite(setting.fixed.min)) throw 'fixed.min is not number'\n\t\tif (!Number.isFinite(setting.fixed.max)) throw 'fixed.max is not number'\n\t\tif (setting.fixed.min >= setting.fixed.max) throw 'fixed min>=max'\n\t} else if (setting.percentile) {\n\t\tif (setting.percentile < 0 || setting.percentile > 100) throw 'invalid setting.percentile'\n\t} else {\n\t\tthrow 'invalid setting{}'\n\t}\n\n\tconst row = holder.append('div')\n\trow.append('span').html('Y scale ')\n\tconst ss = row.append('select')\n\tconst op1 = ss.append('option').text('Automatic')\n\tconst op2 = ss.append('option').text('Fixed')\n\tlet op3\n\tif (!noPercentile) op3 = ss.append('option').text('Percentile')\n\n\tss.on('change', event => {\n\t\tconst si = event.target.selectedIndex\n\t\tif (si == 0) {\n\t\t\tfixedDiv.style('display', 'none')\n\t\t\tpercentileDiv.style('display', 'none')\n\t\t\tcallback({ auto: 1 })\n\t\t\treturn\n\t\t}\n\t\tif (si == 1) {\n\t\t\tfixedDiv.style('display', '')\n\t\t\tmaxInput.node().focus()\n\t\t\tpercentileDiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tfixedDiv.style('display', 'none')\n\t\tpercentileDiv.style('display', '')\n\t\tperInput.node().focus()\n\t})\n\n\tss.property('selectedIndex', setting.auto ? 0 : setting.fixed ? 1 : 2)\n\n\t// following code generates 3 <input> that are accessed upon select change\n\tlet maxInput, minInput, perInput\n\n\t// when \"fixed\" is selected, these controls are shown to enter fixed min/max\n\tconst fixedDiv = row\n\t\t.append('div')\n\t\t.style('margin', '10px')\n\t\t.style('display', setting.fixed ? 'block' : 'none')\n\t{\n\t\tconst row1 = fixedDiv.append('div')\n\t\trow1.append('span').html('Max ').style('font-family', 'Courier').style('font-size', '.9em')\n\t\tmaxInput = row1.append('input').attr('type', 'number').style('width', '50px')\n\t\tif (setting.fixed) maxInput.property('value', setting.fixed.max)\n\t\tconst row2 = fixedDiv.append('div')\n\t\trow2.append('span').html('Min ').style('font-family', 'Courier').style('font-size', '.9em')\n\t\tminInput = row2.append('input').attr('type', 'number').style('width', '50px')\n\t\tif (setting.fixed) minInput.property('value', setting.fixed.min)\n\t\trow2\n\t\t\t.append('button')\n\t\t\t.text('Set')\n\t\t\t.style('margin-left', '5px')\n\t\t\t.on('click', () => {\n\t\t\t\tlet min, max\n\t\t\t\tmax = maxInput.property('value')\n\t\t\t\tif (max == '') {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmax = Number.parseFloat(max)\n\t\t\t\tif (Number.isNaN(max)) {\n\t\t\t\t\talert('invalid max value')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmin = minInput.property('value')\n\t\t\t\tif (min == '') {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmin = Number.parseFloat(min)\n\t\t\t\tif (Number.isNaN(min)) {\n\t\t\t\t\talert('invalid min value')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (min >= max) {\n\t\t\t\t\talert('Min must be smaller than max')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcallback({ fixed: { min, max } })\n\t\t\t})\n\t}\n\n\t// when \"percentile\" is selected, these controls are shown to enter percentile value\n\tconst percentileDiv = row\n\t\t.append('div')\n\t\t.style('margin-top', '6px')\n\t\t.style('display', setting.percentile ? 'block' : 'none')\n\tpercentileDiv.append('span').html('Percentile ').style('font-family', 'Courier').style('font-size', '.9em')\n\tperInput = percentileDiv.append('input').attr('type', 'number').style('width', '50px')\n\tif (setting.percentile) {\n\t\tperInput.property('value', setting.percentile)\n\t}\n\tconst setpercentile = s => {\n\t\tif (s == '') return\n\t\tconst v = Number.parseInt(s)\n\t\tif (Number.isNaN(v) || v <= 0 || v > 100) {\n\t\t\talert('percentile should be integer within range 0-100')\n\t\t\treturn\n\t\t}\n\t\tcallback({ percentile: v })\n\t}\n\tperInput.on('keyup', event => {\n\t\tif (!keyupEnter(event)) return\n\t\tsetpercentile(perInput.property('value'))\n\t})\n\tpercentileDiv\n\t\t.append('button')\n\t\t.text('Set')\n\t\t.style('margin-left', '5px')\n\t\t.on('click', () => {\n\t\t\tsetpercentile(perInput.property('value'))\n\t\t})\n}\n", "import type { Elem, Input } from '../types/d3'\n\n/* makes radio buttons */\n\ntype RadioButtonOpts = {\n\t/** Fires .oninput. Intended for general use. */\n\tcallback?: (f?: any) => void\n\t/** Required. */\n\tholder: any\n\t/** common Name of <input>, use random number if not given */\n\tinputName?: string | number\n\t/** Mass ui specific logic. Optional callback methods for\n\t * non oninput events. Intended to address needs for assistive techology\n\t */\n\tlisteners?: {\n\t\t/** Fires on onmouseup and onkeyup for the button and text label\n\t\t */\n\t\tinput: () => void\n\t}\n\t/** arr of objs defining the radio buttons and properties */\n\toptions: OptionEntry[]\n\t/** css to be applied to each <div> of the options\n\t * e.g. { \"padding\":\"5px\", \"display\":\"inline-block\" }\n\t */\n\tstyles?: { [index: string]: string | number }\n\t/** Legacy support for deprecated radio2 input option, will be mapped to wrapper div display */\n\tlabelDisplay?: string\n}\n\ntype OptionEntry = {\n\t/** only set for only *one* option */\n\tchecked?: boolean | number\n\t/** Text shown in the span to the right of the radio button */\n\tlabel: string\n\t/** Text shown in tooltip */\n\ttitle?: string\n\t/** Should correspond to 'currValue' in callbacks */\n\tvalue: string | number | boolean\n\t/** test id assigned to <input>. if used, assumes all options are assigned testids */\n\ttestid?: string\n}\n\ntype RadioApi = {\n\t/** Divs containing the labels with the padding and display styles applied. */\n\tdivs: Elem\n\t/** Divs encapsulating the radio buttons and text. All styles provided in opts\n\t * applied here. */\n\tlabels: Elem\n\t/** Radio buttons, corresponding to the .options[] opt. */\n\tinputs: Input\n\t/** Trigger changing the checked button from the cooresponding value,\n\t * independent of user and other callbacks. */\n\tmain: (value: number) => void\n}\n\nlet nameSuffix = 0\n\nexport function make_radios(opts: RadioButtonOpts): RadioApi {\n\tif (!opts.callback && !opts.listeners) throw `Missing event callback for radios [#dom/radiobutton.js]`\n\tif (opts.callback && opts.listeners)\n\t\tthrow `Both callback() and .listeners defined [#dom/radiobutton.js]. Only supply one.`\n\tconst inputName = opts.inputName || 'pp-dom-radio-' + nameSuffix++\n\n\tif (!opts.styles) opts.styles = {}\n\tif (!opts.styles.display) {\n\t\tif (opts.labelDisplay) opts.styles.display = opts.labelDisplay\n\t\telse {\n\t\t\t// no style specified. compute automatic style. if total length of all options is small,\n\t\t\t// show all options in one row; otherwise one row per option. this allows to limit width in 2-col edit menu setting\n\t\t\t// count by total number of characters. radio button counts as 4 characters\n\t\t\tconst len = opts.options.reduce((total, d) => total + d.label.length + 4, 0)\n\t\t\topts.styles.display = len < 36 ? 'inline-block' : 'block'\n\t\t}\n\t}\n\tconst styleKeys = Object.keys(opts.styles)\n\tif (!styleKeys.includes('padding')) opts.styles.padding = '3px'\n\n\tconst divs = opts.holder\n\t\t.selectAll('div')\n\t\t.data(opts.options, (d: any) => d?.value)\n\t\t.enter()\n\t\t.append('div')\n\t\t.attr('aria-label', (d: OptionEntry) => d.title)\n\t\t//.style('display', opts.styles.display)\n\t\t.style('padding', opts.styles.padding)\n\n\tif (opts.styles) {\n\t\tfor (const k in opts.styles) {\n\t\t\t// apply opts.styles to div, instead of labels\n\t\t\tdivs.style(k, opts.styles[k])\n\t\t}\n\t}\n\n\tconst labels = divs.append('label')\n\tconst inputs = labels\n\t\t.append('input')\n\t\t.attr('type', 'radio')\n\t\t.attr('name', inputName)\n\t\t.attr('value', (d: OptionEntry) => d.value)\n\t\t/** vertical-align = top was the default in the now deleted radio2.js\n\t\t * used exclusively for mass. Allow for mass to implement this style\n\t\t * without impeding other use cases.*/\n\t\t.style('vertical-align', opts.styles && 'vertical-align' in opts.styles ? opts.styles['vertical-align'] : '')\n\t\t.style('margin-top', '2px')\n\t\t.style('margin-right', 0)\n\t\t.property('checked', (d: OptionEntry) => d?.checked)\n\tif (opts.options.find(i => i.testid)) {\n\t\t// if any testid is present, will assign to all\n\t\tinputs.attr('data-testid', i => i.testid)\n\t}\n\tif (opts.callback) {\n\t\tinputs.on('input', async (event: KeyboardEvent, d: OptionEntry) => {\n\t\t\t//Disable the radio buttons while the callback is running\n\t\t\tinputs.property('disabled', true)\n\t\t\tif (!opts.callback) return //So eslint doesn't complain\n\t\t\tawait opts.callback(d.value)\n\t\t\tradio.main(d.value)\n\t\t\t//Re-enable the radio buttons after the callback finishes\n\t\t\tinputs.property('disabled', false)\n\t\t})\n\t}\n\n\tconst radioText = labels\n\t\t.append('span')\n\t\t.style('vertical-align', opts.styles && 'vertical-align' in opts.styles ? opts.styles['vertical-align'] : '')\n\t\t.html((d: OptionEntry) => ' ' + d.label)\n\n\tif (opts?.listeners?.input) {\n\t\t//Mass UI specific logic for assistive technologies\n\t\tinputs.on('mouseup', opts.listeners.input).on('keyup', opts.listeners.input)\n\t\tradioText.on('mouseup', opts.listeners.input).on('keyup', opts.listeners.input)\n\t}\n\n\tconst radio = {\n\t\tdivs,\n\t\tlabels,\n\t\tinputs,\n\t\tmain(currValue: string | number | boolean) {\n\t\t\tradio['currValue'] = currValue\n\t\t\tinputs.property('checked', (d: OptionEntry) => d.value == radio['currValue'])\n\t\t}\n\t}\n\n\treturn radio\n}\n", "import { icons } from './control.icons'\nimport type { ClientGenome } from '../types/clientGenome'\nimport type { Elem } from '../types/d3'\nimport type { RenderSandboxForm, NewSandboxOpts, NewSandbox } from './types/sandbox'\n\n/*\nCreates sandbox divs, containers running proteinpaint calls, forms, etc. \nindependent of one another. \n\nRequired:\n.holder\n.genomes\n\n****************\n\tEXPORTED\n****************\nrenderSandboxFormDiv\nnewSandboxDiv\n*/\n\nexport function renderSandboxFormDiv(holder: Elem, genomes: ClientGenome[]): RenderSandboxForm {\n\t//Classes for unit testing\n\tholder.classed('sjpp-sandbox-form', true)\n\tconst inputdiv = holder\n\t\t.append('div')\n\t\t.style('margin', '40px 20px 20px 20px')\n\t\t.classed('sjpp-sandbox-form-inputDiv', true)\n\tconst p = inputdiv.append('p').classed('sjpp-sandbox-form-gselect', true)\n\tp.append('span').html('Genome ')\n\tconst gselect = p.append('select')\n\tfor (const n in genomes) {\n\t\tgselect.append('option').text(n)\n\t}\n\t//For file select, pathway input, etc.\n\tconst filediv = inputdiv.append('div').style('margin', '20px 0px').classed('sjpp-sandbox-form-fileDiv', true)\n\t//For error messages\n\tconst saydiv = holder.append('div').style('margin', '10px 20px').classed('sjpp-sandbox-form-sayDiv', true)\n\t//For displaying output\n\tconst visualdiv = holder.append('div').style('margin', '20px').classed('sjpp-sandbox-form-visualDiv', true)\n\treturn [inputdiv, gselect.node(), filediv, saydiv, visualdiv]\n}\n\nconst plotIdToSandboxId = {}\nconst sandboxIdStr = Math.random().toString().slice(-6) + '-' + (+new Date()).toString().slice(-8)\nlet sandboxIdSuffix = 0\n\n/*\n\tsandbox_holder: a d3-selection\n*/\n\nexport function newSandboxDiv(sandbox_holder: Elem, opts: Partial<NewSandboxOpts> = {}): NewSandbox {\n\t// NOTE: plotId=0 (Number) will not be tracked, assumes a non-empty plotId is used\n\tconst insertSelector = opts.beforePlotId\n\t\t? opts.beforePlotId in plotIdToSandboxId\n\t\t\t? '#' + plotIdToSandboxId[opts.beforePlotId]\n\t\t\t: `#${opts.beforePlotId}`\n\t\t: ':first-child'\n\tconst app_div = sandbox_holder.insert('div', insertSelector).attr('class', 'sjpp-sandbox')\n\tlet sandboxId: string\n\tif (opts.plotId) {\n\t\tsandboxId = `sjpp-sandbox-${sandboxIdStr}-${sandboxIdSuffix++}`\n\t\tapp_div.attr('id', sandboxId)\n\t\tplotIdToSandboxId[opts.plotId] = sandboxId\n\t}\n\n\tconst header_row = app_div\n\t\t.append('div')\n\t\t.attr('class', 'sjpp-output-sandbox-header')\n\t\t.style('width', opts.style?.width || '95vw')\n\t\t.style('border', '1px solid #ccc')\n\t\t.style('display', 'flex')\n\t\t.style('align-items', 'center')\n\t\t.style('justify-content', 'left')\n\n\tconst hoverInColor = 'blue'\n\tconst hoverOutColor = 'black'\n\n\t// close_btn\n\tconst closeBtn = header_row\n\t\t.append('div')\n\t\t.classed('sjpp-output-sandbox-close-bt', true)\n\t\t// .classed('sja_menuoption', true)\n\t\t.style('cursor', 'pointer')\n\t\t.style('vertical-align', 'middle')\n\t\t.on('mouseenter', () => {\n\t\t\tconst path = closeBtn.select('path')\n\t\t\tpath.attr('stroke', hoverInColor)\n\t\t})\n\t\t.on('mouseleave', () => {\n\t\t\tconst path = closeBtn.select('path')\n\t\t\tpath.attr('stroke', hoverOutColor)\n\t\t})\n\t\t.html(\n\t\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#000\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\">\n\t\t <path stroke='#000' d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z\"/>\n\t\t</svg>`\n\t\t)\n\t\t.on('mousedown', event => {\n\t\t\tdocument.body.dispatchEvent(new Event('mousedown'))\n\t\t\tevent.stopPropagation()\n\t\t})\n\t\t.on('click', () => {\n\t\t\t// clear event handlers\n\t\t\theader_row.on('click', null).on('mousedown', null)\n\t\t\tapp_div.selectAll('*').remove()\n\t\t\tif (typeof opts.close === 'function') opts.close()\n\t\t})\n\n\t// placeholder for collapse btn\n\tconst collapseBtnDiv = header_row\n\t\t.append('div')\n\t\t.attr('title', 'Click to collapse or expand this chart sandbox')\n\t\t.classed('sjpp-output-sandbox-collapse-btn', true)\n\t// .classed('sja_menuoption', true)\n\t//.style('vertical-align', 'middle')\n\n\t// placeholder for expand btn\n\tconst expandBtnDiv = header_row\n\t\t.append('div')\n\t\t.classed('sjpp-output-sandbox-expand-btn', true)\n\t\t// .classed('sja_menuoption', true)\n\t\t.style('display', 'none')\n\t//.style('vertical-align', 'sub')\n\n\tconst header = header_row\n\t\t.append('div')\n\t\t.attr('id', 'sandbox-header-text')\n\t\t.style('display', 'inline-flex')\n\t\t.style('align-items', 'center')\n\t\t.style('justify-content', 'left')\n\t\t.style('padding', '5px 10px')\n\n\tconst body = app_div\n\t\t.append('div')\n\t\t.attr('class', 'sjpp-output-sandbox-content sjpp_show_scrollbar')\n\t\t.style('width', opts.style?.width || '95vw')\n\n\tlet isSandboxContentVisible = true\n\n\t// Collapse btn\n\ticons['collapse'](collapseBtnDiv, {\n\t\tfontSize: '1.5em',\n\t\tpadding: '4px 10px',\n\t\tcolor: 'black',\n\t\thandler: expandCollapse\n\t})\n\t// Expand btn\n\ticons['expand'](expandBtnDiv, {\n\t\tfontSize: '1.5em',\n\t\tpadding: '4px 10px',\n\t\tcolor: 'black',\n\t\tdisplay: 'none',\n\t\thandler: expandCollapse\n\t})\n\n\tcollapseBtnDiv\n\t\t.on('mouseenter', () => {\n\t\t\tconst path = collapseBtnDiv.select('path')\n\t\t\tpath.attr('stroke', hoverInColor)\n\t\t})\n\t\t.on('mouseleave', () => {\n\t\t\tconst path = collapseBtnDiv.select('path')\n\t\t\tpath.attr('stroke', hoverOutColor)\n\t\t})\n\n\texpandBtnDiv\n\t\t.on('mouseenter', () => {\n\t\t\tconst path = expandBtnDiv.select('path')\n\t\t\tpath.attr('stroke', hoverInColor)\n\t\t})\n\t\t.on('mouseleave', () => {\n\t\t\tconst path = expandBtnDiv.select('path')\n\t\t\tpath.attr('stroke', hoverOutColor)\n\t\t})\n\n\tfunction expandCollapse() {\n\t\tisSandboxContentVisible = !isSandboxContentVisible\n\t\tcollapseBtnDiv.style('display', isSandboxContentVisible == true ? 'inline-block' : 'none')\n\t\texpandBtnDiv.style('display', isSandboxContentVisible == true ? 'none' : 'inline-block')\n\t\tbody.style('display', isSandboxContentVisible == true ? 'block' : 'none')\n\t}\n\n\treturn { header_row, header, body, app_div, id: sandboxId! }\n}\n", "import { debounce } from 'debounce'\nimport { Menu } from '#dom/menu'\nimport type { Selection } from 'd3-selection'\nimport { select } from 'd3-selection'\nimport { keyupEnter } from '../src/client'\nimport { throwMsgWithFilePathAndFnName } from './sayerror'\nimport type { Elem, Input, Span } from '../types/d3'\n\ntype SearchGroupEntry = {\n\t/** Text appearing above the search results group */\n\ttitle: string\n\t/** Array items to search. Maybe string char, objs, etc.\n\t * Buttons text determined by either item.name || item.label if an object\n\t * or as item, if item is a string\n\t */\n\titems: any[]\n\t/** Set the default callback behavior if no item(s) appear*/\n\tdefault: boolean\n\t/** Default color for buttons is light grey. Specify color for the group */\n\tcolor?: string\n\t/** Callback for onclick or onenter */\n\tcallback: (f: any) => any\n}\n\ntype InputSearchOpts = {\n\tholder: Elem\n\t/** can be async or synchronous search */\n\tsearchItems: () => Promise<SearchGroupEntry[]> | SearchGroupEntry[]\n\tapp?: any\n\t/** Menu tip. If not provided, created by default */\n\ttip?: any\n\t/** Add any css style here */\n\tstyle?: any\n\t/**Size of the input field */\n\tsize?: number\n\tplaceholder?: string\n\ttitle?: string\n}\n\nexport class InputSearch {\n\tholder: Elem\n\tinput: Input\n\treadonly tip: any\n\tsearchItems: () => Promise<SearchGroupEntry[]> | SearchGroupEntry[]\n\tstyle: any\n\tsize: number\n\tplaceholder: string\n\t/** Title for input, not title above each group */\n\ttitle: string\n\tapp: any\n\n\tconstructor(opts: InputSearchOpts) {\n\t\tthis.holder = opts.holder\n\t\tthis.input = opts.holder.append('input').attr('type', 'search')\n\t\tthis.tip = opts.tip || new Menu({ border: '', padding: '0px' })\n\t\tthis.style = opts.style || {}\n\t\tthis.size = opts.size || 20\n\t\tthis.placeholder = opts.placeholder || ''\n\t\tthis.title = opts.title || ''\n\t\tthis.searchItems = opts.searchItems\n\t\tthis.app = opts.app\n\t}\n\n\tinitUI() {\n\t\tthis.holder.style('padding', 'padding' in this.style ? this.style.padding : '5px').style('display', 'inline-block')\n\t\tthis.input\n\t\t\t.attr('class', 'sjpp-input-search')\n\t\t\t.style('border', 'border' in this.style ? this.style.border : '5px')\n\t\t\t.attr('size', this.size)\n\t\t\t.attr('placeholder', this.placeholder)\n\t\t\t.attr('aria-label', this.title)\n\t\t\t.on('keyup', async (event: KeyboardEvent) => {\n\t\t\t\tif (event.key == 'ArrowDown') {\n\t\t\t\t\tthis.tip.d.select('.sja_menuoption').node()?.focus()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (keyupEnter(event)) await this.enterSearch()\n\n\t\t\t\tdebounce(this.addSearchItems(), 400)\n\t\t\t})\n\t}\n\n\tasync addSearchItems() {\n\t\tif (!this.input.property('value').trim()) {\n\t\t\tthis.tip.hide()\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tthis.tip.clear().showunder(this.input.node())\n\n\t\t\tconst resultsWrapper = this.tip.d.append('div')\n\t\t\tconst results = await this.searchItems()\n\n\t\t\tawait resultsWrapper\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'flex')\n\t\t\t\t.selectAll()\n\t\t\t\t.data(results.filter(r => r.items?.length >= 1))\n\t\t\t\t.enter()\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'block')\n\t\t\t\t.style('border-left', '0.5px solid lightgrey')\n\t\t\t\t.each(this.showResultsList)\n\t\t} catch (e: any) {\n\t\t\tif (e.stack) console.error(e.stack)\n\t\t\telse throwMsgWithFilePathAndFnName(e)\n\t\t}\n\t}\n\n\tasync showResultsList(\n\t\tthis: Element,\n\t\tresult: SearchGroupEntry & {\n\t\t\twrapper: Selection<Element, any, any, any>\n\t\t\ttitleDiv: Span\n\t\t}\n\t) {\n\t\tresult.wrapper = select(this)\n\t\tresult.wrapper.style('padding', '5px')\n\t\tresult.titleDiv = result.wrapper\n\t\t\t.append('span')\n\t\t\t.style('padding', '3px 0px 5px')\n\t\t\t.style('opacity', 0.65)\n\t\t\t.style('font-size', '0.8em')\n\t\t\t.text(result.title)\n\n\t\tawait result.wrapper\n\t\t\t.append('div')\n\t\t\t.classed('sjpp-result-wrapper', true)\n\t\t\t.selectAll('div')\n\t\t\t.data(result.items)\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.classed('sja_menuoption', true)\n\t\t\t.classed('sjpp-search-result', true)\n\t\t\t.attr(\n\t\t\t\t'data-testid',\n\t\t\t\td => `sjpp-search-result-${(d.name || d.label || d.title || d).toString().toLowerCase().replace(/\\s/g, '-')}`\n\t\t\t)\n\t\t\t.style('display', 'block')\n\t\t\t.style('padding-left', '10px')\n\t\t\t.style('background-color', result.color || '')\n\t\t\t.text((d: any) => d.name || d.label || d.title || d)\n\t\t\t.on('click', (event: MouseEvent, item: any) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tresult.callback(item)\n\t\t\t\t/** Use tip.hide() in callback,\n\t\t\t\t * This will allow the tip to remain open for other\n\t\t\t\t * use cases.\n\t\t\t\t * */\n\t\t\t})\n\t}\n\n\tasync enterSearch() {\n\t\tif (!this.input.property('value').trim()) return\n\t\tconst wrapper = this.tip.d.select('.sjpp-result-wrapper').node()\n\t\tconst result = this.tip.d.select('.sjpp-search-result').node()\n\t\tif (result != null && result.__data__) wrapper.__data__.callback(result.__data__)\n\t\telse {\n\t\t\tconst results = await this.searchItems()\n\t\t\tconst defaultCallback = results.filter(d => d.default)\n\t\t\tdefaultCallback[0].callback(this.input.property('value'))\n\t\t}\n\t\tthis.input.property('value', '')\n\t\tthis.tip.hide()\n\t}\n\n\tupdatePlaceholder(placeholder: string) {\n\t\tthis.input.attr('placeholder', placeholder)\n\t}\n}\n", "export class AppBase {\n\t//type: string\n\t//id: string\n\topts: any\n\tid: string\n\tstate: any\n\t// dom: any\n\t// config: any\n\n\tconstructor(opts) {\n\t\tthis.opts = this.validateOpts(opts)\n\t\tthis.id = opts.id\n\t}\n\n\tvalidateOpts(o: any = {}) {\n\t\tif (!o.holder) throw `missing opts.holder in the app constructor argument`\n\t\tif (!o.callbacks) o.callbacks = {}\n\t\tif (o.state) {\n\t\t\tif (!o.state.vocab) o.state.vocab = {}\n\t\t\tif (typeof o.state.vocab != 'object') throw 'opts.state.vocab{} is not an object'\n\t\t\tif (o.state.genome) {\n\t\t\t\to.state.vocab.genome = o.state.genome\n\t\t\t\tdelete o.state.genome\n\t\t\t}\n\t\t\tif (o.state.dslabel) {\n\t\t\t\to.state.vocab.dslabel = o.state.dslabel\n\t\t\t\tdelete o.state.dslabel\n\t\t\t}\n\t\t}\n\t\tif (o.app) {\n\t\t\tfor (const [k, v] of Object.entries(o.app)) {\n\t\t\t\to[k] = v\n\t\t\t}\n\t\t\tdelete o.app\n\t\t}\n\t\treturn o\n\t}\n}\n", "import { getCompInit } from '../rx'\nimport { select, selectAll } from 'd3-selection'\nimport { getNormalRoot } from '#filter'\nimport { isUsableTerm } from '#shared/termdb.usecase.js'\nimport { termInfoInit } from './termInfo'\nimport { TermTypeGroups, equals } from '#shared/terms.js'\n\nconst childterm_indent = '25px'\nexport const root_ID = 'root'\nexport const custom_variables_ID = '_Custom_Variables_'\n\n// when the total number of children at one branch exceeds this limit, the <div class=cls_termchilddiv> will scroll\n// this only count immediate children, not counting grandchildren\nconst minTermCount2scroll = 20\n// max height of aforementioned scrolling <div>\nconst scrollDivMaxHeight = '400px'\n\n// class names TODO they should be shared between test/tree.spec.js\nconst cls_termdiv = 'termdiv',\n\tcls_termchilddiv = 'termchilddiv',\n\tcls_termbtn = 'termbtn',\n\tcls_termlabel = 'termlabel',\n\tcls_termloading = 'termloading',\n\tcls_termcheck = 'termcheck'\n\n/*\n******************** EXPORTED\ntreeInit()\nroot_ID\n\n******************** constructor opts{}\n.holder\n.click_term()\n.disable_terms[]\n\n******************** exit/update/enter\ntermsById{} is bound to the DOM tree, to provide:\n- term label\n- list of children terms for a parent term\n\n\n******************* special flags\nroot term does not exist in the termdb, but is synthesized upon initializing instance, has the \"__tree_isroot\" flag\n\n\n\n******************* Recommended Component Code Organization\n\n(a) class (produces instance):\n- all methods expected by rx.api (main, etc)\n- all data processing code\n(b) setRenderers(self): attaches renderer methods\n(c) setInteractivity(self): attaches event handlers\n\n*/\n\nclass TdbTree {\n\tstatic type = 'tree'\n\n\t/*\n\tTermdb Tree Component\n\t- api-related and data processing code\n\t within this class declaration\n\t*/\n\tconstructor(opts) {\n\t\tthis.type = 'tree'\n\t\t// attach instance-specific methods via closure\n\t\tsetInteractivity(this)\n\t\tsetRenderers(this)\n\n\t\t// for terms waiting for server response for children terms, transient, not state\n\t\tthis.loadingTermSet = new Set()\n\t\tthis.termsByCohort = {}\n\t\tthis.expandAll = 'expandAll' in opts ? opts.expandAll : false\n\t\t//getCompInit(TdbTree) will set this.id, .app, .opts, .api\n\t}\n\n\tinit() {\n\t\tthis.dom = {\n\t\t\tholder: this.opts.holder.append('div')\n\t\t}\n\t}\n\n\treactsTo(action) {\n\t\tif (action.type.startsWith('tree_')) return true\n\t\tif (action.type.startsWith('filter_')) return true\n\t\tif (action.type.startsWith('cohort_')) return true\n\t\tif (action.type.startsWith('info_')) return true\n\t\tif (action.type.startsWith('submenu_')) return true\n\t\tif (action.type == 'app_refresh') return true\n\t\tif (action.type == 'set_term_type_group') return true\n\t}\n\n\tgetState(appState) {\n\t\tconst filter = getNormalRoot(appState.termfilter.filter)\n\t\tconst state = {\n\t\t\tisVisible: !appState.submenu.term,\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\texpandedTermIds: appState.tree.expandedTermIds,\n\t\t\tselectedTerms: appState.selectedTerms,\n\t\t\ttermfilter: { filter },\n\t\t\tusecase: appState.tree.usecase,\n\t\t\ttermTypeGroup: appState.termTypeGroup\n\t\t}\n\n\t\t// if cohort selection is enabled for the dataset, tree component needs to know which cohort is selected\n\t\tif (appState.termdbConfig.selectCohort) {\n\t\t\tstate.toSelectCohort = true\n\t\t\tconst choice = appState.termdbConfig.selectCohort.values[appState.activeCohort]\n\t\t\tif (choice) {\n\t\t\t\t// a selection has been made\n\t\t\t\tstate.cohortValuelst = choice.keys\n\t\t\t}\n\t\t}\n\t\treturn state\n\t}\n\n\tasync main() {\n\t\tif (this.state.termTypeGroup != TermTypeGroups.DICTIONARY_VARIABLES) {\n\t\t\t/* due to original design, in ./app.ts, tree component is always created\n\t\t\tin this app ui, the tree component only shows native/custom dictionary tree\n\t\t\tfor both cases, state.termTypeGroup value is TermTypeGroups.DICTIONARY_VARIABLES\n\t\t\t\n\t\t\tit must be noted that tree.js will not support non-dict term selection ui\n\t\t\tand it is wrong to attempt to do so\n\t\t\tthose are carried out in ./handlers/<termtype>\n\n\t\t\twhen the app ui is only for showing contents from non-dict term types, e.g. scrna gene exp\n\t\t\tthis check will avoid a dictionary ui from showing up alongside the ui and causing a bug\n\t\t\t*/\n\t\t\tthis.dom.holder.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tif (!this.state.isVisible) {\n\t\t\tthis.dom.holder.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tif (this.state.toSelectCohort) {\n\t\t\t// dataset requires a cohort to be selected\n\t\t\tif (!this.state.cohortValuelst) {\n\t\t\t\t// a selection has not been made; do not render tree\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\t// refer to the current cohort's termsById\n\t\tthis.termsById = this.getTermsById()\n\t\tconst root = this.termsById[root_ID]\n\t\troot.terms = await this.requestTermRecursive(root)\n\t\troot.terms.push(...(await this.mayGetCustomTerms()))\n\t\tthis.dom.holder.style('display', 'block')\n\t\tawait this.renderBranch(root, this.dom.holder)\n\t\tthis.dom.holder\n\t\t\t.selectAll('.termbtn, .sja_tree_click_term')\n\t\t\t.attr('tabindex', 0)\n\t\t\t.attr('data-testid', 'sjpp_termdbbutton')\n\t\t\t.on('keyup', event => {\n\t\t\t\tif (event.key == 'Enter') event.target.click()\n\t\t\t})\n\t}\n\n\tgetTermsById() {\n\t\tif (!(this.state.activeCohort in this.termsByCohort)) {\n\t\t\tthis.termsByCohort[this.state.activeCohort] = {\n\t\t\t\t[root_ID]: {\n\t\t\t\t\tid: root_ID,\n\t\t\t\t\t__tree_isroot: true // must not delete this flag\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this.termsByCohort[this.state.activeCohort]\n\t}\n\n\tasync requestTermRecursive(term) {\n\t\t/* will request child terms for this entire branch recursively\n\n\t\tmust synthesize request string (dataName) for every call\n\t\tand get cached result for the same dataName which has been requested before\n\t\tthis is to support future features\n\t\te.g. to show number of samples for each term that can change based on filters\n\t\twhere the same child terms already loaded must be re-requested with the updated filter parameters to update\n\n\t\tTODO determine when to re-request cached server response as needed\n\n\t\tCAUTION\n\t\twill be great if tree_collapse will not trigger this function\n\t\tbut hard to do given that main() has no way of telling what action was dispatched\n\t\tto prevent previously loaded .terms[] for the collapsing term from been wiped out of termsById,\n\t\tneed to add it back TERMS_ADD_BACK\n\t\t*/\n\t\tconst data = await this.app.vocabApi.getTermChildren(\n\t\t\tterm,\n\t\t\tthis.state.toSelectCohort ? this.state.cohortValuelst : null,\n\t\t\tthis.state.termfilter.filter\n\t\t)\n\t\tif (data.error) throw data.error\n\t\tif (!data.lst || data.lst.length == 0) {\n\t\t\t// do not throw exception; its children terms may have been filtered out\n\t\t\treturn []\n\t\t}\n\t\tconst terms = []\n\t\tfor (const t of data.lst) {\n\t\t\tconst copy = Object.assign({}, t)\n\t\t\tterms.push(copy)\n\t\t\t// rehydrate expanded terms as needed\n\t\t\t// fills in termsById, for recovering tree\n\t\t\tif (this.state.expandedTermIds.includes(copy.id)) {\n\t\t\t\tcopy.terms = await this.requestTermRecursive(copy)\n\t\t\t} else {\n\t\t\t\t// not an expanded term\n\t\t\t\t// if it's collapsing this term, must add back its children terms for toggle button to work\n\t\t\t\t// see flag TERMS_ADD_BACK\n\t\t\t\tconst t0 = this.termsById[copy.id || copy.name]\n\t\t\t\tif (t0 && t0.terms) {\n\t\t\t\t\tcopy.terms = t0.terms\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.termsById[copy.id || copy.name] = copy\n\t\t}\n\t\treturn terms\n\t}\n\n\tbindKey(term) {\n\t\treturn term.id || term.name\n\t}\n\n\tasync mayGetCustomTerms() {\n\t\tconst tws = await this.app.vocabApi.getCustomTerms()\n\t\tif (!tws.length) return []\n\n\t\tconst id = custom_variables_ID\n\t\tconst parentTerm = {\n\t\t\tname: 'Custom Variables',\n\t\t\tid: id,\n\t\t\tisleaf: false,\n\t\t\tincluded_types: ['categorical'],\n\t\t\tchild_types: ['categorical'],\n\t\t\tterms: tws.map(tw => {\n\t\t\t\tthis.termsById[tw.term.id || tw.term.name] = tw.term\n\t\t\t\ttw.term.isleaf = true\n\t\t\t\treturn tw.term\n\t\t\t})\n\t\t}\n\t\tthis.termsById[id] = parentTerm\n\t\treturn [parentTerm]\n\t}\n}\n\nexport const treeInit = getCompInit(TdbTree)\n\nfunction setRenderers(self) {\n\t/*\n\t\tSet static renderer code here for HTML, SVGs, etc \n\n\t\tClosured reference to object instance as self\n\t\tversus alternative \"this\" context such as DOM element\n\n\t\tself: a TdbTree instance\n\t*/\n\t// !!! no free-floating variable declarations here !!!\n\t// set properties within the class declarations\n\n\t/*\n\tterm{}\n\t\tmust be from termsById\n\t\t.terms[]\n\t\t\tlist of children terms\n\tdiv\n\t\tthe childdiv of this term\n\tbutton\n\t\toptional, the toggle button\n\t*/\n\tself.renderBranch = (term, div, button) => {\n\t\tif (!term || !term.terms) return\n\n\t\tif (term.terms.length >= minTermCount2scroll) {\n\t\t\t// too many children. scroll\n\t\t\tif (div.classed('sjpp_show_scrollbar')) {\n\t\t\t\t// already scrolling. the style has been applied from a previous click. do not reset\n\t\t\t} else {\n\t\t\t\tdiv\n\t\t\t\t\t.style('max-height', scrollDivMaxHeight)\n\t\t\t\t\t.style('padding', '10px')\n\t\t\t\t\t.style('resize', 'vertical')\n\t\t\t\t\t.classed('sjpp_show_scrollbar', true)\n\n\t\t\t\t/***************************\n\t\t\t\tremaining issues\n\n\t\t\t\t1. if there's a way to make scrollbar always visible, as a clear indication you need to scroll to see more hidden stuff\n\t\t\t\t*/\n\t\t\t}\n\t\t}\n\n\t\t// add disabled terms to opts.disable_terms\n\t\tif (self.opts.disable_terms) {\n\t\t\tterm.terms.forEach(t => {\n\t\t\t\tif (t.disabled) self.opts.disable_terms.push(t)\n\t\t\t})\n\t\t}\n\n\t\tself.included_terms = []\n\t\tif (self.state.usecase) {\n\t\t\tfor (const t of term.terms) {\n\t\t\t\tconst uses = isUsableTerm(t, self.state.usecase, self.app.vocabApi.termdbConfig)\n\t\t\t\tif (uses && uses.size) {\n\t\t\t\t\tself.included_terms.push(t)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tself.included_terms.push(...term.terms)\n\t\t}\n\n\t\tconst id = term.id || term.name\n\t\tif (!(id in self.termsById) || !self.included_terms.length) {\n\t\t\tdiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\n\t\tif (self.loadingTermSet.has(term.id)) {\n\t\t\tself.loadingTermSet.delete(term.id)\n\t\t\tdiv.select('.' + cls_termloading).remove()\n\t\t}\n\n\t\tconst expandedTermIds = self.state.expandedTermIds\n\t\tif (!expandedTermIds.includes(term.id)) {\n\t\t\tdiv.style('display', 'none')\n\t\t\tif (button) button.text('+')\n\t\t\treturn\n\t\t}\n\t\tdiv.style('display', 'block')\n\t\tif (button) button.text('-')\n\n\t\tconst divs = div.selectAll('.' + cls_termdiv).data(self.included_terms, self.bindKey)\n\n\t\tdivs.exit().each(self.hideTerm)\n\n\t\tdivs.each(self.updateTerm)\n\n\t\tdivs.enter().append('div').each(self.addTerm)\n\n\t\tfor (const child of term.terms) {\n\t\t\tif (expandedTermIds.includes(child.id)) {\n\t\t\t\tself.renderBranch(\n\t\t\t\t\tchild,\n\t\t\t\t\tdiv.selectAll('.' + cls_termchilddiv).filter(i => i.id == child.id),\n\t\t\t\t\tdiv.selectAll('.' + cls_termbtn).filter(i => i.id == child.id)\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t// this == the d3 selected DOM node\n\tself.hideTerm = function (term) {\n\t\tconst id = term.id || term.name\n\t\tif (id in self.termsById && self.state.expandedTermIds.includes(term.id)) return\n\t\tselect(this).style('display', 'none')\n\t}\n\n\tself.updateTerm = function (term) {\n\t\tconst div = select(this)\n\t\tconst id = term.id || term.name\n\t\tif (!(id in self.termsById)) {\n\t\t\tdiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\n\t\tconst termIsDisabled = self.opts?.disable_terms?.some(t => equals(t, term))\n\t\tconst uses = isUsableTerm(term, self.state.usecase, self.app.vocabApi.termdbConfig)\n\n\t\tdiv.style('display', '')\n\t\tconst isExpanded = self.state.expandedTermIds.includes(term.id)\n\t\tdiv.select('.' + cls_termbtn).text(isExpanded ? '-' : '+')\n\t\t// update other parts if needed, e.g. label\n\t\tdiv.select('.' + cls_termchilddiv).style('display', isExpanded ? 'block' : 'none')\n\n\t\tconst tid = term.id || term.name\n\t\tconst isSelected = self.state.selectedTerms.find(t => (t.id ? t.id === id : t.name == id) && t.type === term.type)\n\t\tdiv\n\t\t\t.select('.' + cls_termlabel)\n\t\t\t.style(\n\t\t\t\t'background-color',\n\t\t\t\t!uses.has('plot') || termIsDisabled ? '' : isSelected ? 'rgba(255, 194, 10,0.5)' : '#cfe2f3'\n\t\t\t)\n\t\tdiv\n\t\t\t.select('.' + cls_termcheck)\n\t\t\t.style('display', uses.has('plot') && isSelected && !termIsDisabled ? 'inline-block' : 'none')\n\t}\n\n\tself.addTerm = async function (term) {\n\t\tconst termIsDisabled = self.opts?.disable_terms?.some(t => equals(t, term))\n\t\tconst uses = isUsableTerm(term, self.state.usecase, self.app.vocabApi.termdbConfig)\n\n\t\tconst div = select(this)\n\t\t\t.attr('class', cls_termdiv)\n\t\t\t.style('margin', term.isleaf ? '' : '2px')\n\t\t\t.style('padding', '0px 5px')\n\n\t\tif (uses.has('branch')) {\n\t\t\tdiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption ' + cls_termbtn)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('padding', '4px 9px')\n\t\t\t\t.style('font-family', 'courier')\n\t\t\t\t.text('+')\n\t\t\t\t// always allow show/hide children even this term is already in use\n\t\t\t\t.on('click', event => {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\tself.toggleBranch(term)\n\t\t\t\t})\n\t\t\tif (self.expandAll) self.toggleBranch(term)\n\t\t}\n\n\t\tconst id = term.id || term.name\n\t\tconst isSelected = self.state.selectedTerms.find(t => t.id === id && t.type === term.type)\n\t\tconst labeldiv = div\n\t\t\t.append('div')\n\t\t\t.attr('class', cls_termlabel)\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('padding', '5px')\n\t\t\t.style('opacity', termIsDisabled ? 0.4 : null)\n\t\t\t.text(term.name)\n\n\t\tlet infoIcon_div //Empty div for info icon if termInfoInit is called\n\t\tif (term.hashtmldetail) {\n\t\t\tinfoIcon_div = div.append('div').style('display', 'inline-block')\n\t\t}\n\n\t\tif (uses.size > 0) {\n\t\t\tif (termIsDisabled) {\n\t\t\t\tlabeldiv\n\t\t\t\t\t.attr('class', 'sja_tree_click_term_disabled ' + cls_termlabel)\n\t\t\t\t\t.style('padding', '5px 8px')\n\t\t\t\t\t.style('margin', '1px 0px')\n\t\t\t\t\t.style('opacity', 0.7)\n\t\t\t} else if (uses.has('plot')) {\n\t\t\t\tlabeldiv\n\t\t\t\t\t// need better css class\n\t\t\t\t\t.attr('class', 'ts_pill sja_filter_tag_btn sja_tree_click_term ' + cls_termlabel)\n\t\t\t\t\t.style('color', 'black')\n\t\t\t\t\t.style('padding', '5px 8px')\n\t\t\t\t\t.style('border-radius', '6px')\n\t\t\t\t\t.style('background-color', isSelected ? 'rgba(255, 194, 10,0.5)' : '#cfe2f3')\n\t\t\t\t\t.style('margin', '1px 0px')\n\t\t\t\t\t.style('cursor', 'default')\n\t\t\t\t\t.on('click', () => self.clickTerm(term))\n\t\t\t}\n\n\t\t\t//show sample count for a term\n\t\t\tif (term.samplecount !== undefined) {\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('font-size', '.8em')\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin-left', '5px')\n\t\t\t\t\t.style('color', term.samplecount ? '#777' : '#ddd')\n\t\t\t\t\t.text('n=' + term.samplecount)\n\t\t\t}\n\t\t}\n\t\t//Creates the info icon and description div from termInfo.js\n\t\tif (term.hashtmldetail) {\n\t\t\ttermInfoInit({\n\t\t\t\tvocabApi: self.app.vocabApi,\n\t\t\t\ticon_holder: infoIcon_div,\n\t\t\t\tcontent_holder: div.append('div'),\n\t\t\t\tid: term.id,\n\t\t\t\tstate: { term }\n\t\t\t})\n\t\t}\n\n\t\tlet selected_checkbox\n\t\tif (self.opts.submit_lst) {\n\t\t\tselected_checkbox = div\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', cls_termcheck)\n\t\t\t\t.style('color', '#008000')\n\t\t\t\t.style('display', isSelected ? 'inline-block' : 'none')\n\t\t\t\t.html('✓')\n\t\t}\n\n\t\tif (!term.isleaf) {\n\t\t\tdiv.append('div').attr('class', cls_termchilddiv).style('padding-left', childterm_indent)\n\t\t}\n\t}\n}\n\nfunction setInteractivity(self) {\n\t/*\n\t\tSet interactivity code here, for mouseovers, clicks, etc.\n\n\t\tClosured reference to object instance as self\n\t\tversus alternative \"this\" context such as DOM element\n\n\t\tself: a TdbTree instance\n\t*/\n\t// !!! no free-floating variable declarations here !!!\n\t// use self in TdbTree constructor to create properties\n\n\tself.toggleBranch = function (term) {\n\t\t//event.stopPropagation()\n\t\tif (term.isleaf) return\n\t\tconst t0 = self.termsById[term.id || term.name]\n\t\tif (!t0) throw 'invalid term id'\n\n\t\tif (!t0.terms) {\n\t\t\t// to load child term with request, guard against repetitive clicking\n\t\t\t// TERMS_ADD_BACK\n\t\t\t// this requires .terms[] to be added back when updated by requestTermRecursive()\n\t\t\tif (self.loadingTermSet.has(t0.id)) return\n\t\t\tself.loadingTermSet.add(t0.id)\n\t\t\tselect(this.parentNode)\n\t\t\t\t.selectAll('.' + cls_termchilddiv)\n\t\t\t\t.filter(d => d.id === t0.id)\n\t\t\t\t.style('display', 'block')\n\t\t\t\t.append('div')\n\t\t\t\t.text('Loading...')\n\t\t\t\t.attr('class', cls_termloading)\n\t\t\t\t.style('opacity', 0.5)\n\t\t\t\t.style('padding', '5px')\n\t\t}\n\n\t\tconst expanded = self.state.expandedTermIds.includes(term.id)\n\t\tconst type = expanded ? 'tree_collapse' : 'tree_expand'\n\t\tself.app.dispatch({ type, termId: term.id })\n\t}\n\n\tself.clickTerm = async term => {\n\t\tif (self.opts.click_term2select_tvs) {\n\t\t\tself.app.dispatch({ type: 'submenu_set', submenu: { term, type: 'tvs' } })\n\t\t\treturn\n\t\t}\n\n\t\tif (self.opts.click_term_wrapper) {\n\t\t\tself.opts.click_term_wrapper(term)\n\t\t\treturn\n\t\t}\n\n\t\tif (self.opts.submit_lst) {\n\t\t\tconst id = term.id || term.name\n\t\t\tconst i = self.state.selectedTerms.findIndex(t => (t.id ? t.id === id : t.name == id) && t.type === term.type)\n\t\t\tif (i == -1) {\n\t\t\t\tself.app.dispatch({\n\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\tstate: {\n\t\t\t\t\t\tselectedTerms: [...self.state.selectedTerms, term]\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tconst selectedTerms = self.state.selectedTerms.slice(0)\n\t\t\t\tselectedTerms.splice(i, 1)\n\t\t\t\tself.app.dispatch({\n\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\tstate: { selectedTerms }\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tthrow 'missing term click callback'\n\t}\n}\n", "import { Tabs } from '#dom'\nimport { type AppApi, getCompInit } from '../rx'\nimport { TermTypeGroups, TermTypes, typeGroup, numericTypes, isSingleCellTerm } from '#shared/terms.js'\nimport type { Term } from '#types'\nimport type { ClientGenome } from '../types/clientGenome'\nimport { select } from 'd3-selection'\n\n/*\nWhen searching for terms, depending on the use case, only certain types of terms are allowed.\nThe tree target is used to determine the allowed term types.\nNOTE: dataset-specific overrides may be applied when the TermTypeSearch is initialized\n */\n\nconst {\n\tSNP_LOCUS,\n\tSNP_LIST,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tTERM_COLLECTION,\n\tMUTATION_CNV_FUSION,\n\tMETABOLITE_INTENSITY,\n\tDICTIONARY_VARIABLES,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tDNA_METHYLATION,\n\tPROTEOME_ABUNDANCE,\n\tSSGSEA\n} = TermTypeGroups\n\nexport const useCasesExcluded = {\n\tmatrix: [SNP_LOCUS, SNP_LIST, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tfacet: [SNP_LOCUS, SNP_LIST, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tfilter: [SNP_LOCUS, SNP_LIST, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tdictionary: [SNP_LOCUS, SNP_LIST],\n\tsummary: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tsummaryInput: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tbarchart: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION],\n\tviolin: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION],\n\tsampleScatter: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION],\n\tcuminc: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tMETABOLITE_INTENSITY,\n\t\tISOFORM_EXPRESSION,\n\t\tPROTEOME_ABUNDANCE,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t],\n\tdataDownload: [\n\t\t//SNP_LOCUS, //this tabs require that the handler for this term type to be implemented\n\t\t//SNP_LIST, //this tabs require that the handler for this term type to be implemented\n\t\tMUTATION_CNV_FUSION,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t], //Later on can support other term types like snplocus, snplst, geneVariant, non dictionary terms\n\tsurvival: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\t//Used from the termsetting when searching for a term, as any term with categories is allowed\n\tdefault: [SNP_LOCUS, SNP_LIST, TERM_COLLECTION, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tregression: [SNP_LIST, SNP_LOCUS, TERM_COLLECTION, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION],\n\tmetaboliteIntensity: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tDICTIONARY_VARIABLES,\n\t\tGENE_EXPRESSION,\n\t\tISOFORM_EXPRESSION,\n\t\tDNA_METHYLATION,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t],\n\tproteomeAbundance: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tDICTIONARY_VARIABLES,\n\t\tGENE_EXPRESSION,\n\t\tISOFORM_EXPRESSION,\n\t\tDNA_METHYLATION,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION,\n\t\tMETABOLITE_INTENSITY\n\t],\n\tproteinView: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tDICTIONARY_VARIABLES,\n\t\tGENE_EXPRESSION,\n\t\tISOFORM_EXPRESSION,\n\t\tDNA_METHYLATION,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION,\n\t\tMETABOLITE_INTENSITY\n\t],\n\tgeneExpression: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tDICTIONARY_VARIABLES,\n\t\tISOFORM_EXPRESSION,\n\t\tMETABOLITE_INTENSITY,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t],\n\tisoformExpression: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tDICTIONARY_VARIABLES,\n\t\tGENE_EXPRESSION,\n\t\tMETABOLITE_INTENSITY,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t],\n\tcorrelationVolcano: [SNP_LOCUS, SNP_LIST, MUTATION_CNV_FUSION, TERM_COLLECTION],\n\n\tnumericDictTermCluster: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tGENE_EXPRESSION,\n\t\tMETABOLITE_INTENSITY,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION,\n\t\tDNA_METHYLATION\n\t],\n\n\ttermCollections: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tGENE_EXPRESSION,\n\t\tISOFORM_EXPRESSION,\n\t\tDNA_METHYLATION,\n\t\tMETABOLITE_INTENSITY,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t],\n\trunChart2: [\n\t\tSNP_LOCUS,\n\t\tSNP_LIST,\n\t\tMUTATION_CNV_FUSION,\n\t\tGENE_EXPRESSION,\n\t\tISOFORM_EXPRESSION,\n\t\tDNA_METHYLATION,\n\t\tMETABOLITE_INTENSITY,\n\t\tPROTEOME_ABUNDANCE,\n\t\tSSGSEA,\n\t\tTERM_COLLECTION,\n\t\tSINGLECELL_CELLTYPE,\n\t\tSINGLECELL_GENE_EXPRESSION\n\t]\n}\n\nexport type Tab = {\n\tlabel: string // required by Tabs\n\ttermTypeGroup: string // required for comparing\n\ttermType: string\n\tcontentHolder?: any // added by Tabs\n\tcallback: (...args: any[]) => any\n}\n\nexport class TermTypeSearch {\n\tstatic type = 'termTypeSearch'\n\n\tdom: any\n\tapp: any\n\ttype: string\n\ttypes: Array<string> // array of term types available to ds\n\ttabs: Tab[]\n\tstate: any\n\tgenomeObj: ClientGenome\n\thandlerByType: {\n\t\t[termType: string]: any\n\t}\n\tclick_term: (term: Term) => void\n\tsubmit_lst?: (terms: Array<Term>) => void\n\tuseCasesExcluded: {\n\t\t[useCaseTarget: string]: string[]\n\t}\n\n\tconstructor(opts) {\n\t\tthis.type = TermTypeSearch.type\n\t\tthis.genomeObj = opts.genome\n\t\tthis.click_term = opts.click_term\n\t\tthis.submit_lst = opts.submit_lst\n\t\tconst selectedTermsDiv = opts.topbar\n\t\t\t.append('div')\n\t\t\t.style('width', '99%')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('flex-wrap', 'wrap')\n\t\t\t.style('gap', '5px')\n\t\t\t.style('min-height', '20px')\n\t\t\t.style('margin', '10px 0px')\n\t\t\t.style('padding', '6px 2px')\n\t\tthis.types = []\n\t\tthis.tabs = []\n\t\tthis.handlerByType = {}\n\t\tthis.dom = { holder: opts.holder, topbar: opts.topbar, selectedTermsDiv, submitDiv: opts.submitDiv }\n\t\t// do not overwrite the original copy; may apply overrides in init()\n\t\tthis.useCasesExcluded = structuredClone(useCasesExcluded)\n\t}\n\n\tasync init(appState) {\n\t\tthis.types = appState.allowedTermTypes || this.app.vocabApi.termdbConfig?.allowedTermTypes || ['categorical'] //if no types it is a custom vocab for testing\n\t\tif (!this.types) return\n\n\t\tif (this.app.vocabApi.termdbConfig?.useCasesExcluded)\n\t\t\tObject.assign(this.useCasesExcluded, this.app.vocabApi.termdbConfig?.useCasesExcluded)\n\n\t\tconst tabs: Tab[] = getAllowedTabs(appState, this)\n\t\tfor (const tab of tabs) {\n\t\t\ttry {\n\t\t\t\tif (!this.usesDefaultSearch(tab.termTypeGroup)) {\n\t\t\t\t\tconst _ = await import(`./handlers/${tab.termType}.ts`)\n\t\t\t\t\tthis.handlerByType[tab.termType] = await new _.SearchHandler()\n\t\t\t\t\tif (!this.handlerByType[tab.termType].init) throw new Error('init not implemented')\n\t\t\t\t}\n\t\t\t\tthis.addLoadTopTerms(tab.termType)\n\t\t\t} catch (e) {\n\t\t\t\tthrow new Error(`error with handler='./handlers/${tab.termType}.ts': ${e}`)\n\t\t\t}\n\t\t\tthis.tabs.push(tab)\n\t\t}\n\n\t\tif (this.submit_lst) {\n\t\t\t//multiple terms can be selected\n\t\t\tthis.dom.clearbt = this.dom.submitDiv\n\t\t\t\t.append('button')\n\t\t\t\t.style('margin-left', '5px')\n\t\t\t\t.text('Clear')\n\t\t\t\t.on('click', () => this.selectTerms([]))\n\t\t}\n\n\t\tif (this.tabs.length == 0) throw 'No term types allowed for this use case'\n\n\t\tif (this.tabs.length == 1) return // only one tab (group of term type); return and do not show a lone tab\n\n\t\t// TODO: should not trigger Tabs.main() here, may move this code to TermTypeSearch.main() if there is no Tabs component yet\n\t\tnew Tabs({\n\t\t\tholder: this.dom.holder,\n\t\t\ttabsPosition: 'vertical',\n\t\t\tlinePosition: 'right',\n\t\t\ttabs: this.tabs\n\t\t}).main()\n\n\t\tfor (const t of this.tabs) {\n\t\t\tconst holder = t.contentHolder.style('padding-left', '20px')\n\t\t\tholder.append('div')\n\t\t}\n\t}\n\n\treactsTo(action) {\n\t\tif (action.type.startsWith('submenu_')) return true //may change tree visibility\n\t\tif (action.type == 'set_term_type_group') return true\n\t\tif (action.type == 'app_refresh') return true\n\t}\n\n\tmain() {\n\t\tthis.dom.holder.style('display', this.state.isVisible ? 'inline-block' : 'none')\n\t\tthis.dom.topbar.style('display', this.state.isVisible ? 'inline-block' : 'none')\n\t\tif (this.submit_lst) {\n\t\t\tthis.renderTermsSelected()\n\t\t\tthis.dom.selectedTermsDiv.style('display', this.state.selectedTerms.length > 0 ? 'inline-block' : 'none')\n\t\t} else this.dom.selectedTermsDiv.style('display', 'none')\n\t\tthis.renderTermsSelected()\n\t\tif (this.dom.clearbt) this.dom.clearbt.property('disabled', this.state.selectedTerms.length == 0)\n\t}\n\n\trenderTermsSelected() {\n\t\tthis.dom.selectedTermsDiv.selectAll('*').remove()\n\t\tthis.dom.selectedTermsDiv\n\t\t\t.selectAll('div')\n\t\t\t.data(this.state.selectedTerms)\n\t\t\t.enter()\n\t\t\t.append('div')\n\t\t\t.attr('aria-label', 'Click to delete')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('tabindex', 0)\n\t\t\t.style('position', 'relative')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('padding', '5px 16px 5px 9px')\n\t\t\t.style('margin-left', '5px')\n\t\t\t.each(renderTerm)\n\t\t\t.on('click', (e, t) => this.deleteTerm(e, t))\n\t\t\t.on('mouseover', function (event) {\n\t\t\t\tconst deleteSvg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#000\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\">\n\t\t\t\t<path stroke='#f00' d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z\"/>\n\t\t\t\t</svg>`\n\t\t\t\tconst div = select(event.target)\n\t\t\t\tdiv\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('margin-left', '4px')\n\t\t\t\t\t.classed('sjpp_deletebt', true)\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('position', 'absolute')\n\t\t\t\t\t.style('right', '0px')\n\t\t\t\t\t.style('top', '0px')\n\n\t\t\t\t\t.style('transform', 'scale(0.6)')\n\t\t\t\t\t.style('pointer-events', 'none')\n\t\t\t\t\t.html(deleteSvg)\n\t\t\t})\n\t\t\t.on('mouseout', function (event) {\n\t\t\t\tselect(event.target).select('.sjpp_deletebt').remove()\n\t\t\t})\n\n\t\tfunction renderTerm(this: any, term) {\n\t\t\tconst div = select(this).style('border-radius', '5px')\n\t\t\tdiv\n\t\t\t\t.insert('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.html(term.gene || term.name)\n\t\t}\n\t}\n\n\tdeleteTerm(e, t) {\n\t\tconst i = this.state.selectedTerms.findIndex(term => term.name === t.name)\n\t\tif (i != -1) {\n\t\t\tconst selectedTerms = [...this.state.selectedTerms]\n\t\t\tselectedTerms.splice(i, 1)\n\t\t\tthis.app.dispatch({\n\t\t\t\ttype: 'app_refresh',\n\t\t\t\tstate: { selectedTerms }\n\t\t\t})\n\t\t}\n\t}\n\n\tgetState(appState) {\n\t\treturn {\n\t\t\tdslabel: appState.dslabel,\n\t\t\ttermTypeGroup: appState.termTypeGroup, //See comment in store for usage\n\t\t\tusecase: appState.tree.usecase,\n\t\t\tisVisible: !appState.submenu.term,\n\t\t\tselectedTerms: appState.selectedTerms,\n\t\t\ttermfilter: appState.termfilter\n\t\t}\n\t}\n\n\tusesDefaultSearch(termTypeGroup) {\n\t\treturn termTypeGroup == DICTIONARY_VARIABLES || termTypeGroup == METABOLITE_INTENSITY\n\t}\n\n\tasync addLoadTopTerms(type) {\n\t\tif (type == TermTypes.METABOLITE_INTENSITY)\n\t\t\t//maybe later other types are supported\n\t\t\tthis.dom.submitDiv\n\t\t\t\t.append('button')\n\t\t\t\t.style('margin-left', '5px')\n\t\t\t\t.text('Load top terms')\n\t\t\t\t.on('click', async () => {\n\t\t\t\t\tconst args = {\n\t\t\t\t\t\tfilter0: this.state.termfilter.filter0,\n\t\t\t\t\t\tfilter: this.state.termfilter.filter,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t\tconst result = await this.app.vocabApi.getTopTermsByType(args)\n\t\t\t\t\tthis.selectTerms(result.terms)\n\t\t\t\t})\n\t}\n\n\tasync selectTerms(terms) {\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'app_refresh',\n\t\t\tstate: {\n\t\t\t\tselectedTerms: terms\n\t\t\t}\n\t\t})\n\t}\n\n\tasync setTermTypeGroup(type, termTypeGroup, details = {}) {\n\t\tawait this.app.dispatch({ type: 'set_term_type_group', value: termTypeGroup })\n\t\tconst tab = this.tabs.find(tab => tab.termTypeGroup == termTypeGroup)\n\t\tif (!tab) return\n\t\tconst holder = tab.contentHolder\n\t\tholder.selectAll('*').remove()\n\t\tif (tab.termTypeGroup != DICTIONARY_VARIABLES && tab.termTypeGroup != METABOLITE_INTENSITY) {\n\t\t\t//When called in init before main(), this.state is not set.\n\t\t\t//Get the state from the app to pass it to the handlers.\n\t\t\tconst { usecase } = this.state?.usecase ? this.state : this.getState(this.app.getState())\n\t\t\tconst handler = this.handlerByType[type]\n\t\t\tawait handler.init({\n\t\t\t\tholder,\n\t\t\t\tapp: this.app,\n\t\t\t\tgenomeObj: this.genomeObj,\n\t\t\t\tcallback: term => this.selectTerm(term),\n\t\t\t\tdetails,\n\t\t\t\tusecase\n\t\t\t})\n\t\t}\n\t}\n\t//This callback will be called by the handlers when a term is selected\n\tselectTerm(term) {\n\t\tif (this.click_term) this.click_term(term)\n\t\telse if (this.submit_lst) {\n\t\t\tconst t = term.term || term\n\t\t\tif (term.type == TermTypes.TERM_COLLECTION) {\n\t\t\t\tthis.app.dispatch({\n\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\tstate: {\n\t\t\t\t\t\tselectedTerms: [t]\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.app.dispatch({\n\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\tstate: {\n\t\t\t\t\t\tselectedTerms: [...this.state.selectedTerms, t]\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t} else {\n\t\t\tthis.app.dispatch({\n\t\t\t\ttype: 'submenu_set',\n\t\t\t\tsubmenu: {\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\tterm: term.term?.type == 'geneVariant' ? this.getDtTerm(term) : term\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\t// get child dt term from geneVariant term to use for tvs\n\tgetDtTerm(tw) {\n\t\tif (tw.term.type != 'geneVariant') throw 'term.type is not geneVariant'\n\t\tif (tw.q.type != 'predefined-groupset') throw 'q.type must be predefined-groupset'\n\t\tconst dtTerm = tw.term.childTerms[tw.q.predefined_groupset_idx]\n\t\tif (!dtTerm) throw 'dtTerm not found'\n\t\treturn dtTerm\n\t}\n}\n\nexport const TermTypeSearchInit = getCompInit(TermTypeSearch)\n\nexport type SearchHandlerOpts = {\n\tholder: any\n\tapp: AppApi\n\tgenomeObj: any\n\tcallback: (arg0: { gene: string; name: string; type: string }) => void\n\tdetails: any\n\tusecase: { target: string; detail: string; [index: string]: any }\n}\n\nexport function getAllowedTabs(state, self) {\n\tconst tabs: Tab[] = []\n\tconst allowedTermTypes = state.allowedTermTypes || self.types\n\tfor (const type of allowedTermTypes) {\n\t\tconst termTypeGroup = typeGroup[type]\n\n\t\tif (tabs.some(tab => tab.termTypeGroup == termTypeGroup)) {\n\t\t\t// tab entry exists for this group (possible because multiple term types can match to same group)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (type == TermTypes.TERM_COLLECTION) {\n\t\t\tconst collections = self.app.vocabApi?.termdbConfig?.termCollections\n\t\t\tif (!collections) throw new Error('termdbConfig.termCollections missing')\n\t\t\t// special: one tab for each collection, if permitted by usecase\n\t\t\tfor (const c of collections) {\n\t\t\t\tif (c.type != 'categorical' && c.type != 'numeric') throw new Error('tc.type not categorical/numeric')\n\t\t\t\tswitch (state.tree.usecase?.target) {\n\t\t\t\t\tcase 'dictionary':\n\t\t\t\t\tcase 'filter':\n\t\t\t\t\tcase 'matrix':\n\t\t\t\t\tcase 'facet':\n\t\t\t\t\t\tif (c.type == 'categorical') continue // not supported yet\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttabs.push({\n\t\t\t\t\tlabel: c.name,\n\t\t\t\t\ttermType: type,\n\t\t\t\t\ttermTypeGroup,\n\t\t\t\t\tcallback: () => self.setTermTypeGroup(type, termTypeGroup, c)\n\t\t\t\t})\n\t\t\t}\n\t\t} else {\n\t\t\tlet label = termTypeGroup // label displayed on the tab for this group. might be customized as below\n\t\t\tif (type == TermTypes.GENE_VARIANT) {\n\t\t\t\tconst labels: string[] = []\n\t\t\t\tif (self.app.vocabApi.termdbConfig.queries.snvindel) labels.push('Mutation')\n\t\t\t\tif (self.app.vocabApi.termdbConfig.queries.cnv) labels.push('CNV')\n\t\t\t\tif (self.app.vocabApi.termdbConfig.queries.svfusion) labels.push('Fusion')\n\t\t\t\tif (labels.length == 0) continue\n\t\t\t\tlabel = labels.join('/')\n\t\t\t}\n\n\t\t\ttabs.push({\n\t\t\t\tlabel,\n\t\t\t\ttermType: type,\n\t\t\t\ttermTypeGroup,\n\t\t\t\tcallback: () => self.setTermTypeGroup(type, termTypeGroup)\n\t\t\t})\n\t\t}\n\t}\n\treturn tabs\n}\n\n// state = app.getState()\n// used directly by termdb/store.ts init() to not make the initial state\n// dependent on any component init()\nexport function getAllowedTermTypesForUseCase(state, app) {\n\tconst allowedTermTypes: string[] = []\n\tconst types = app.vocabApi.termdbConfig?.allowedTermTypes || ['categorical']\n\tconst usecase = state.tree.usecase\n\tconst { target, detail } = usecase\n\tconst dsUseCasesExcluded = Object.assign(\n\t\tstructuredClone(useCasesExcluded),\n\t\tapp.vocabApi.termdbConfig?.useCasesExcluded || {}\n\t)\n\n\tfor (const type of types) {\n\t\tif (type == TermTypes.SNP_LIST || type == TermTypes.SNP_LOCUS) {\n\t\t\t// do not create tabs for snplst/snplocus terms as these\n\t\t\t// terms do not have termdb search handlers\n\t\t\tcontinue\n\t\t}\n\n\t\tconst termTypeGroup = typeGroup[type]\n\t\tif (!termTypeGroup) {\n\t\t\tthrow new Error(`should not happen: no group for a term type = ${type}`)\n\t\t}\n\t\t/* based on usecase, determine if to allow group of this term type\n\t\t- false: continue\n\t\t- true: create tab entry\n\t\t*/\n\n\t\tif (usecase?.specialCase?.type == 'singleCell') {\n\t\t\t//Limit the tree to only single cell types when use case is single cell\n\t\t\tif (!isSingleCellTerm({ type })) continue\n\t\t} else {\n\t\t\t// not singlecell! in cohort mode, disallow sc terms\n\t\t\tif (isSingleCellTerm({ type })) continue\n\t\t}\n\n\t\tif (target && dsUseCasesExcluded[target]?.includes(termTypeGroup)) continue\n\t\tif (target == 'regression') {\n\t\t\t//regression snplst/snplocus cases will be handled when the search handler is added\n\t\t\tif (type == TermTypes.SNP) continue // same functionality is covered by snplst/snplocus terms\n\t\t\tif (type == TermTypes.GENE_VARIANT && detail != 'independent') continue\n\t\t\tif (type == TermTypes.GENE_EXPRESSION && detail != 'independent') continue\n\t\t\tif (type == TermTypes.DNA_METHYLATION && detail != 'independent') continue\n\t\t\tif (type == TermTypes.SSGSEA && detail != 'independent') continue\n\t\t}\n\n\t\tif (target == 'sampleScatter') {\n\t\t\tif (detail == 'numeric' && !numericTypes.has(type)) continue\n\t\t\t//Limit the tree to only single cell types when use case is single cell\n\t\t}\n\n\t\tif ((target == 'survival' || target == 'cuminc') && termTypeGroup != DICTIONARY_VARIABLES) {\n\t\t\tif (detail == 'term') continue\n\t\t}\n\n\t\tif (target == 'dataDownload') {\n\t\t\tif (type == TermTypes.SNP) continue // same functionality is covered by snplst/snplocus terms\n\t\t}\n\n\t\t//////////////////////////////////////\n\t\t// reaches here means the group for this term type will be shown!!\n\t\tallowedTermTypes.push(type)\n\t}\n\treturn allowedTermTypes\n}\n", "import { StoreApi, StoreBase, type AppApi, type RxStore } from '#rx'\nimport { root_ID, custom_variables_ID } from './tree'\nimport { getFilterItemByTag, findParent } from '#filter'\nimport { isUsableTerm } from '#shared/termdb.usecase.js'\nimport { getAllowedTermTypesForUseCase, useCasesExcluded } from './TermTypeSearch.ts'\nimport { typeGroup } from '#shared/terms.js'\n\nconst defaultState = {\n\theader_mode: 'search_only',\n\t// will be ignored if there is no dataset termdb.selectCohort\n\t// or value will be set to match a filter node that has been tagged\n\t// as 'cohortfilter' in state.termfilter.filter\n\tactiveCohort: 0,\n\ttree: {\n\t\tusecase: {},\n\t\texpandedTermIds: []\n\t},\n\tsubmenu: {\n\t\t// type: 'tvs', may add other types later\n\t\t// term: {} or undefined\n\t},\n\tsearch: { isVisible: true },\n\tselectedTerms: [],\n\ttermfilter: {\n\t\tfilter: {\n\t\t\ttype: 'tvslst',\n\t\t\tin: true,\n\t\t\tjoin: '',\n\t\t\tlst: []\n\t\t}\n\t}\n}\n\n// one store for the whole tdb app\nclass TdbStore extends StoreBase implements RxStore {\n\tstatic type = 'store'\n\n\t// expected RxStore, some are already declared/set in StoreBase\n\tapp: AppApi\n\tapi: StoreApi\n\ttype: string\n\n\t// expected class-specific props\n\tactions!: {\n\t\t[actionType: string]: (action: { type: string; [prop: string]: any }) => void | Promise<void>\n\t}\n\n\tdefaultState = defaultState\n\n\tuseCasesExcluded = structuredClone(useCasesExcluded)\n\n\tconstructor(opts, api) {\n\t\tsuper(opts)\n\t\tthis.type = 'store'\n\t\tthis.app = opts.app\n\t\tthis.api = api\n\t\tthis.state = this.copyMerge(this.toJson(defaultState), opts.state) // opts.state\n\t\t// use for assigning unique IDs where needed\n\t\t// may be used later to simplify getting component state by type and id\n\t\tthis.prevGeneratedId = 0\n\t}\n\n\tvalidateOpts(opts) {\n\t\tif (!opts.state) throw '.state{} missing'\n\t\tconst s = opts.state\n\t\tif (s.vocab) {\n\t\t\t/*** !!! May not need to duplicate the validation steps in vocabulary.js ??? ***/\n\t\t\t// assume that any vocabulary with a route\n\t\t\t// will require genome + dslabel\n\t\t\tif (s.vocab.dslabel) {\n\t\t\t\tif (!s.vocab.genome) throw '.state[.vocab].genome missing'\n\t\t\t} else if (s.vocab.genome) {\n\t\t\t\tif (!s.vocab.dslabel) throw '.state[.vocab].dslabel missing'\n\t\t\t} else {\n\t\t\t\tif (!Array.isArray(s.vocab.terms)) throw 'vocab.terms must be an array of objects'\n\t\t\t}\n\t\t}\n\t\treturn opts\n\t}\n\n\tvalidateState() {\n\t\tconst s = this.state\n\t\tif (s.tree.expandedTermIds.length == 0) {\n\t\t\ts.tree.expandedTermIds.push(root_ID, custom_variables_ID)\n\t\t} else {\n\t\t\tif (s.tree.expandedTermIds[0] != root_ID) {\n\t\t\t\ts.tree.expandedTermIds.unshift(root_ID)\n\t\t\t}\n\t\t}\n\t}\n\n\tasync init() {\n\t\tthis.state.termdbConfig = await this.app.vocabApi.getTermdbConfig()\n\t\t// always reset state.allowedTermTypes based on the current\n\t\tthis.state.allowedTermTypes = getAllowedTermTypesForUseCase(this.state, this.app)\n\t\tthis.state.termTypeGroup = typeGroup[this.state.allowedTermTypes[0]]\n\n\t\t// maybe no need to provide term filter at this query\n\t\tlet filterUiRoot = getFilterItemByTag(this.state.termfilter.filter, 'filterUiRoot')\n\t\tif (!filterUiRoot) {\n\t\t\tthis.state.termfilter.filter.tag = 'filterUiRoot'\n\t\t\tfilterUiRoot = this.state.termfilter.filter\n\t\t}\n\n\t\tif (this.state.termdbConfig.selectCohort) {\n\t\t\tlet cohortFilter = getFilterItemByTag(this.state.termfilter.filter, 'cohortFilter')\n\t\t\tif (!cohortFilter) {\n\t\t\t\t// support legacy state.termfilter and test scripts that\n\t\t\t\t// that does not specify a cohort when required;\n\t\t\t\t// will use state.activeCohort if not -1\n\t\t\t\tcohortFilter = {\n\t\t\t\t\ttag: 'cohortFilter',\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: JSON.parse(JSON.stringify(this.state.termdbConfig.selectCohort.term)),\n\t\t\t\t\t\tvalues:\n\t\t\t\t\t\t\tthis.state.activeCohort == -1\n\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t: this.state.termdbConfig.selectCohort.values[this.state.activeCohort].keys.map(key => {\n\t\t\t\t\t\t\t\t\t\treturn { key, label: key }\n\t\t\t\t\t\t\t\t })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.state.termfilter.filter = {\n\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\tin: true,\n\t\t\t\t\tjoin: 'and',\n\t\t\t\t\tlst: [cohortFilter, filterUiRoot]\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst sorter = (a, b) => (a < b ? -1 : 1)\n\t\t\t\tcohortFilter.tvs.values.sort((a, b) => (a.key < b.key ? -1 : 1))\n\t\t\t\tconst keysStr = JSON.stringify(cohortFilter.tvs.values.map(v => v.key).sort(sorter))\n\t\t\t\tconst i = this.state.termdbConfig.selectCohort.values.findIndex(\n\t\t\t\t\tv => keysStr == JSON.stringify(v.keys.sort(sorter))\n\t\t\t\t)\n\t\t\t\tif (this.state.activeCohort !== -1 && this.state.activeCohort !== 0 && i !== this.state.activeCohort) {\n\t\t\t\t\tconsole.log('Warning: cohortFilter will override the state.activeCohort due to mismatch')\n\t\t\t\t}\n\t\t\t\tthis.state.activeCohort = i\n\t\t\t}\n\t\t} else {\n\t\t\tthis.state.activeCohort = -1\n\t\t\tif (this.state.header_mode === 'with_cohortHtmlSelect') {\n\t\t\t\tconsole.warn(`no termdbConfig.selectCohort to use for state.header_mode = 'with_cohortHtmlSelect'`)\n\t\t\t\tthis.state.header_mode = 'search_only'\n\t\t\t}\n\t\t}\n\t}\n\n\tsetId(item) {\n\t\titem.$id = this.prevGeneratedId++\n\t\tif (item.$lst) {\n\t\t\tfor (const subitem of item.$lst) {\n\t\t\t\tthis.setId(subitem)\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n\tTo clearly indicate the allowed store actions,\n\tsupply a literal \"actions\" object on the \n\tconstructor prototype\n*/\nTdbStore.prototype.actions = {\n\tapp_refresh(this: TdbStore, action) {\n\t\t// optional action.state{} may be full or partial overrides\n\t\t// to the current state\n\t\t//\n\t\t// when constructing an app, app_refresh() is called\n\t\t// without action.state as the current state at the\n\t\t// initial render is not meant to be modified yet\n\t\t//\n\t\tthis.state = this.copyMerge(this.toJson(this.state), action.state ? action.state : {})\n\t},\n\tcohort_set(this: TdbStore, action) {\n\t\tthis.state.activeCohort = action.activeCohort\n\t\tconst cohort = this.state.termdbConfig.selectCohort.values[action.activeCohort]\n\t\tconst cohortFilter = getFilterItemByTag(this.state.termfilter.filter, 'cohortFilter')\n\t\tif (!cohortFilter) throw `No item tagged with 'cohortFilter'`\n\t\tcohortFilter.tvs.values = cohort.keys.map(key => {\n\t\t\treturn { key, label: key }\n\t\t})\n\t},\n\ttree_expand(this: TdbStore, action) {\n\t\tif (this.state.tree.expandedTermIds.includes(action.termId)) return\n\t\tthis.state.tree.expandedTermIds.push(action.termId)\n\t},\n\n\ttree_collapse(this: TdbStore, action) {\n\t\tconst i = this.state.tree.expandedTermIds.indexOf(action.termId)\n\t\tif (i == -1) return\n\t\tthis.state.tree.expandedTermIds.splice(i, 1)\n\t},\n\n\tfilter_replace(this: TdbStore, action) {\n\t\tconst replacementFilter = action.filter ? action.filter : { type: 'tvslst', join: '', in: 1, lst: [] }\n\t\tif (!action.filter.tag) {\n\t\t\tthis.state.termfilter.filter = replacementFilter\n\t\t} else {\n\t\t\tconst filter = getFilterItemByTag(this.state.termfilter.filter, action.filter.tag)\n\t\t\tif (!filter) throw `cannot replace missing filter with tag '${action.filter.tag}'`\n\t\t\tconst parent = findParent(this.state.termfilter.filter, filter.$id)\n\t\t\tif (parent == filter) {\n\t\t\t\tthis.state.termfilter.filter = replacementFilter\n\t\t\t} else {\n\t\t\t\tconst i = parent.lst.indexOf(filter)\n\t\t\t\tparent.lst[i] = replacementFilter\n\t\t\t}\n\t\t}\n\t},\n\n\tsubmenu_set(this: TdbStore, action) {\n\t\tconst term = action.submenu && action.submenu.term\n\t\tif (!term) {\n\t\t\tthis.state.submenu = {}\n\t\t\tthis.state.tree.expandedTermIds = [root_ID]\n\t\t} else {\n\t\t\tconst expandedTermIds = [root_ID]\n\t\t\tif (term.__ancestors) {\n\t\t\t\texpandedTermIds.push(...term.__ancestors)\n\t\t\t}\n\n\t\t\tif (isUsableTerm(term, {}, this.state.termdbConfig).has('plot')) {\n\t\t\t\tObject.assign(this.state.submenu, action.submenu)\n\t\t\t} else {\n\t\t\t\texpandedTermIds.push(term.id)\n\t\t\t\tdelete this.state.submenu.term\n\t\t\t}\n\n\t\t\tthis.state.tree.expandedTermIds = expandedTermIds\n\t\t}\n\t},\n\n\t/** Changing the state.termTypeGroup in TermTypeSearch notifies\n\t * the tree of which handler should be shown. */\n\tset_term_type_group(this: TdbStore, { value }) {\n\t\tthis.state.termTypeGroup = value\n\t}\n}\n\n// must use the await keyword when using this storeInit()\nexport const storeInit = StoreApi.getInitFxn(TdbStore)\n", "import { getCompInit } from '../rx'\nimport { showTvsMenu } from '../filter/tvs'\nimport { dtTermTypes } from '#shared/terms.js'\n\nclass TdbSubmenu {\n\tstatic type = 'submenu'\n\n\tconstructor(opts) {\n\t\tthis.type = TdbSubmenu.type\n\t\tthis.dom = { holder: opts.holder }\n\t\tsetRenderers(this)\n\t\t//getCompInit(TdbSubmenu) will set this.id, .app, .opts, .api\n\t}\n\n\treactsTo(action) {\n\t\tif (action.type.startsWith('submenu_')) return true\n\t\tif (action.type == 'app_refresh') return true\n\t}\n\n\tgetState(appState) {\n\t\treturn {\n\t\t\ttype: appState.submenu.type,\n\t\t\tterm: appState.submenu.term,\n\t\t\ttermfilter: appState.termfilter\n\t\t}\n\t}\n\n\tmain() {\n\t\tif (!this.state.term) {\n\t\t\tthis.dom.holder.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tif (this.state.type == 'tvs') this.showTvsMenu(this.state.term)\n\t\telse throw `unsupported submenu.type='${this.state.type}'`\n\t}\n}\n\nexport const submenuInit = getCompInit(TdbSubmenu)\n\nfunction setRenderers(self) {\n\tself.showTvsMenu = function (term) {\n\t\tself.dom.holder.selectAll('*').remove()\n\n\t\tself.dom.holder\n\t\t\t.style('display', 'block')\n\t\t\t.append('div')\n\t\t\t.style('margin', '10px 10px 15px 10px')\n\t\t\t.append('span')\n\t\t\t.html('« ' + (self.app.opts.tree?.backToSelectionText || 'Back to variable selection'))\n\t\t\t.attr('class', 'sja_clbtext')\n\t\t\t.attr('data-testid', 'sja_treesubmenu_backprompt')\n\t\t\t.on('click', () => self.app.dispatch({ type: 'submenu_set', submenu: {} }))\n\n\t\tif (!dtTermTypes.has(term.type)) {\n\t\t\tself.dom.holder\n\t\t\t\t.style('display', 'block')\n\t\t\t\t.append('div')\n\t\t\t\t.style('margin', '10px 0px 5px 10px')\n\t\t\t\t.style('font-weight', 'bold')\n\t\t\t\t.style('font-size', '.9em')\n\t\t\t\t.text(term.name)\n\t\t}\n\n\t\tshowTvsMenu({\n\t\t\tterm,\n\t\t\tfilter: self.state.termfilter.filter,\n\t\t\tholder: self.dom.holder.append('div'),\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\tdebug: self.app.debug,\n\t\t\tgetCategoriesArguments: self.app.opts.getCategoriesArguments,\n\t\t\tisMafFilter: self.app.opts.isMafFilter,\n\t\t\tcallback: self.app.opts.tree.click_term2select_tvs\n\t\t})\n\t}\n}\n", "import { getCompInit } from '#rx'\nimport { select, selectAll } from 'd3-selection'\nimport { sayerror } from '#dom'\nimport { debounce } from 'debounce'\nimport { root_ID } from './tree'\nimport { isUsableTerm } from '#shared/termdb.usecase.js'\nimport { keyupEnter } from '#src/client'\nimport { TermTypeGroups, isNonDictionaryType, equals } from '#shared/terms.js'\n\n/*\nsteps:\nuser input at <input> will call doSearch()\ndoSearch() lets app dispatch an action, type: search_\nbut the action will NOT update app state\napp notifies all components with the action\nonly main() of the \"search component\" will responds to the action to perform querying and display result\n\nopts{}\n.holder\n.click_term()\n.disable_terms[]\n\nTODO\nallow to search categories, e.g. hodgkin lymphoma from diaggrp, how to act upon clicking?\n\n */\n\nclass TermSearch {\n\tstatic type = 'search'\n\n\tconstructor(opts) {\n\t\tthis.type = TermSearch.type\n\t\t// currently postSearch is only used for testing\n\t\tthis.customEvents = ['postSearch']\n\t\t// set this.id, .app, .opts, .api\n\t\tsetRenderers(this)\n\t\tsetInteractivity(this)\n\t\tthis.dom = { holder: opts.holder }\n\n\t\tthis.isVisible = 'isVisible' in opts ? opts.isVisible : true\n\t}\n\n\tasync init(appState) {\n\t\tthis.initUI(this.getState(appState))\n\t}\n\n\treactsTo(action) {\n\t\tif (action.type == 'set_term_type_group') return true\n\t\tif (action.type == 'app_refresh') return true\n\t\tconst prefix = action.type.split('_')[0]\n\t\treturn ['search', 'cohort', 'submenu'].includes(prefix)\n\t}\n\n\tgetState(appState) {\n\t\treturn {\n\t\t\tisVisible: !appState.submenu.term && this.isVisible,\n\t\t\tcohortStr:\n\t\t\t\tappState.activeCohort == -1 || !appState.termdbConfig.selectCohort\n\t\t\t\t\t? ''\n\t\t\t\t\t: appState.termdbConfig.selectCohort.values[appState.activeCohort].keys.slice().sort().join(','),\n\t\t\tallowedTermTypes: appState.termdbConfig?.allowedTermTypes || [],\n\t\t\texpandedTermIds: appState.tree.expandedTermIds,\n\t\t\tselectedTerms: appState.selectedTerms,\n\t\t\tusecase: appState.tree.usecase,\n\t\t\tsearch: appState.search,\n\t\t\ttermTypeGroup: appState.termTypeGroup\n\t\t}\n\t}\n\n\tisTermTypeSupported() {\n\t\tconst termTypeGroup = this.state.termTypeGroup\n\n\t\tif (termTypeGroup == TermTypeGroups.DICTIONARY_VARIABLES) return true\n\t\tif (termTypeGroup == TermTypeGroups.METABOLITE_INTENSITY) return true\n\t\tif (termTypeGroup == TermTypeGroups.PROTEOME_ABUNDANCE) return true\n\n\t\treturn false\n\t}\n\n\tasync main() {\n\t\t// show/hide search input from the tree\n\t\tif (!this.isTermTypeSupported()) {\n\t\t\tthis.dom.holder.style('display', 'none') //These views will have their own UI\n\t\t\treturn\n\t\t}\n\t\tthis.dom.input.node().value = ''\n\t\tthis.dom.input.attr(\n\t\t\t'placeholder',\n\t\t\t// termTypeGroup values cannot cover geneset, thus this check\n\t\t\t// tdbcfg is missing for front vocab?\n\t\t\t`Search ${this.app.vocabApi.termdbConfig?.isGeneSetTermdb ? 'Gene Sets' : this.state.termTypeGroup}`\n\t\t)\n\t\tthis.clear()\n\t\tthis.dom.holder.style('display', this.state.isVisible ? 'block' : 'none')\n\t}\n\n\t// targetType optional, see vocab.findTerm()\n\tasync doSearch(str) {\n\t\tif (!str || str.length < 3) {\n\t\t\tthis.clear()\n\t\t\tthis.bus.emit('postSearch', [])\n\t\t\treturn\n\t\t}\n\t\tconst data = await this.app.vocabApi.findTerm(\n\t\t\tstr,\n\t\t\tthis.state.cohortStr,\n\t\t\tthis.state.usecase,\n\t\t\tthis.state.termTypeGroup\n\t\t)\n\t\tthis.currData = data\n\t\tif (!data.lst || data.lst.length == 0) {\n\t\t\tthis.noResult()\n\t\t} else {\n\t\t\t// found terms\n\t\t\tthis.showTerms(data)\n\t\t}\n\t\tthis.bus.emit('postSearch', data)\n\t}\n}\n\nexport const searchInit = getCompInit(TermSearch)\n\nfunction setRenderers(self) {\n\tself.initUI = state => {\n\t\tself.dom.holder.style('display', self.search && self.search.isVisible == false ? 'none' : 'block')\n\n\t\tconst searchDiv = self.dom.holder.append('div').style('text-align', 'left')\n\n\t\tself.dom.input = searchDiv\n\t\t\t.append('input')\n\t\t\t.attr('type', 'search')\n\t\t\t.attr('class', 'tree_search')\n\t\t\t.style('width', '250px')\n\t\t\t.style('margin', '10px')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.on('input', debounce(self.onInput, 300))\n\t\t\t.on('keyup', self.onKeyup)\n\n\t\tself.dom.resultCntDiv = searchDiv.append('div').style('display', 'none')\n\n\t\tif (self.opts.focus != 'off') self.dom.input.node().focus()\n\n\t\t/* a holder to contain two side-by-side divs \n\t\tused to show genes on one side and dictionary term on another, but gene is no longer shown\n\t\tside-by-side holder is commented off but may be reused for new purpose\n\t\t*/\n\t\tself.dom.resultDiv = (self.opts.resultsHolder || self.dom.holder)\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sjpp_show_scrollbar')\n\t\t\t.style('max-height', '35vh')\n\t\t\t.style('display', 'none')\n\t\t\t//div is hidden when no results to show, since an empty grid holder occupies white space and increase the distance between search box and tree\n\t\t\t// when showing, turn to \"inline-grid\", but not \"grid\", to show up nicely\n\t\t\t.style('grid-template-columns', 'auto auto')\n\n\t\t// left div to show gene hits\n\t\t//const div_gene = self.dom.resultDiv.append('div')\n\t\t// right div to show term hits\n\t\tconst div_term = self.dom.resultDiv.append('div')\n\n\t\t/*\n\t\tself.dom.resultDiv_genes = div_gene\n\t\t\t.append('div')\n\t\t\t.style('border-left', 'solid 1px rgb(133,182,225)')\n\t\t\t.style('margin', '0px 0px 10px 10px')\n\t\t\t.style('padding-left', '5px')\n\t\t\t*/\n\t\tself.dom.resultDiv_terms = div_term\n\t\t\t.append('div')\n\t\t\t.style('border-left', self.opts.resultsHolder ? '' : 'solid 1px rgb(133,182,225)')\n\t\t\t.style('margin', '0px 0px 10px 10px')\n\t\t\t.style('padding-left', '5px')\n\t}\n\n\tself.noResult = () => {\n\t\tself.clear()\n\t\tself.dom.resultDiv.style('display', 'inline-grid')\n\t\tself.dom.resultDiv_terms.append('div').style('padding', '3px 3px 3px 0px').style('opacity', 0.5).text('No match')\n\t}\n\tself.showTerms = data => {\n\t\t// add disabled terms to opts.disable_terms\n\n\t\tif (self.opts.disable_terms) {\n\t\t\tdata.lst.forEach(t => {\n\t\t\t\tif (t.disabled) self.opts.disable_terms.push(t)\n\t\t\t})\n\t\t}\n\t\tself.clear()\n\t\tself.dom.resultDiv.style('display', 'inline-grid')\n\n\t\tif (data.lst.length) {\n\t\t\tself.dom.resultDiv_terms.append('table').selectAll().data(data.lst).enter().append('tr').each(self.showTerm)\n\t\t\tself.dom.resultCntDiv.style('display', 'inline-block').text(`${data.lst.length} results`)\n\t\t}\n\n\t\tself.focusableResults = [...self.dom.resultDiv.node().querySelectorAll('.sja_tree_click_term, .sja_menuoption')]\n\t}\n\tself.showTerm = function (term) {\n\t\tconst tr = select(this)\n\t\tconst button = tr.append('td').text(term.name)\n\t\tconst uses = isUsableTerm(term, self.state.usecase, self.app.vocabApi.termdbConfig)\n\t\t/*\n\t\tbelow, both callbacks are made in app.js validateOpts()\n\t\t1. self.opts.click_term() is for selecting to tvs\n\t\t2. self.app.opts.tree.click_term_wrapper() is a wrapper for opts.tree.click_term()\n\t\t*/\n\t\tif ((self.opts.click_term || self.app.opts?.tree?.click_term_wrapper) && uses.has('plot')) {\n\t\t\t// to click a graphable term, show as blue button\n\t\t\tif (term && self.opts.disable_terms?.find(term2 => equals(term, term2))) {\n\t\t\t\t// but it's disabled\n\t\t\t\tbutton\n\t\t\t\t\t.attr('class', 'sja_tree_click_term_disabled')\n\t\t\t\t\t.style('display', 'block')\n\t\t\t\t\t.style('padding', '5px 8px')\n\t\t\t\t\t.style('margin', '1px 0px')\n\t\t\t\t\t.style('opacity', 0.4)\n\t\t\t} else {\n\t\t\t\t// clickable button\n\t\t\t\tbutton\n\t\t\t\t\t.attr('class', 'ts_pill sja_filter_tag_btn sja_tree_click_term')\n\t\t\t\t\t.attr('tabindex', 0)\n\t\t\t\t\t.style('display', 'block')\n\t\t\t\t\t.style('color', 'black')\n\t\t\t\t\t.style('padding', '5px 8px')\n\t\t\t\t\t.style('border-radius', '6px')\n\t\t\t\t\t.style('background-color', '#cfe2f3')\n\t\t\t\t\t.style('margin', '1px 0px')\n\t\t\t\t\t.style('cursor', 'default')\n\t\t\t\t\t.on('click', () => {\n\t\t\t\t\t\tif (self.opts.click_term) {\n\t\t\t\t\t\t\tself.opts.click_term(term)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.app.opts.tree.click_term_wrapper(term)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tself.clear()\n\t\t\t\t\t\tself.dom.input.property('value', '')\n\t\t\t\t\t})\n\t\t\t\t\t.on('keyup', self.navInputValueByKeyboard)\n\t\t\t}\n\t\t\t//show sample count for a term\n\t\t\tif (term.samplecount !== undefined) {\n\t\t\t\ttr.append('td')\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('font-size', '.8em')\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin-left', '5px')\n\t\t\t\t\t.style('color', term.samplecount ? '#777' : '#ddd')\n\t\t\t\t\t.text('n=' + term.samplecount)\n\t\t\t}\n\t\t} else {\n\t\t\t// as regular button, click to expand tree\n\t\t\tbutton\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('tabindex', 0)\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tself.clear()\n\t\t\t\t\tself.dom.input.property('value', '')\n\t\t\t\t\tconst expandedTermIds = [root_ID]\n\n\t\t\t\t\tif (term.type && isNonDictionaryType(term.type)) {\n\t\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\tselectedTerms: [...self.state.selectedTerms, term]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (term.__ancestors) {\n\t\t\t\t\t\t\texpandedTermIds.push(...term.__ancestors)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// pre-expand non-selectable parent term\n\t\t\t\t\t\tif (!self.app.vocabApi.graphable(term)) expandedTermIds.push(term.id)\n\t\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\ttree: { expandedTermIds }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.on('keyup', self.navInputValueByKeyboard)\n\t\t}\n\t\ttr.append('td')\n\t\t\t.text((term.__ancestorNames || []).join(' > '))\n\t\t\t.style('opacity', 0.5)\n\t\t\t.style('font-size', '.7em')\n\t}\n\tself.clear = () => {\n\t\t//self.dom.resultDiv_genes.selectAll('*').remove()\n\t\tself.dom.resultDiv_terms.selectAll('*').remove()\n\t\tself.dom.resultDiv.style('display', 'none')\n\t\tself.dom.resultCntDiv.style('display', 'none')\n\t}\n}\n\nfunction setInteractivity(self) {\n\tself.onKeyup = event => {\n\t\t// to search snp upon hitting enter\n\t\tif (event.key == 'ArrowDown' && self.currData?.lst?.length) {\n\t\t\tself.dom.resultDiv.select('.sja_tree_click_term, .sja_menuoption').node().focus()\n\t\t\treturn\n\t\t}\n\t\tif (!keyupEnter(event)) return // not pressing enter\n\t\tself.onInput(event)\n\t}\n\n\tself.onInput = async event => {\n\t\tconst str = self.dom.input.property('value')\n\t\t// do not trim space from input so that 'age ' will not match with 'agent'\n\t\ttry {\n\t\t\t//await self.main({ str })\n\t\t\tawait self.doSearch(str)\n\t\t} catch (e) {\n\t\t\tself.clear()\n\t\t\tself.dom.resultDiv.style('display', 'inline-grid')\n\t\t\tsayerror(self.dom.resultDiv_terms, 'Error: ' + (e.message || e))\n\t\t\tif (e.stack) console.log(e.stack)\n\t\t}\n\t}\n\n\tself.navInputValueByKeyboard = event => {\n\t\tif (event.key == 'Enter') event.target.click()\n\t\telse if (event.key.startsWith('Arrow')) {\n\t\t\tconst i = self.focusableResults.findIndex(r => r === event.target)\n\t\t\tif (event.key == 'ArrowDown') {\n\t\t\t\tif (i < self.focusableResults.length - 1) self.focusableResults[i + 1].focus()\n\t\t\t\telse self.focusableResults[0].focus()\n\t\t\t} else if (event.key == 'ArrowUp') {\n\t\t\t\tif (i != 0) self.focusableResults[i - 1].focus()\n\t\t\t\telse self.focusableResults[self.focusableResults.length - 1].focus()\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { AppApi, multiInit, type RxApp, type ComponentApi } from '#rx'\nimport { AppBase } from '#plots/AppBase.ts'\nimport { storeInit } from './store'\nimport { vocabInit } from './vocabulary'\nimport { treeInit } from './tree'\nimport { TermTypeSearchInit } from './TermTypeSearch'\nimport { submenuInit } from './submenu'\nimport { searchInit } from './search'\nimport { select } from 'd3-selection'\nimport { Menu, sayerror } from '#dom'\nimport { dofetch3 } from '#common/dofetch'\n\n/*\nopts{}\n\tstate{}\n\t\trequired, will fill-in or override store.defaultState\n\tapp{}\n\ttree{}\n\t\tdisable_terms[]\n\t\tclick_term2select_tvs()\n\t\tclick_term()\n\t\tbackToSelectionText:str\n\tsearch{}\n\tvocabApi\n\tgetCategoriesArguments{}\n*/\n\nclass TdbApp extends AppBase implements RxApp {\n\tstatic type = 'app'\n\t// expected RxApp, some are already declared/set in AppBase\n\tapi: AppApi\n\ttype = 'app'\n\tparentId?: string\n\tdom!: {\n\t\t[index: string]: any\n\t}\n\tcomponents: {\n\t\t[name: string]: ComponentApi | { [name: string]: ComponentApi }\n\t} = {}\n\n\twasDestroyed = false\n\tstore: any\n\tbus!: any\n\n\t// expected class-specific props\n\n\tconstructor(opts, api) {\n\t\tsuper(opts)\n\t\tthis.opts = this.validateOpts(this.opts)\n\t\tthis.api = api\n\t\tthis.dom = this.getDom(this.opts)\n\t}\n\n\t// override AppBase.validateOpts()\n\tvalidateOpts(o) {\n\t\tif (o.vocabApi) {\n\t\t\t// verify it is an object returned by vocabInit()\n\t\t} else if (o.state && o.state.vocab) {\n\t\t\tif (typeof o.state.vocab != 'object') throw 'opts.state.vocab{} is not an object'\n\t\t} else if (o.state && o.state.genome) {\n\t\t\tconst s = o.state\n\t\t\tif (!s.vocab) s.vocab = {}\n\t\t\ts.vocab.genome = s.genome\n\t\t\tdelete s.genome\n\t\t\tif (s.dslabel) {\n\t\t\t\ts.vocab.dslabel = s.dslabel\n\t\t\t\tdelete s.dslabel\n\t\t\t}\n\t\t} else {\n\t\t\tthrow 'neither state.vocab{} or opts.vocabApi provided'\n\t\t}\n\t\tif (o.tree) {\n\t\t\tif (\n\t\t\t\to.tree.disable_terms &&\n\t\t\t\t!o.tree.click_term &&\n\t\t\t\t!o.tree.click_term2select_tvs &&\n\t\t\t\t(!o.barchart || !o.barchart.bar_click_override)\n\t\t\t) {\n\t\t\t\tthrow `opts.tree.disable_terms is used only when opts.tree.click_term, opts.tree.click_term2select_tvs, or opts.barchart.bar_click_override is set`\n\t\t\t}\n\n\t\t\t// opts.search{} is required, possibly in search.js\n\t\t\tif (!o.search) o.search = {}\n\n\t\t\tif (o.tree.click_term2select_tvs) {\n\t\t\t\t// create the callback on o.search{} so search.js code does not break\n\t\t\t\t// FIXME dispatch('submenu_set') is coded twice (also in tree.js)\n\t\t\t\to.search.click_term = term =>\n\t\t\t\t\tthis.api.dispatch({\n\t\t\t\t\t\ttype: 'submenu_set',\n\t\t\t\t\t\tsubmenu: { term, type: 'tvs' }\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (o.tree.click_term) {\n\t\t\t\t// no need to create extra on\n\n\t\t\t\to.tree.click_term_wrapper = async term => {\n\t\t\t\t\t// this function wraps user-defined click_term, to encapsulate some logic\n\n\t\t\t\t\tif (this.state.termdbConfig.isGeneSetTermdb) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\tthe dataset is special-purpose that will map terms to gene sets (e.g. msigdb)\n\t\t\t\t\t\tdo this hardcoded behavior that upon clicking a term, it fetches the list of genes for this term\n\t\t\t\t\t\tand attaches to the term object as an ad-hoc attribute\n\t\t\t\t\t\tthe same behaviors are maintained in that the click_term() callback gets the term obj as well as the genes\n\t\t\t\t\t\t*/\n\t\t\t\t\t\tconst geneset = await dofetch3('termdb', {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tgenome: this.state.vocab.genome,\n\t\t\t\t\t\t\t\tdslabel: this.state.vocab.dslabel,\n\t\t\t\t\t\t\t\tgenesetByTermId: term.id\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\tterm._geneset = geneset\n\t\t\t\t\t}\n\n\t\t\t\t\t// call the click callback\n\t\t\t\t\to.tree.click_term(term)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (o.tree.disable_terms) o.search.disable_terms = o.tree.disable_terms\n\t\t}\n\t\tif (o.app) {\n\t\t\tfor (const [k, v] of Object.entries(o.app)) {\n\t\t\t\to[k] = v\n\t\t\t}\n\t\t\tdelete o.app\n\t\t}\n\t\treturn o\n\t}\n\n\tgetDom(opts) {\n\t\tif (!opts.holder) select('body').append('div')\n\n\t\t// do this in the constructor to have an dom.errdiv\n\t\t// available at any point during initialization\n\t\tconst submitDiv = opts.holder\n\t\t\t.append('div')\n\t\t\t.style('display', opts.tree?.submit_lst ? '' : 'none')\n\t\t\t.style('text-align', 'center')\n\t\t\t.style('margin', '10px 5px')\n\n\t\tconst submitBtn = submitDiv\n\t\t\t.append('button')\n\t\t\t.property('disabled', true)\n\t\t\t.on('click', () =>\n\t\t\t\t// state is frozen, must submit non-frozen copies\n\t\t\t\tthis.opts.tree?.submit_lst(this.state.selectedTerms.map(t => structuredClone(t)))\n\t\t\t)\n\n\t\tconst topbar = opts.holder.append('div')\n\t\tconst termTypeSearchDiv = topbar.append('div').style('display', 'inline-block')\n\t\tconst treeDiv = topbar.append('div').style('display', 'inline-block').style('vertical-align', 'top')\n\n\t\treturn {\n\t\t\ttopbar,\n\t\t\tholder: opts.holder,\n\t\t\ttermTypeSearchDiv,\n\t\t\tsearchDiv: treeDiv.append('div'),\n\t\t\ttreeDiv: treeDiv.append('div'),\n\t\t\tcustomTermDiv: treeDiv.append('div').style('margin', '10px'),\n\t\t\tsubmitDiv,\n\t\t\tsubmitBtn,\n\t\t\tfilterDiv: topbar.append('div').style('display', 'none'),\n\t\t\terrdiv: opts.holder.append('div'),\n\t\t\ttip: new Menu({ padding: '5px' })\n\t\t}\n\t}\n\n\tasync preApiFreeze(api) {\n\t\ttry {\n\t\t\tif (this.opts.vocabApi) {\n\t\t\t\tapi.vocabApi = this.opts.vocabApi\n\t\t\t} else {\n\t\t\t\tconst state = {\n\t\t\t\t\tvocab: this.opts.state.vocab || {\n\t\t\t\t\t\tgenome: this.opts.state.genome,\n\t\t\t\t\t\tdslabel: this.opts.state.dslabel\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tapi.vocabApi = await vocabInit({ app: this.api, state, fetchOpts: this.opts.fetchOpts })\n\t\t\t}\n\t\t\tapi.appInit = appInit\n\t\t} catch (e) {\n\t\t\tconsole.log(e)\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync init() {\n\t\ttry {\n\t\t\tthis.store = await storeInit({ app: this.api, state: this.opts.state })\n\t\t\tthis.state = await this.store.copyState()\n\t\t\tthis.components = await this.getComponents()\n\t\t\tawait this.api.dispatch()\n\t\t} catch (e) {\n\t\t\tthis.printError(e)\n\t\t}\n\t}\n\n\tasync getComponents() {\n\t\tconst header_mode = this.state.nav?.header_mode\n\t\tconst compPromises: { [name: string]: Promise<ComponentApi> } = {\n\t\t\tsearch: searchInit({\n\t\t\t\tapp: this.api,\n\t\t\t\tholder: this.dom.searchDiv,\n\t\t\t\tisVisible: header_mode !== 'hide_search'\n\t\t\t}),\n\t\t\ttermTypeSearch: TermTypeSearchInit({\n\t\t\t\tapp: this.api,\n\t\t\t\tholder: this.dom.termTypeSearchDiv,\n\t\t\t\ttopbar: this.dom.topbar,\n\t\t\t\tgenome: this.opts.vocabApi?.app?.opts?.genome,\n\t\t\t\tclick_term: this.opts.tree?.click_term,\n\t\t\t\tsubmit_lst: this.opts.tree?.submit_lst,\n\t\t\t\tsubmitDiv: this.dom.submitDiv\n\t\t\t}),\n\t\t\ttree: treeInit({\n\t\t\t\tapp: this.api,\n\t\t\t\tholder: this.dom.treeDiv,\n\t\t\t\theaderDiv: this.dom.headerDiv,\n\t\t\t\texpandAll: header_mode == 'hide_search'\n\t\t\t})\n\t\t}\n\t\tif (this.opts.tree && this.opts.tree.click_term2select_tvs) {\n\t\t\tcompPromises.submenu = submenuInit({\n\t\t\t\tapp: this.api,\n\t\t\t\tholder: this.dom.holder.append('div').style('display', 'none')\n\t\t\t})\n\t\t}\n\n\t\treturn multiInit(compPromises)\n\t}\n\n\tasync main() {\n\t\tthis.api.vocabApi.main()\n\t\tconst n = this.state.selectedTerms.length\n\t\tthis.dom.submitBtn\n\t\t\t.property('disabled', !n)\n\t\t\t.text(!n ? 'Search or click term(s)' : `Submit ${n} term${n > 1 ? 's' : ''}`)\n\n\t\tthis.dom.holder.selectAll('search, .termbtn, button').attr('tabindex', 0)\n\t\tthis.dom.holder.selectAll('.termbtn').on('keyup', event => {\n\t\t\tif (event.key == 'Enter') event.target.click()\n\t\t})\n\t}\n\n\tprintError(e) {\n\t\tsayerror(this.dom.errdiv, 'Error: ' + (e.message || e))\n\t\tif (e.stack) console.log(e.stack)\n\t}\n}\n\n// must use the await keyword when using this appInit()\nexport const appInit = AppApi.getInitFxn(TdbApp)\n", "import { appInit } from '#termdb/app'\nimport { Menu } from '#dom'\n\n/*\nFIXME return tw but not term\n\na ui to select two terms from termdb tree and submit them to a callback\nexample usage: dynamic scatter using two numeric terms, facet table using any two terms\n\nargs:\n\ttip\n\t\tin which this ui is shown\n\tapp\n\t\t.getState()\n\tchartType:string\n\tdetail{}\n\t\toptional, filters both X & Y terms\n\tcallback\n\tdetail2{}\n\t\tif provided, only filters the Y term.\n\t\tUsed for the run chart that requires date for the first time and a numeric term for the second value that is not a date.\n*/\nexport function select2Terms(tip, app, chartType, detail, callback, detail2) {\n\tconst tip2 = new Menu({\n\t\t// creates tip2 on every launch\n\t\tpadding: '5px',\n\t\tparent_menu: tip.d.node() // uses tip as parent to avoid hiding tip when toggling tabs inside tip2\n\t})\n\n\t// registers each selected terms FIXME use tw\n\tlet xterm, yterm\n\n\t// label for each term. tailor by chartType\n\tlet xlab = 'X',\n\t\tylab = 'Y'\n\tif (chartType == 'facet') {\n\t\tylab = 'Row ' // spaces for equal width\n\t\txlab = 'Column'\n\t}\n\n\tconst d0 = tip.d.append('div').style('margin', '10px')\n\t{\n\t\tconst row = d0.append('div')\n\t\trow\n\t\t\t.append('span')\n\t\t\t.html(xlab + ' ')\n\t\t\t.style('font-family', 'Courier')\n\t\tconst xdiv = row\n\t\t\t.append('div')\n\t\t\t.attr('class', 'ts_pill sja_filter_tag_btn')\n\t\t\t.attr('data-testid', chartType == 'facet' ? 'sjpp-facet-column-selector' : null)\n\t\t\t.style('padding', '3px 6px')\n\t\t\t.style('border-radius', '6px')\n\t\t\t.text('+')\n\t\t\t.on('click', e => {\n\t\t\t\tgetTreeTerm(xdiv, term => (xterm = term), detail)\n\t\t\t})\n\t}\n\t{\n\t\tconst row = d0.append('div').style('margin', '1px 0px 5px 0px')\n\t\trow\n\t\t\t.append('span')\n\t\t\t.html(ylab + ' ')\n\t\t\t.style('font-family', 'Courier')\n\t\tconst ydiv = row\n\t\t\t.append('div')\n\t\t\t.attr('class', 'ts_pill sja_filter_tag_btn')\n\t\t\t.attr('data-testid', chartType == 'facet' ? 'sjpp-facet-row-selector' : null)\n\t\t\t.style('padding', '3px 6px')\n\t\t\t.style('border-radius', '6px')\n\t\t\t.text('+')\n\t\t\t.on('click', e => {\n\t\t\t\tgetTreeTerm(ydiv, term => (yterm = term), detail2 || detail)\n\t\t\t})\n\t}\n\n\tconst row = d0.append('div')\n\tconst submitBtn = row\n\t\t.append('button')\n\t\t.attr('data-testid', chartType == 'facet' ? 'sjpp-facet-submit' : null)\n\t\t.text('Submit')\n\t\t.property('disabled', true)\n\t\t.on('click', () => {\n\t\t\tcallback(xterm, yterm)\n\t\t\ttip.hide()\n\t\t})\n\trow.append('span').html(' Select two variables to plot').style('opacity', 0.6).style('font-size', '.7em')\n\n\tfunction getTreeTerm(div, callback, detail) {\n\t\tconst disable_terms = []\n\t\tif (xterm) disable_terms.push(xterm)\n\t\tif (yterm) disable_terms.push(yterm)\n\t\tappInit({\n\t\t\tholder: tip2.clear().showunder(div.node()).d,\n\t\t\tvocabApi: app.vocabApi,\n\t\t\tstate: {\n\t\t\t\tactiveCohort: app.getState().activeCohort,\n\t\t\t\ttree: { usecase: { detail, target: chartType } }\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tdisable_terms,\n\t\t\t\tclick_term: term => {\n\t\t\t\t\t/////////////////////////////////////////\n\t\t\t\t\t// note! geneVariant yields a tw but not term; future fix is for this ui to return tw but not term\n\t\t\t\t\t/////////////////////////////////////////\n\t\t\t\t\tconst t = term.term || term\n\t\t\t\t\tcallback(t)\n\t\t\t\t\ttip2.hide()\n\t\t\t\t\tdiv.text(t.name)\n\t\t\t\t\tif (xterm != null && yterm != null) submitBtn.property('disabled', false)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n", "import { select as d3select } from 'd3-selection'\n\n//Icons from bootstrap: https://icons.getbootstrap.com/\nexport const shapes = {\n\t//circle filled\n\tfilledCircle: {\n\t\tpath: 'M 8,8 m 8,0 a 8,8 0 1,0 -16,0 a 8,8 0 1,0 16,0',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { radius: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { radius } = _opts\n\n\t\t\treturn `M${radius},0 A${radius},${radius} 0 1,1 ${-radius},0 A${radius},${radius} 0 1,1 ${radius},0 Z`\n\t\t},\n\t\tisFilled: true\n\t},\n\n\t//rectangle empty\n\t// https://icons.getbootstrap.com/icons/file/\n\temptyVerticalRectangle: {\n\t\tpath: 'M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { height: 16, width: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height } = _opts\n\n\t\t\treturn `M-${width / 2},-${height / 2}h${width}v${height}h-${width}z`\n\t\t},\n\t\tisFilled: false\n\t},\n\n\t//circle empty\n\t//https://icons.getbootstrap.com/icons/circle/\n\temptyCircle: {\n\t\tpath: 'M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { radius: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { radius } = _opts\n\n\t\t\treturn `M${radius},0 A${radius},${radius} 0 1,1 ${-radius},0 A${radius},${radius} 0 1,1 ${radius},0 Z`\n\t\t},\n\t\tisFilled: false\n\t},\n\n\t// shield empty\n\t// https://icons.getbootstrap.com/icons/shield/\n\temptyShield: {\n\t\tpath: 'M5.338 1.59a61 61 0 0 0-2.837.856.48.48 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.7 10.7 0 0 0 2.287 2.233c.346.244.652.42.893.533q.18.085.293.118a1 1 0 0 0 .101.025 1 1 0 0 0 .1-.025q.114-.034.294-.118c.24-.113.547-.29.893-.533a10.7 10.7 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { width: 16, height: 24 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height } = _opts\n\n\t\t\tconst halfWidth = width / 2\n\t\t\tconst arcRadius = halfWidth\n\n\t\t\treturn `M-${halfWidth},-${height / 2} A${arcRadius},${arcRadius} 0 0,1 ${halfWidth},-${\n\t\t\t\theight / 2\n\t\t\t} L${halfWidth},${height * 0.1} L0,${height / 2} L-${halfWidth},${height * 0.1} Z`\n\t\t},\n\t\tisFilled: false\n\t},\n\n\t// triangle filled\n\t// https://icons.getbootstrap.com/icons/triangle-fill/\n\tfilledTriangle: {\n\t\tpath: 'M7.022 1.566a1.13 1.13 0 0 1 1.96 0l6.857 11.667c.457.778-.092 1.767-.98 1.767H1.144c-.889 0-1.437-.99-.98-1.767z',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { height: 16, width: 16, isUp: true }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height, isUp } = _opts\n\n\t\t\tconst xOffset = width / 2\n\t\t\tconst yOffset = height / 2\n\n\t\t\tconst p1 = isUp ? `M0,-${yOffset}` : `M0,${yOffset}`\n\t\t\tconst p2 = isUp ? `L${xOffset},${yOffset}` : `L${xOffset},-${yOffset}`\n\t\t\tconst p3 = isUp ? `L-${xOffset},${yOffset}` : `L-${xOffset},-${yOffset}`\n\n\t\t\treturn `${p1} ${p2} ${p3} Z`\n\t\t},\n\t\tisFilled: true\n\t},\n\n\t//triangle empty\n\t//https://icons.getbootstrap.com/icons/triangle/\n\temptyTriangle: {\n\t\tpath: 'M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.15.15 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.2.2 0 0 1-.054.06.1.1 0 0 1-.066.017H1.146a.1.1 0 0 1-.066-.017.2.2 0 0 1-.054-.06.18.18 0 0 1 .002-.183L7.884 2.073a.15.15 0 0 1 .054-.057m1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767z',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { height: 16, width: 16, isUp: true }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height, isUp } = _opts\n\n\t\t\tconst xOffset = width / 2\n\t\t\tconst yOffset = height / 2\n\n\t\t\tconst p1 = isUp ? `M0,-${yOffset}` : `M0,${yOffset}`\n\t\t\tconst p2 = isUp ? `L${xOffset},${yOffset}` : `L${xOffset},-${yOffset}`\n\t\t\tconst p3 = isUp ? `L-${xOffset},${yOffset}` : `L-${xOffset},-${yOffset}`\n\n\t\t\treturn `${p1} ${p2} ${p3} Z`\n\t\t},\n\t\tisFilled: false\n\t},\n\n\t//shield filled\n\tfilledShield: {\n\t\tpath: 'M5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56',\n\t\tisFilled: true\n\t},\n\n\t//diamond filled\n\tfilledDiamond: {\n\t\tpath: 'M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.48 1.48 0 0 1 0-2.098z',\n\t\tisFilled: true\n\t},\n\n\t//cross large\n\tlargeCross: {\n\t\tpath: 'M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z'\n\t},\n\n\t//diamond empty\n\temptyDiamond: {\n\t\tpath: 'M8.384 1.226a.463.463 0 0 0-.768 0l-4.56 6.468a.54.54 0 0 0 0 .612l4.56 6.469a.463.463 0 0 0 .768 0l4.56-6.469a.54.54 0 0 0 0-.612zM6.848.613a1.39 1.39 0 0 1 2.304 0l4.56 6.468a1.61 1.61 0 0 1 0 1.838l-4.56 6.468a1.39 1.39 0 0 1-2.304 0L2.288 8.92a1.61 1.61 0 0 1 0-1.838z',\n\t\tisFilled: false\n\t},\n\n\t//plus\n\tplusIcon: {\n\t\tpath: 'M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2'\n\t},\n\n\t// egg filled\n\tfilledEgg: {\n\t\tpath: 'M14 10a6 6 0 0 1-12 0C2 5.686 5 0 8 0s6 5.686 6 10',\n\t\tisFilled: true\n\t},\n\n\t//pentagon filled\n\tfilledPentagon: {\n\t\tpath: 'M7.685.256a.5.5 0 0 1 .63 0l7.421 6.03a.5.5 0 0 1 .162.538l-2.788 8.827a.5.5 0 0 1-.476.349H3.366a.5.5 0 0 1-.476-.35L.102 6.825a.5.5 0 0 1 .162-.538l7.42-6.03Z',\n\t\tisFilled: true\n\t},\n\n\t//egg empty\n\temptyEgg: {\n\t\tpath: 'M8 15a5 5 0 0 1-5-5c0-1.956.69-4.286 1.742-6.12.524-.913 1.112-1.658 1.704-2.164C7.044 1.206 7.572 1 8 1s.956.206 1.554.716c.592.506 1.18 1.251 1.704 2.164C12.31 5.714 13 8.044 13 10a5 5 0 0 1-5 5m0 1a6 6 0 0 0 6-6c0-4.314-3-10-6-10S2 5.686 2 10a6 6 0 0 0 6 6',\n\t\tisFilled: false\n\t},\n\n\t//pentagon empty\n\temptyPentagon: {\n\t\tpath: 'M7.685 1.545a.5.5 0 0 1 .63 0l6.263 5.088a.5.5 0 0 1 .161.539l-2.362 7.479a.5.5 0 0 1-.476.349H4.099a.5.5 0 0 1-.476-.35L1.26 7.173a.5.5 0 0 1 .161-.54l6.263-5.087Zm8.213 5.28a.5.5 0 0 0-.162-.54L8.316.257a.5.5 0 0 0-.631 0L.264 6.286a.5.5 0 0 0-.162.538l2.788 8.827a.5.5 0 0 0 .476.349h9.268a.5.5 0 0 0 .476-.35l2.788-8.826Z',\n\t\tisFilled: false\n\t},\n\n\t//suit diamond filled\n\tfilledDiamondSuit: {\n\t\tpath: 'M2.45 7.4 7.2 1.067a1 1 0 0 1 1.6 0L13.55 7.4a1 1 0 0 1 0 1.2L8.8 14.933a1 1 0 0 1-1.6 0L2.45 8.6a1 1 0 0 1 0-1.2',\n\t\tisFilled: true\n\t},\n\n\t//square empty\n\t//https://icons.getbootstrap.com/icons/square/\n\temptySquare: {\n\t\tpath: 'M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { height: 16, width: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height } = _opts\n\n\t\t\treturn `M-${width / 2},-${height / 2} h${width} v${height} h-${width} Z`\n\t\t},\n\t\tisFilled: false\n\t},\n\n\t//suit diamond empty\n\temptyDiamondSuit: {\n\t\tpath: 'M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.48 1.48 0 0 1 0-2.098zm1.4.7a.495.495 0 0 0-.7 0L1.134 7.65a.495.495 0 0 0 0 .7l6.516 6.516a.495.495 0 0 0 .7 0l6.516-6.516a.495.495 0 0 0 0-.7L8.35 1.134z',\n\t\tisFilled: false\n\t},\n\n\t//cross\n\tcrossShape: {\n\t\tpath: 'M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'\n\t},\n\n\t//square filled\n\t// https://icons.getbootstrap.com/icons/square-fill/\n\tfilledSquare: {\n\t\tpath: 'M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2z',\n\t\tcalculatePath(opts) {\n\t\t\tconst _opts = { height: 16, width: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height } = _opts\n\n\t\t\treturn `M-${width / 2},-${height / 2} h${width} v${height} h-${width} Z`\n\t\t},\n\t\tisFilled: true\n\t},\n\n\t//rectangle filled\n\t// https://icons.getbootstrap.com/icons/file-fill/\n\tfilledVerticalRectangle: {\n\t\tpath: 'M4 0h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2',\n\t\tcalculatePath: opts => {\n\t\t\tconst _opts = { height: 16, width: 16 }\n\t\t\tObject.assign(_opts, opts)\n\t\t\tconst { width, height } = _opts\n\n\t\t\treturn `M-${width / 2},-${height / 2}h${width}v${height}h-${width}z`\n\t\t},\n\t\tisFilled: true\n\t}\n}\n\nexport const shapesArray = Object.values(shapes).map(shape => shape.path)\n\nexport function shapeSelector(div, callback, arr = shapesArray, opts = {}) {\n\tconst size = 20\n\tconst cols = 8\n\tconst height = Math.ceil(arr.length / cols) * size\n\tdiv.style('background-color', 'backgroundColor' in opts ? opts.backgroundColor : 'white')\n\tconst svg = div\n\t\t.append('div')\n\t\t.style('padding', '5px')\n\t\t.append('svg')\n\t\t.attr('width', size * cols)\n\t\t.attr('height', height)\n\tlet count = 0\n\tlet y = 0\n\tfor (const shape of arr) {\n\t\tconst index = count + y * cols\n\t\tsvg\n\t\t\t.append('path')\n\t\t\t.style('pointer-events', 'bounding-box')\n\t\t\t.style('fill', 'gray')\n\t\t\t.attr('d', shape)\n\t\t\t.attr('transform', `translate(${size * count}, ${y * size})`)\n\t\t\t.on('click', () => {\n\t\t\t\tcallback(index)\n\t\t\t})\n\t\t\t.on('mouseover', function () {\n\t\t\t\td3select(this).style('fill', 'black')\n\t\t\t})\n\t\t\t.on('mouseout', function () {\n\t\t\t\td3select(this).style('fill', 'gray')\n\t\t\t})\n\t\tcount++\n\t\tif (count % cols == 0) {\n\t\t\tcount = 0\n\t\t\ty++\n\t\t}\n\t}\n}\n", "import type { UrlTemplateSsm } from '#types'\n\n/*\nMake html links from one m object (m is ssm-simple somatic mutation, snvindel, or nonmutation)\nextendable to support multiple link formats\n\nArguments:\n\nssm_urls:\n\tsee type def\nm:\n\tvariant object\nvariantNameDom:\n\tdom (<span>) that's already rendered with the variant name. \n\tif ssm url config.shownSeparately=false , <a> tag is rendered into this <span>, so the link appears over the variant name\n\totherwise the new link html is added to separateUrls[] and returned\ngenome:\n\tonly used for regulomedb for now\n\nReturns:\n\nseparateUrls[]: array of html links (if ssm_urls is array) or html string (if ssm_urls is object)\n*/\nexport function makeSsmLink(\n\tssm_urls: UrlTemplateSsm | UrlTemplateSsm[],\n\tm: {\n\t\tchr?: string\n\t\tpos?: number\n\t},\n\tvariantNameDom: any,\n\tgenome: string\n) {\n\t// urls shown separately\n\tconst separateUrls: string[] = []\n\n\tif (Array.isArray(ssm_urls)) {\n\t\t// ssm_urls is array\n\t\tfor (const ssm_url of ssm_urls) {\n\t\t\tif (ssm_url.namekey == 'regulomedb') {\n\t\t\t\t// this key corresponds to hardcoded logic to build regulomedb link with special requirements that also include genome\n\t\t\t\tif (typeof m.chr == 'string' && m.pos !== undefined && Number.isInteger(m.pos)) {\n\t\t\t\t\tconst coord = `${m.chr}%3A${m.pos}-${m.pos + 1}`\n\t\t\t\t\tseparateUrls.push(\n\t\t\t\t\t\t`<a href=\"${ssm_url.base}regions=${coord}&genome=${genome == 'hg38' ? 'GRCh38' : genome}\" target=\"_blank\">${\n\t\t\t\t\t\t\tssm_url.linkText\n\t\t\t\t\t\t}</a>`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmakeGeneralLink(ssm_url, m, variantNameDom, separateUrls)\n\t\t}\n\t} else {\n\t\tmakeGeneralLink(ssm_urls, m, variantNameDom, separateUrls)\n\t}\n\treturn separateUrls\n}\n\nfunction makeGeneralLink(ssm_url: UrlTemplateSsm, m: object, variantNameDom: any, separateUrls: string[]) {\n\tconst mValue = m[ssm_url.namekey]\n\tif (mValue == undefined) return // m{} does not have valid value which is required to compose a url. do not make\n\n\tconst url = ssm_url.base + mValue\n\n\tif (ssm_url.shownSeparately) {\n\t\t// to generate a link separate from variantNameDom\n\t\tseparateUrls.push(`<a href=\"${url}\" target=\"_blank\">${ssm_url.linkText || mValue}</a>`)\n\t\treturn\n\t}\n\t// not showing separately\n\tvariantNameDom.html(`<a href=\"${url}\" target=\"_blank\">${variantNameDom.html()}</a>`)\n}\n", "import { select } from 'd3-selection'\nimport { ColorScale, computeTicks } from '#dom'\n\nexport default function svgLegend(opts) {\n\tlet currlinex = 0\n\tlet currliney = 0\n\tlet currG\n\n\tconst defaultSettings = {\n\t\tontop: false,\n\t\tlineh: 25,\n\t\tpadx: 5,\n\t\tpadleft: 0, //150,\n\t\tpadright: 20,\n\t\tpadbtm: 30,\n\t\tfontsize: 12,\n\t\ticonh: 10,\n\t\ticonw: 10,\n\t\thangleft: 1,\n\t\tlinesep: false,\n\t\tmutationorder: [\n\t\t\t'M',\n\t\t\t'E',\n\t\t\t'F',\n\t\t\t'N',\n\t\t\t'S',\n\t\t\t'D',\n\t\t\t'I',\n\t\t\t'P',\n\t\t\t'L',\n\t\t\t'Intron',\n\t\t\t'ITD',\n\t\t\t'DEL',\n\t\t\t'NLOSS',\n\t\t\t'CLOSS',\n\t\t\t'Utr3',\n\t\t\t'Utr5',\n\t\t\t'X',\n\t\t\t'noncoding',\n\t\t\t'Fuserna',\n\t\t\t'SV',\n\t\t\t'CNV_amplification',\n\t\t\t'CNV_homozygous_deletion',\n\t\t\t'CNV_amp',\n\t\t\t'CNV_loss',\n\t\t\t'CNV_loh',\n\t\t\t'snv',\n\t\t\t'mnv'\n\t\t],\n\t\titemOpacity: 1\n\t}\n\n\tconst settings = Object.assign(defaultSettings, opts.settings || {})\n\n\tfunction render(data, overrides = {}) {\n\t\tObject.assign(settings, overrides.settings || {})\n\t\tcurrlinex = settings.padleft\n\t\tcurrliney = 0\n\n\t\topts.holder.selectAll('g').remove()\n\t\topts.holder.selectAll('text').remove()\n\t\tconst d = settings.dimensions\n\t\tif (!opts.holder.attr('transform')) {\n\t\t\t// d.yOffset should be used instead of settings.svgh ???\n\t\t\topts.holder.attr('transform', settings.ontop ? null : `translate(${d.xOffset},${settings.svgh})`)\n\t\t}\n\t\tif (opts.note && data.length) {\n\t\t\topts.holder\n\t\t\t\t.append('text')\n\t\t\t\t.style('font-size', '0.8em')\n\t\t\t\t.text(opts.note)\n\t\t\t\t.attr('transform', `translate(-135, 15)`)\n\t\t\t\t.attr('font-style', 'italic')\n\t\t}\n\t\tconst l = opts.holder.selectAll('g').data(data)\n\n\t\tl.exit().remove()\n\t\tl.enter().append('g').each(addGroup)\n\n\t\treturn currliney + settings.lineh + settings.padbtm\n\t}\n\n\tfunction addGroup(d, i) {\n\t\tif (!d.items || !d.items.length) return\n\t\tcurrlinex = 0\n\t\tcurrliney += settings.lineh\n\n\t\tlet g = select(this).style('opacity', d.crossedOut ? '0.6' : 1)\n\t\tif (d.id) g = g.attr('id', d.id)\n\t\tif (d.class) g = g.attr('class', d.class)\n\t\tconst leftdist = settings.hangleft ? settings.padleft + settings.hangleft - settings.padx : settings.padleft\n\n\t\tconst grplabel = g\n\t\t\t.append('text')\n\t\t\t.attr('transform', 'translate(' + leftdist + ',' + (currliney + settings.iconh / 2) + ')')\n\t\t\t.attr('text-anchor', settings.hangleft ? 'end' : 'start')\n\t\t\t.attr('font-weight', 700)\n\t\t\t.attr('font-size', settings.fontsize)\n\t\t\t.attr('dominant-baseline', 'central')\n\t\t\t.text(d.name)\n\t\t\t.style('text-decoration', d.crossedOut ? 'line-through' : '')\n\n\t\tif (settings.linesep) {\n\t\t\tcurrlinex = settings.padleft\n\t\t\tcurrliney += settings.lineh\n\t\t} /* else if (d.hasScale) {\n\t\t\tcurrlinex = leftdist - 2 * settings.padx + 2\n\t\t} */ else if (d.hasScale || settings.hangleft) {\n\t\t\tcurrlinex = leftdist + 2 * settings.padx\n\t\t} else {\n\t\t\tcurrlinex += settings.padleft + grplabel.node().getBBox().width + 2 * settings.padx\n\t\t}\n\t\td.itemStartX = currlinex\n\n\t\tif (d.sorter) d.items.sort(d.sorter)\n\n\t\tg.selectAll('g')\n\t\t\t.data(d.items)\n\t\t\t.enter()\n\t\t\t.append('g')\n\t\t\t//.attr('transform', 'translate(0,'+i*20+')')\n\t\t\t.each(addItem)\n\n\t\tconst bbox = grplabel.node().getBBox()\n\t\tif (Math.abs(bbox.y + bbox.height / 2) > 1) {\n\t\t\t// dominant-baseline is not supported, manually position\n\t\t\tgrplabel.attr('y', bbox.height / 4)\n\t\t}\n\t}\n\n\tfunction addItem(d, i) {\n\t\tconst g = select(this)\n\t\t\t.style('opacity', settings.itemOpacity)\n\t\t\t.style('opacity', d.greyedOut ? '0.6' : 1)\n\t\tif (d.newLine) {\n\t\t\tcurrliney += settings.lineh\n\t\t\tconst groupData = this.parentNode ? this.parentNode.__data__ : null\n\t\t\tconst leftdist = !settings.hangleft ? settings.padleft : settings.padleft + settings.hangleft + settings.padx\n\t\t\tcurrlinex = groupData && groupData.itemStartX != null ? groupData.itemStartX : leftdist\n\t\t}\n\t\tg.attr('transform', 'translate(' + currlinex + ',' + currliney + ')')\n\n\t\tconst itemlabel = g\n\t\t\t.append('text')\n\t\t\t.attr('transform', 'translate(' + (settings.iconw + settings.padx / 2) + ',' + settings.iconh / 2 + ')')\n\t\t\t.attr('font-size', settings.fontsize)\n\t\t\t.attr('dominant-baseline', 'central')\n\t\t\t.style('cursor', 'default')\n\t\t\t.style(\n\t\t\t\t'text-decoration',\n\t\t\t\t(settings.exclude && settings.exclude.classes && settings.exclude.classes.includes(d.class)) || d.crossedOut\n\t\t\t\t\t? 'line-through'\n\t\t\t\t\t: ''\n\t\t\t)\n\n\t\titemlabel.each(function (d) {\n\t\t\tconst t = select(this)\n\t\t\tif (settings.isExcludedAttr && d[settings.isExcludedAttr]) {\n\t\t\t\tt.style('text-decoration', 'line-through').style('opacity', 0.5)\n\t\t\t}\n\t\t\tif (typeof d.text == 'string') {\n\t\t\t\tt.text(d.text)\n\t\t\t} else if (Array.isArray(d.text)) {\n\t\t\t\tt.selectAll('tspan')\n\t\t\t\t\t.data(d.text)\n\t\t\t\t\t.enter()\n\t\t\t\t\t.append('tspan')\n\t\t\t\t\t.text(d => d)\n\t\t\t\t\t.attr('dominant-baseline', 'central')\n\t\t\t\t\t.attr('x', function (dd, i) {\n\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\tselect(this).attr('font-weight', 700)\n\t\t\t\t\t\t\td.lastx = select(this).node().getComputedTextLength() + 10\n\t\t\t\t\t\t\treturn 0\n\t\t\t\t\t\t} else if (d.lastx) {\n\t\t\t\t\t\t\treturn d.lastx\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (d.onClickCallback) {\n\t\t\t\tt.on('click', () => d.onClickCallback(d, t))\n\t\t\t\tt.style('cursor', 'pointer')\n\t\t\t}\n\t\t})\n\n\t\tconst bbox = itemlabel.node().getBBox()\n\t\tlet width = d.width || settings.iconw\n\t\tif (d.colorPicker) {\n\t\t\twidth += (d.inputWidth || 30) + settings.padx\n\t\t}\n\t\tif (d.skipIcon) width = 0\n\t\tcurrlinex += bbox.width + width\n\t\tif (settings.linesep || currlinex > settings.svgw - settings.padright) {\n\t\t\tcurrliney += settings.lineh\n\t\t\tconst leftdist = !settings.hangleft ? settings.padleft : settings.padleft + settings.hangleft + settings.padx\n\n\t\t\tg.attr('transform', 'translate(' + leftdist + ',' + currliney + ')')\n\t\t\tcurrlinex = bbox.width + width + settings.padleft\n\t\t\tif (settings.hangleft) currlinex = settings.iconw + bbox.width + leftdist\n\t\t\telse currlinex = width + bbox.width + settings.padleft\n\t\t}\n\n\t\tconst y = settings.fontsize - bbox.height + (bbox.height - settings.iconh) / 2\n\t\tlet colorGradientId\n\t\tif (d.domain) {\n\t\t\tcolorGradientId = `sjpp-linear-gradient-${getId()}`\n\t\t\tconst domain = d.domain || [d.minLabel, d.maxLabel]\n\t\t\tconst yPos = y + 3\n\t\t\tconst min = d.domain[0]\n\t\t\tconst max = d.domain[d.domain.length - 1]\n\t\t\tconst domainRange = Math.abs(max - min)\n\n\t\t\tconst opts = {\n\t\t\t\tbarwidth: width,\n\t\t\t\tbarheight: settings.iconh,\n\t\t\t\tcolors: d.colors || d.scale.range() || ['white', 'grey'],\n\t\t\t\tdomain,\n\t\t\t\tfontSize: 0.82 * settings.fontsize,\n\t\t\t\t/** Must separate the color scale from the label for\n\t\t\t\t * event handlers (e.g. if click behavior on the label\n\t\t\t\t * is different than click behavior on the color scale itself)*/\n\t\t\t\tholder: g.append('g'),\n\t\t\t\tid: colorGradientId,\n\t\t\t\tposition: `${bbox.width + 25},${yPos}`,\n\t\t\t\tticks: computeTicks(domainRange, 2),\n\t\t\t\ttickSize: 2,\n\t\t\t\ttopTicks: true\n\t\t\t}\n\t\t\tif (d.labels) {\n\t\t\t\topts.labels = d.labels\n\t\t\t\tif (d.text) opts.position = `${bbox.width + bbox.x + 45 + settings.padx},${yPos}`\n\t\t\t}\n\t\t\t// numericInputs is the clickable menu\n\t\t\t// see ColorScaleOpts type for description\n\t\t\tif (d.numericInputs) opts.numericInputs = d.numericInputs\n\n\t\t\tnew ColorScale(opts)\n\n\t\t\tif (opts.labels) currlinex += bbox.width + 25 + 15 * settings.padx\n\t\t\telse currlinex += 10 * settings.padx\n\t\t} else {\n\t\t\tif (d.colorPicker) {\n\t\t\t\tconst inputHeight = d.inputHeight || settings.iconh + 6\n\t\t\t\tconst inputWidth = d.inputWidth || 30\n\n\t\t\t\tconst colorInput = g\n\t\t\t\t\t.append('foreignObject')\n\t\t\t\t\t.attr('x', bbox.width + settings.padx)\n\t\t\t\t\t.attr('y', y + settings.iconh / 2 - inputHeight / 2)\n\t\t\t\t\t.attr('width', inputWidth)\n\t\t\t\t\t.attr('height', inputHeight)\n\t\t\t\t\t.append('xhtml:input')\n\t\t\t\t\t.attr('type', 'color')\n\t\t\t\t\t.attr('value', d.color || '#4d4d4d')\n\t\t\t\t\t.style('width', `${inputWidth}px`)\n\t\t\t\t\t.style('height', `${inputHeight}px`)\n\t\t\t\t\t.style('padding', '0')\n\t\t\t\t\t.style('border', '1px solid #ccc')\n\t\t\t\t\t.style('border-radius', '4px')\n\n\t\t\t\tif (typeof d.onColorChange === 'function') {\n\t\t\t\t\tcolorInput.on('change', event => {\n\t\t\t\t\t\td.onColorChange(event.target.value)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else if (!d.skipIcon) {\n\t\t\t\tg.append('rect')\n\t\t\t\t\t.attr('height', settings.iconh)\n\t\t\t\t\t.attr('width', width)\n\t\t\t\t\t//.attr('x', bbox.width)\n\t\t\t\t\t.attr('y', y)\n\t\t\t\t\t.attr('fill', colorGradientId ? `url(#${colorGradientId})` : opts.rectFillFxn)\n\t\t\t\t\t.attr('stroke', opts.iconStroke)\n\t\t\t\t\t.attr('shape-rendering', 'crispEdges')\n\n\t\t\t\tcurrlinex += 2.5 * settings.padx\n\t\t\t}\n\t\t}\n\n\t\tif (Math.abs(bbox.y + bbox.height / 2) > 1) {\n\t\t\t// dominant-baseline is not supported, manually position\n\t\t\titemlabel.attr('y', bbox.height / 4)\n\t\t}\n\t}\n\n\treturn render\n}\n\nlet i = 0\nfunction getId() {\n\treturn `${i++}-${Date.now().toString().slice(-6)}-${Math.random().toString().slice(-6)}`\n}\n", "import { select } from 'd3-selection'\n\nexport function svgScroll(_opts) {\n\tif (!_opts.holder) throw `missing svgScroll.opts.holder argument`\n\tconst defaults = {\n\t\theight: 12,\n\t\tzoomLevel: 1,\n\t\topacity: 0.3\n\t}\n\n\tconst opts = Object.assign({}, defaults, _opts)\n\n\tfunction scrollInit(e) {\n\t\tref.x = e.clientX\n\t\tselect('body').on('mousemove.sjppSvgScroll', scrollMove).on('mouseup.sjppSvgScroll', scrollStop)\n\t}\n\n\tfunction scrollMove(e) {\n\t\tif (!('x' in ref)) return\n\t\tconst dx = e.clientX - ref.x\n\t\tif (ref.sliderX + ref.sliderWidth + dx > opts.visibleWidth - 1) {\n\t\t\t// when the available space at the right side is less than the distance moved to the right\n\t\t\treturn\n\t\t}\n\t\tif (ref.sliderX + dx < 0) {\n\t\t\t// when the available space at the left side is less than the distance moved to the left\n\t\t\treturn\n\t\t}\n\t\tslider.attr('x', ref.sliderX + dx)\n\t\topts.callback(ref.dxFactor * dx, 'move')\n\t}\n\n\tfunction scrollStop(e) {\n\t\tif (!('x' in ref)) return\n\t\tconst dx = e.clientX - ref.x\n\t\topts.callback(ref.dxFactor * Math.min(ref.maxDx, Math.max(dx, ref.minDx)), 'up')\n\t\tdelete ref.x\n\t\tselect('body').on('mousemove.sjppSvgScroll', null).on('mouseup.sjppSvgScroll', null)\n\t}\n\n\tfunction scrollByClick(e) {\n\t\tref.x = e.clientX\n\t\tconst i = e.clientX < slideElem.getBoundingClientRect().x ? -1 : 1\n\t\tscrollStop({ clientX: Math.floor(ref.x + i * ref.arrowDx) })\n\t}\n\n\topts.holder\n\t\t.attr('display', 'none')\n\t\t.attr('opacity', opts.opacity)\n\t\t.on('mouseover', () => opts.holder.attr('opacity', 1))\n\t\t.on('mouseout', () => opts.holder.attr('opacity', opts.opacity))\n\n\t// assumes horizontal for now\n\tconst rect = opts.holder\n\t\t.append('rect')\n\t\t.style('height', opts.height)\n\t\t.style('stroke', 'none')\n\t\t//.style('stroke-width', 1)\n\t\t//.attr('rx', opts.height / 2)\n\t\t.style('fill', '#fff')\n\t\t.on('click', scrollByClick)\n\n\tconst line = opts.holder.append('line').style('stroke', '#ccc').style('stroke-width', 1).on('click', scrollByClick)\n\n\tconst leftArrow = opts.holder\n\t\t.append('path')\n\t\t.attr('y', -opts.height)\n\t\t.attr('d', `M0,${opts.height / 2}L${opts.height},0L${opts.height},${opts.height}Z`)\n\t\t.style('stroke', '#ccc')\n\t\t.style('stroke-width', 1)\n\t\t//.attr('rx', opts.height / 2)\n\t\t.style('fill', '#ccc')\n\t\t.on('click', e => {\n\t\t\tref.x = e.clientX\n\t\t\tscrollStop({ clientX: Math.round(ref.x - ref.arrowDx) })\n\t\t})\n\n\tconst rtArrow = opts.holder\n\t\t.append('path')\n\t\t.attr('y', -opts.height)\n\t\t.style('stroke', '#ccc')\n\t\t.style('stroke-width', 1)\n\t\t//.attr('rx', opts.height / 2)\n\t\t.style('fill', '#ccc')\n\t\t.attr('d', `M0,0L${opts.height},${opts.height / 2}L0,${opts.height}Z`)\n\t\t.on('click', e => {\n\t\t\tref.x = e.clientX\n\t\t\tscrollStop({ clientX: Math.round(ref.x + ref.arrowDx) })\n\t\t})\n\n\tconst sliderHt = opts.height - 4\n\tconst slider = opts.holder\n\t\t.append('rect')\n\t\t.attr('y', 2)\n\t\t.attr('height', sliderHt)\n\t\t.attr('stroke', '#aaa')\n\t\t.attr('stroke-width', 1)\n\t\t.attr('fill', '#ccc')\n\t\t.attr('rx', sliderHt / 2)\n\t\t.on('mousedown', scrollInit)\n\t\t.on('mousemove', scrollMove)\n\t\t.on('mouseup', scrollStop)\n\n\tconst slideElem = slider.node()\n\n\tconst ref = {}\n\n\tconst api = {\n\t\tupdate(_opts) {\n\t\t\tconst prev = { v: opts.visibleWidth, t: opts.totalWidth, z: opts.zoomCenter }\n\t\t\tObject.assign(opts, _opts)\n\t\t\tconst t = opts.totalWidth\n\t\t\tconst v = opts.visibleWidth\n\t\t\tif (t <= v) {\n\t\t\t\topts.holder.attr('display', 'none')\n\t\t\t\treturn\n\t\t\t}\n\t\t\topts.holder.attr('transform', `translate(${opts.x},${opts.y})`).attr('display', '')\n\n\t\t\trect.attr('width', v)\n\n\t\t\tline\n\t\t\t\t.attr('x1', 0)\n\t\t\t\t.attr('x2', v)\n\t\t\t\t.attr('y1', opts.height / 2)\n\t\t\t\t.attr('y2', opts.height / 2)\n\n\t\t\tleftArrow.attr('transform', `translate(0,0)`)\n\n\t\t\trtArrow.attr('transform', `translate(${v - opts.height},0)`)\n\n\t\t\tif (v != prev.v || t != prev.t) {\n\t\t\t\t// multiply visibleWidth by the ratio of v:t,\n\t\t\t\t// to make the slider width proportional to v:t\n\t\t\t\tref.sliderWidth = (v * v) / t\n\t\t\t\t// each slider dx movement is equivalent to the ratio of\n\t\t\t\t// the open slider space on its left and right side\n\t\t\t\t// versus the unseen left and right portions of the element to be scrolled;\n\t\t\t\t// in other words, the available slidable segment of the scrollbar handle\n\t\t\t\t// proprotionally represents the unseen segment of the svg element\n\t\t\t\tref.dxFactor = (t - v) / (v - ref.sliderWidth)\n\t\t\t}\n\n\t\t\tconst center = v * (opts.zoomCenter / t)\n\t\t\tref.sliderX = Math.max(0, Math.min(center - ref.sliderWidth / 2, v - ref.sliderWidth - 1))\n\t\t\tslider.attr('width', ref.sliderWidth).attr('x', ref.sliderX)\n\n\t\t\tref.maxDx = opts.visibleWidth - ref.sliderX - ref.sliderWidth\n\t\t\tref.minDx = -ref.sliderX\n\t\t\tref.arrowDx = Math.round(0.1 * opts.visibleWidth)\n\t\t\tdelete ref.x\n\t\t}\n\t}\n\n\treturn api\n}\n", "/*\nmake a html table of two columns, for showing a list of key-value pairs.\n1st column shows key in gray text, 2nd column shows value in black text, or arbitrary button/svg etc\nas rows are added, as soon as table width exceeds a limit, it auto scrolls\n\nto create new table:\n\n\tconst table = table2col({holder})\n\nto add a new row with only text data:\n\n\ttable.addRow('Key', 'Value')\n\nif need to insert html and other dynamic contents instead of plain text, do this instead:\n\n\tconst [td1,td2] = table.addRow()\n\ttd1.html(xx)\n\ttd2.append('input')...\n\n\narg{}\n\t.holder\n\t.margin\n\t.cellPadding\n\t.disableScroll=true\n\t.testid // overrides default\n*/\nexport function table2col(arg) {\n\tconst scrollDiv = arg.holder.append('div').style('max-width', '80vw')\n\n\tconst table = scrollDiv\n\t\t.append('table')\n\t\t.style('margin', arg.margin || '5px 8px')\n\t\t.attr('class', 'sja_simpletable')\n\t\t.attr('data-testid', arg.testid || 'sja_simpletable')\n\treturn {\n\t\tscrollDiv,\n\t\ttable,\n\t\taddRow: (text1, text2) => {\n\t\t\tif (table.node().offsetHeight > 500 && !arg.disableScroll) {\n\t\t\t\tscrollDiv\n\t\t\t\t\t.style('height', '450px')\n\t\t\t\t\t.style('resize', 'both')\n\t\t\t\t\t.style('overflow-y', 'scroll')\n\t\t\t\t\t.attr('class', 'sjpp_show_scrollbar')\n\t\t\t}\n\t\t\tconst tr = table.append('tr')\n\t\t\tconst td1 = tr\n\t\t\t\t.append('td')\n\t\t\t\t.style('padding', arg.cellPadding || '3px')\n\t\t\t\t.style('color', '#555')\n\t\t\tconst td2 = tr.append('td').style('padding', arg.cellPadding || '3px')\n\t\t\tif (text1 != undefined) td1.text(text1)\n\t\t\tif (text2 != undefined) td2.text(text2)\n\t\t\treturn [td1, td2]\n\t\t}\n\t}\n}\n\n/*\ndata[ {} ]\n.kvlst[]\n.k\n.v\n\ndeprecated, replace with above\n*/\nexport function make_table_2col(holder, data, overlen) {\n\tconst color = '#9e9e9e'\n\tconst table = holder\n\t\t.append('table')\n\t\t.style('margin', '5px 8px')\n\t\t.style('font-size', 'inherit')\n\t\t.attr('class', 'sja_simpletable')\n\tfor (const i of data) {\n\t\tconst tr = table.append('tr')\n\t\tif (i.kvlst) {\n\t\t\ttr.append('td').attr('rowspan', i.kvlst.length).style('padding', '3px').style('color', color).html(i.k)\n\t\t\ttr.append('td').style('padding', '3px').style('color', color).html(i.kvlst[0].k)\n\t\t\ttr.append('td').style('padding', '3px').html(i.kvlst[0].v)\n\t\t\tfor (let j = 1; j < i.kvlst.length; j++) {\n\t\t\t\tconst tr2 = table.append('tr')\n\t\t\t\ttr2.append('td').style('padding', '3px').style('color', color).html(i.kvlst[j].k)\n\t\t\t\ttr2.append('td').style('padding', '3px').html(i.kvlst[j].v)\n\t\t\t}\n\t\t} else {\n\t\t\ttr.append('td').attr('colspan', 2).style('padding', '3px').style('color', color).html(i.k)\n\t\t\tconst td = tr.append('td').style('padding', '3px')\n\t\t\tif (overlen && i.v.length > overlen) {\n\t\t\t\ttd.html(i.v.substr(0, overlen - 3) + ' ...»')\n\t\t\t\t\t.attr('class', 'sja_clbtext')\n\t\t\t\t\t.on('click', () => {\n\t\t\t\t\t\ttd.html(i.v).classed('sja_clbtext', false).on('click', null)\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttd.html(i.v)\n\t\t\t}\n\t\t}\n\t}\n\treturn table\n}\n", "import { select } from 'd3-selection'\nimport type { TabsInputEntry, TabsOpts } from './types/toggleButtons'\n\n/*\n********************** EXPORTED\nTabs(opts)\n\nNote: \n- newly created dom elements are attached to opts{} and tabs for external code to access\n- if everything should be rendered in single holder, supply just `holder`\n- if main tabs and div containing tab specific ui (e.g. the app drawer sandboxes) should be in different tabs, \n\tdefine them sepeartely as holder and contentholder\n- tab data is bound to the rendered tab elements/content holder and vice-versa. \n\tFor easier debugging, in the console using inspect element > styles > properties > __data__\t\n*/\n\nconst activeColor = '#1575ad'\nconst inactiveColor = '#757373'\n\nexport class Tabs {\n\topts: TabsOpts\n\ttabs: TabsInputEntry[]\n\tdom: {\n\t\tholder: HTMLDivElement\n\t}\n\tdefaultTabWidth: number\n\trender: any\n\tupdate: any\n\n\tconstructor(opts: TabsOpts) {\n\t\tthis.opts = this.validateOpts(opts)\n\t\tthis.tabs = opts.tabs\n\t\tthis.dom = {\n\t\t\tholder: opts.holder\n\t\t}\n\t\tthis.defaultTabWidth = 90\n\t\tsetRenderers(this)\n\t}\n\n\tvalidateOpts(opts: TabsOpts) {\n\t\tif (!opts.holder) throw `missing opts.holder for Tabs()`\n\t\tif (!Array.isArray(opts.tabs)) throw `invalid opts.tabs array for Tabs()`\n\t\tif (!opts.tabsPosition) opts.tabsPosition = 'horizontal'\n\t\tif (opts.tabsPosition != 'horizontal' && opts.tabsPosition != 'vertical')\n\t\t\tthrow `Invalid .tabsPosition arg. Must be either vertical or horizontal`\n\t\tif (!opts.linePosition) {\n\t\t\topts.linePosition = opts.tabsPosition == 'horizontal' ? 'bottom' : 'right'\n\t\t}\n\t\tif (\n\t\t\topts.linePosition != 'bottom' &&\n\t\t\topts.linePosition != 'top' &&\n\t\t\topts.linePosition != 'right' &&\n\t\t\topts.linePosition != 'left'\n\t\t)\n\t\t\tthrow `Invalid .linePosition arg. Must be either bottom, top, right, or left`\n\t\treturn opts\n\t}\n\n\tasync main() {\n\t\ttry {\n\t\t\tawait this.render()\n\t\t} catch (e: any) {\n\t\t\tif (e.stack) console.log(e.stack)\n\t\t\telse throw e\n\t\t}\n\t}\n}\n\nfunction setRenderers(self) {\n\tself.render = async () => {\n\t\tconst has_active_tab = self.tabs.find(tab => tab.active)\n\t\tif (!has_active_tab) self.tabs[0].active = true\n\n\t\tconst textAlign =\n\t\t\tself.opts.linePosition == 'bottom' || self.opts.linePosition == 'top' ? 'center' : self.opts.linePosition\n\n\t\t/* Implementation assumes the position of the tabs and content are not contiguous\n\t\tto accommodate all situations. If having troubles with rendering, try creating \n\t\ta wrapper for the tabsHolder and contentHolder. */\n\n\t\tself.dom.tabsHolder = self.dom.holder\n\t\t\t.append('div')\n\t\t\t//add light blue border underneath the buttons\n\t\t\t.style(`border-${self.opts.linePosition}`, '0.5px solid #1575ad')\n\n\t\tif (!self.dom.contentHolder && !self.opts.noContent) {\n\t\t\tself.dom.contentHolder = self.opts.contentHolder || self.dom.holder.append('div')\n\t\t}\n\n\t\tif (self.opts.tabsPosition == 'vertical') {\n\t\t\tself.dom.tabsHolder\n\t\t\t\t.style('display', 'inline-grid')\n\t\t\t\t.style('align-items', 'start')\n\t\t\t\t.style('gap', self.opts.gap || '')\n\t\t\tself.dom.contentHolder\n\t\t\t\t//First part of fix for svgs rendering inline, outside of the contentHolder\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('vertical-align', 'top')\n\t\t\t\t.style('position', 'relative')\n\t\t} else self.dom.tabsHolder.style('display', 'inline-block')\n\n\t\tawait self.dom.tabsHolder\n\t\t\t.selectAll('button')\n\t\t\t.data(self.tabs)\n\t\t\t.enter()\n\t\t\t.append('button')\n\t\t\t.attr('data-testid', d => d.testid || 'sja_toggle_button')\n\t\t\t.attr('class', 'sj-toggle-button') //\n\t\t\t.classed('sjpp-active', tab => tab.active)\n\t\t\t//Padding here overrides automatic styling for all pp buttons\n\t\t\t.style('padding', '0px')\n\t\t\t.style('width', tab => (tab.width ? `${tab.width}px` : 'fit-content'))\n\t\t\t.style('min-width', tab => (tab.width ? null : Math.max(self.defaultTabWidth)))\n\t\t\t.style('border', 'none')\n\t\t\t.style('background-color', 'transparent')\n\t\t\t.style('display', tab => {\n\t\t\t\tif (!tab.isVisible || tab.isVisible()) return self.opts.tabsPosition == 'vertical' ? 'flex' : 'inline-grid'\n\t\t\t\telse return 'none'\n\t\t\t})\n\t\t\t.property('disabled', tab => (tab.disabled ? tab.disabled() : false))\n\t\t\t.each(async function (this: any, tab) {\n\t\t\t\tif (tab.active) {\n\t\t\t\t\t// assume that an active tabbed content div should receive focus when first rendered,\n\t\t\t\t\t// otherwise using tabs to navigate would not be intuitive or user-friendly if it\n\t\t\t\t\t// starts far away from recently rendered content\n\t\t\t\t\tthis.focus()\n\t\t\t\t\t// blur the forced autofocus right away, only want the menu/pane to have priority when\n\t\t\t\t\t// navigating by keyboard, don't want the browser's default element highlight\n\t\t\t\t\t// (blue border in Chrome) to be distracting\n\t\t\t\t\tthis.blur()\n\t\t\t\t}\n\n\t\t\t\t/* The whole button is clickable (i.e. the white space where the blue, 'active' line\n\t\t\t\tis not visible). The event is on the button (i.e. tab.wrapper). The style changes \n\t\t\t\twhen the button is active/inactive are on the text (i.e. tab.tab) and line \n\t\t\t\t(i.e. tab.line) */\n\t\t\t\tconst isVisible = tab.isVisible ? tab.isVisible() : true\n\t\t\t\ttab.wrapper = select(this).style('cursor', isVisible && tab.disabled?.() ? 'not-allowed' : 'pointer')\n\n\t\t\t\tif (self.opts.linePosition == 'right') tab.wrapper.style('justify-self', 'end')\n\t\t\t\tif (self.opts.linePosition == 'left') tab.wrapper.style('justify-self', 'start')\n\n\t\t\t\t//Line position determines the order of appending divs\n\t\t\t\tif (self.opts.linePosition == 'top' || self.opts.linePosition == 'left') {\n\t\t\t\t\t//create the line div before the tab text\n\t\t\t\t\ttab.line = tab.wrapper\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.style('display', self.opts.linePosition == 'left' ? 'inline-flex' : 'flex')\n\t\t\t\t\ttab.tab = tab.wrapper\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.style('display', self.opts.linePosition == 'left' ? 'inline-block' : 'block')\n\t\t\t\t} else {\n\t\t\t\t\t//create the line div after the tab text\n\t\t\t\t\ttab.tab = tab.wrapper\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.style('display', self.opts.linePosition == 'right' ? 'inline-block' : 'block')\n\t\t\t\t\ttab.line = tab.wrapper\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.style('display', self.opts.linePosition == 'right' ? 'inline-flex' : 'flex')\n\t\t\t\t}\n\n\t\t\t\ttab.tab //Button text\n\t\t\t\t\t.attr('data-testid', `sjpp-toggle_button-text-${tab.label.toLowerCase().replace(/\\s/g, '-')}`)\n\t\t\t\t\t.style('color', tab.active ? activeColor : inactiveColor)\n\t\t\t\t\t.style('text-align', textAlign)\n\t\t\t\t\t.style('padding', '5px')\n\t\t\t\t\t.html(tab.label)\n\n\t\t\t\ttab.line //Bolded, blue line indicating the active button\n\t\t\t\t\t.style('background-color', activeColor)\n\t\t\t\t\t.style('visibility', tab.active ? 'visible' : 'hidden')\n\n\t\t\t\tif (self.opts.linePosition == 'top' || self.opts.linePosition == 'bottom') {\n\t\t\t\t\ttab.line.style('height', '8px').style('padding', '0px 5px')\n\t\t\t\t} else {\n\t\t\t\t\ttab.line\n\t\t\t\t\t\t//stretch tricks div to expand to full height\n\t\t\t\t\t\t.style('align-self', 'stretch')\n\t\t\t\t\t\t.style('padding', '5px 0px')\n\t\t\t\t\t\t//inline width prevents width changing for long labels\n\t\t\t\t\t\t.html('<span style=\"width: 8px\";> </span>')\n\t\t\t\t}\n\n\t\t\t\tif (self.dom.contentHolder) {\n\t\t\t\t\ttab.contentHolder = self.dom.contentHolder\n\t\t\t\t\t\t/* Second part of svg rendering fix: Extra div prevents svgs from displaying \n\t\t\t\t\tabove contentHolder (i.e. inline at the beginning of the holder). \n\t\t\t\t\tDiv acts as a `viewBox`.*/\n\t\t\t\t\t\t.append('div')\n\t\t\t\t\t\t.style('display', tab.active ? 'block' : 'none')\n\t\t\t\t\tif (self.opts.tabsPosition == 'horizontal' && !self.opts.noTopContentStyle) {\n\t\t\t\t\t\ttab.contentHolder.style('padding-top', '10px').style('margin-top', '10px')\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// TODO: window.event should not be used, see https://developer.mozilla.org/en-US/docs/Web/API/Window/event\n\t\t\t\t// event should always be detected from an event handler/listener's first argument\n\t\t\t\tif (tab.active && tab.callback) await tab.callback(event, tab)\n\n\t\t\t\ttab.wrapper\n\t\t\t\t\t.on('mouseenter', () => {\n\t\t\t\t\t\ttab.tab.style('color', tab.active ? inactiveColor : activeColor)\n\t\t\t\t\t})\n\t\t\t\t\t.on('mouseleave', () => {\n\t\t\t\t\t\ttab.tab.style('color', tab.active ? activeColor : inactiveColor)\n\t\t\t\t\t})\n\t\t\t})\n\t\t\t.on('click', async (event, tab) => {\n\t\t\t\tfor (const t of self.tabs) {\n\t\t\t\t\t/** Hide tab content on double click if specified */\n\t\t\t\t\tif (self.opts.hideOnDblClick && t.active == true && t === tab) {\n\t\t\t\t\t\tt.active = false\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tt.active = t === tab\n\t\t\t\t}\n\t\t\t\tconst activeTabIndex = self.tabs.findIndex(t => t.active) //Fix for non-Rx implementations\n\n\t\t\t\t/*\n\t\t\t\tTODO: self.update() not required for non-RX components\n\t\t\t\tIdea is to create super class, then state and stateless components\n\t\t\t\tfor rx and non-rx components, respectively.\n\t\t\t\trx -> include app.dispatch() here. Maybe other intuitive methods to \n\t\t\t\t\tallievate callback code in tabs array\n\t\t\t\tnon-rx -> include self.update() here without activeTabIndex arg\n\t\t\t\t*/\n\t\t\t\tself.update(activeTabIndex)\n\t\t\t\tif (tab.callback) await tab.callback(event, tab)\n\t\t\t})\n\t\t\t.on('keydown', async function (event, tab) {\n\t\t\t\t// ignore this event if it bubbled up from a descendant element\n\t\t\t\tif (event.target.tagName != 'BUTTON') return\n\t\t\t\tif (event.key == 'Escape') {\n\t\t\t\t\treturn false\n\t\t\t\t} else if (event.key == 'Enter') {\n\t\t\t\t\t// default behavior equals click event\n\t\t\t\t\tif (tab.keydownCallback) tab.keydownCallback(event, tab)\n\t\t\t\t}\n\t\t\t})\n\t\tconst activeTabIndex = self.tabs.findIndex(t => t.active) //Fix for non-Rx implementations\n\t\tself.update(activeTabIndex)\n\t}\n\n\tself.update = (activeTabIndex = 0) => {\n\t\tself.tabs.forEach((tab, i) => {\n\t\t\ttab.active = activeTabIndex === i\n\t\t})\n\t\tself.dom.tabsHolder\n\t\t\t.selectAll('button')\n\t\t\t.data(self.tabs)\n\t\t\t.classed('sjpp-active', tab => tab.active)\n\t\t\t.each(tab => {\n\t\t\t\tconst isVisible = tab.isVisible ? tab.isVisible() : true\n\t\t\t\ttab.wrapper.classed('sjpp-active', tab.active)\n\t\t\t\tif (tab.isVisible) tab.wrapper.style('display', isVisible ? '' : 'none')\n\t\t\t\tif (tab.contentHolder) tab.contentHolder.style('display', tab.active ? 'block' : 'none')\n\t\t\t\ttab.tab.style('color', tab.active ? activeColor : inactiveColor)\n\t\t\t\ttab.line.style('visibility', tab.active ? 'visible' : 'hidden')\n\t\t\t\ttab.tab.html(tab.label) // re-print tab label since the label value could have been updated by outside code\n\t\t\t})\n\t}\n}\n", "export function zoom(opts) {\n\tif (!opts.holder) throw `zoom requires an opts.holder`\n\tif (typeof opts.callback != 'function') throw `zoom requires an opts.callback function`\n\n\tconst defaultSettings = {\n\t\tmin: 1,\n\t\tmax: 100,\n\t\tvalue: 25,\n\t\tstep: 10,\n\t\tincrement: 1,\n\t\tnumberInputWidth: '35px',\n\t\tshowJumpBtns: false\n\t}\n\n\tconst settings = Object.assign({}, defaultSettings, opts.settings || {})\n\n\tlet showSlider = false\n\topts.holder\n\t\t.attr('title', opts.title || null)\n\t\t.style('vertical-align', 'top')\n\t\t.style('text-align', 'center')\n\t\t.on('mouseenter', () => {\n\t\t\tsliderDiv.style('display', 'inline-block').style('overflow', 'visible')\n\t\t\tshowSlider = true\n\t\t})\n\t\t.on('mouseleave', () => {\n\t\t\tsliderDiv.style('display', 'none').style('overflow', 'hidden')\n\t\t\tshowSlider = false\n\t\t})\n\n\tconst label = opts.holder.append('label')\n\tconst labelText = label.append('span').text('Zoom')\n\n\tconst number = label\n\t\t.append('input')\n\t\t.attr('title', 'Enter a desired zoom level')\n\t\t.attr('type', 'number')\n\t\t.attr('min', settings.min)\n\t\t.attr('max', settings.max)\n\t\t.attr('step', settings.increment)\n\t\t.style('min-width', settings.numberInputWidth)\n\t\t.style('width', opts.width || 'fit-content')\n\t\t.style('margin', '3px 5px')\n\t\t.property('value', settings.value)\n\t\t.on('change', event => {\n\t\t\tconst value = Number(event.target.value)\n\t\t\tapi.update({ value })\n\t\t\topts.callback(value)\n\t\t})\n\n\tlabel.append('span').text('unit' in opts ? opts.unit : '%')\n\n\t// if the zoom is rendered within a parent/ancestor div that is invisible,\n\t// then the box dimensions will be zero, will be corrected in the update()\n\t// below as needed\n\tconst box = opts.holder.node().getBoundingClientRect()\n\topts.holder.style('max-height', box.height + 'px').style('max-width', box.width + 'px')\n\n\topts.holder.append('br')\n\n\tconst sliderDiv = opts.holder.append('div').style('display', 'none')\n\n\tconst minusBtn = !opts.showJumpBtns\n\t\t? null\n\t\t: opts.holder\n\t\t\t\t.append('button')\n\t\t\t\t.attr('title', 'Zoom in')\n\t\t\t\t.style('width', '25px')\n\t\t\t\t.html('-')\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tconst value = Math.max(\n\t\t\t\t\t\tsettings.step * Math.ceil((settings.value - settings.step) / settings.step),\n\t\t\t\t\t\tsettings.min\n\t\t\t\t\t)\n\t\t\t\t\tapi.update({ value })\n\t\t\t\t\topts.callback(value)\n\t\t\t\t})\n\n\tconst slider = sliderDiv\n\t\t.append('input')\n\t\t.attr('title', 'Slide to desired zoom level')\n\t\t.attr('type', 'range')\n\t\t.attr('min', settings.min)\n\t\t.attr('max', settings.max)\n\t\t.attr('step', settings.increment)\n\t\t.style('margin', '2px 5px')\n\t\t.style('padding', 0)\n\t\t.style('vertical-align', 'middle')\n\t\t.property('value', settings.value)\n\t\t.html('-')\n\t\t.on('input', event => {\n\t\t\tnumber.property('value', event.target.value)\n\t\t})\n\t\t.on('change', event => {\n\t\t\tconst value = Number(event.target.value)\n\t\t\tapi.update({ value })\n\t\t\topts.callback(value)\n\t\t})\n\n\t// TODO: may give an option to render plus/minus 'jump' buttons\n\tconst plusBtn = !opts.showJumpBtns\n\t\t? null\n\t\t: opts.holder\n\t\t\t\t.append('button')\n\t\t\t\t.attr('title', 'Zoom out')\n\t\t\t\t.style('width', '25px')\n\t\t\t\t.html('+')\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tconst value = Math.min(\n\t\t\t\t\t\tsettings.step * Math.floor((settings.value + settings.step) / settings.step),\n\t\t\t\t\t\tsettings.max\n\t\t\t\t\t)\n\t\t\t\t\tapi.update({ value })\n\t\t\t\t\topts.callback(value)\n\t\t\t\t})\n\n\tsliderDiv\n\t\t.append('span')\n\t\t.style('text-decoration', 'underline')\n\t\t.style('cursor', 'pointer')\n\t\t.style('title', 'use the default zoom value')\n\t\t.text('Reset')\n\t\t.on('click', opts.reset)\n\n\tconst api = {\n\t\tupdate(s = {}) {\n\t\t\tconst box = opts.holder.node().getBoundingClientRect()\n\t\t\tif (!box.height || !box.width) {\n\t\t\t\t// when the matrix renders in an invisible div, these dimensions are empty,\n\t\t\t\t// should be reset based on the width of its contents\n\t\t\t\topts.holder.style('max-height', '').style('max-width', '')\n\t\t\t\tconst box = opts.holder.node().getBoundingClientRect()\n\t\t\t\topts.holder.style('max-height', box.height + 'px').style('max-width', box.width + 'px')\n\t\t\t}\n\n\t\t\tObject.assign(settings, s)\n\t\t\tslider\n\t\t\t\t.property('value', settings.value)\n\t\t\t\t.attr('min', settings.min)\n\t\t\t\t.attr('max', settings.max)\n\t\t\t\t.attr('step', settings.increment)\n\t\t\tnumber\n\t\t\t\t.property('value', settings.value)\n\t\t\t\t.attr('min', settings.min)\n\t\t\t\t.attr('max', settings.max)\n\t\t\t\t.attr('step', settings.increment)\n\t\t\tminusBtn?.property('disabled', settings.value <= settings.min)\n\t\t\tplusBtn?.property('disabled', settings.value >= settings.max)\n\t\t}\n\t}\n\n\tif (opts.debug)\n\t\tapi.Inner = {\n\t\t\tsettings,\n\t\t\tnumber,\n\t\t\tslider,\n\t\t\tminusBtn,\n\t\t\tplusBtn\n\t\t}\n\n\treturn api\n}\n", "import { getCompInit } from '#rx'\nimport { Menu, getAncestorWithComputedStyle } from '#dom'\nimport { getNormalRoot } from '#filter/filter'\nimport { NumericModes, TermTypes } from '#shared/terms.js'\nimport { importPlot } from '#plots/importPlot.js'\n\nclass MassCharts {\n\tstatic type = 'charts'\n\n\tconstructor(opts = {}) {\n\t\tthis.type = MassCharts.type\n\t\t// stickyAncestor will attached to button data, to be used by menu.stickyPosition()\n\t\t// when showing the menu tip near a clicked chart button\n\t\tthis.stickyAncestor = getAncestorWithComputedStyle(opts.holder.node(), 'position', new Set(['sticky', 'fixed']))\n\t\tsetRenderers(this)\n\t}\n\n\tasync init(appState) {\n\t\tthis.dom = {\n\t\t\tholder: this.opts.holder,\n\t\t\ttip: new Menu({ padding: '0px', testid: 'sjpp-mass-nav-chartBtnMenu' }),\n\t\t\ttooltip: new Menu({ padding: '4px' })\n\t\t}\n\n\t\tthis.makeButtons(appState)\n\t}\n\n\t// TODO later add reactsTo() to react to filter change\n\n\tgetState(appState) {\n\t\tconst state = {\n\t\t\tvocab: appState.vocab, // TODO delete it as vocabApi should be used instead\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\ttermfilter: appState.termfilter,\n\t\t\tcurrentCohortChartTypes: getCurrentCohortChartTypes(appState),\n\t\t\ttermdbConfig: appState.termdbConfig\n\t\t}\n\t\tif (appState?.termfilter?.filter) {\n\t\t\tstate.filter = getNormalRoot(appState.termfilter.filter)\n\t\t}\n\t\treturn state\n\t}\n\n\tmain() {\n\t\tthis.dom.btns.style('display', d => (this.state.currentCohortChartTypes.includes(d.chartType) ? '' : 'none'))\n\t}\n\n\tgetBtnLabel_dict(state) {\n\t\t// has \"queries\" meaning presence of non-dictionary data types, use \"Variables\" to broaden scope and not limited to just \"Dictionary\"\n\t\treturn state.termdbConfig.queries ? 'Data Variables' : 'Data Dictionary'\n\t}\n\tgetBtnLabel_regression(state) {\n\t\t/* define button label based on conditions:\n\t\tif ds allows multiple regression methods, use generic name, click btn will display menu of options\n\t\tif ds allows just one method, directly show method name on button, click btn will show sandbox\n\t\t*/\n\t\tconst lst = getCurrentCohortChartTypes(state)\n\t\tif (!lst.includes('regression')) return '' // plot not supported. label doesn't matter as button will be hidden\n\t\tconst ms = []\n\t\tif (lst.includes('linear')) ms.push('linear')\n\t\tif (lst.includes('logistic')) ms.push('logistic')\n\t\tif (lst.includes('cox')) ms.push('cox')\n\t\tif (ms.length > 1) return 'Regression Analysis' // more than 1 methods. return general name\n\t\t// only 1 method\n\t\treturn `${ms[0] == 'linear' ? 'Linear' : ms[0] == 'cox' ? 'Cox' : 'Logistic'} Regression`\n\t}\n\tgetBtnLabel_sampleScatter(state) {\n\t\t// define button label\n\t\tconst lst = getCurrentCohortChartTypes(state)\n\t\tif (state.termdbConfig.scatterplots?.length == 1 && !lst.includes('dynamicScatter')) {\n\t\t\t// has 1 premade plot and no dynamic scatter. just show premade plot name as button name\n\t\t\treturn state.termdbConfig.scatterplots[0].name\n\t\t}\n\t\t// either has >1 premade plots or dynamic scatter. show generic name\n\t\treturn 'Sample Scatter'\n\t}\n\tgetBtnLabel_report(state) {\n\t\treturn state.termdbConfig.plotConfigByCohort?.default?.report?.name || 'Report'\n\t}\n\tgetBtnLabel_summarizeMutationTerm(state, phrase) {\n\t\tif (!state.termdbConfig.queries) return 'Not supported!' // the function always runs for all ds, thus must detect and guard against it; in such case the btn should not be shown\n\t\tconst t = []\n\t\tif (state.termdbConfig.queries.snvindel) t.push('Mutation')\n\t\tif (state.termdbConfig.queries.cnv) t.push('CNV')\n\t\tif (state.termdbConfig.queries.svfusion) t.push('Fusion')\n\t\t// todo customize Diagnosis\n\t\treturn `${t.length > 2 ? 'Alterations' : t.join('/')} vs ${phrase}`\n\t}\n}\n\nexport const chartsInit = getCompInit(MassCharts)\n\nexport function getActiveCohortStr(appState) {\n\tif (appState?.termdbConfig?.selectCohort?.values) {\n\t\t// dataset allows subcohort selection\n\t\tif (!Number.isInteger(appState.activeCohort)) throw 'appState.activeCohort is not integer array index'\n\t\tconst activeCohortObject = appState.termdbConfig.selectCohort.values[appState.activeCohort]\n\t\tif (!activeCohortObject) throw 'appState.activeCohort array index out of bound'\n\t\t// get a valid cohort obj\n\t\treturn [...activeCohortObject.keys].sort().join(',')\n\t}\n\t// if not, is undefined\n\treturn ''\n}\n\nexport function getCurrentCohortChartTypes(appState) {\n\tconst activeCohortStr = getActiveCohortStr(appState)\n\tconst chartTypesByCohort = structuredClone(appState.termdbConfig?.supportedChartTypes || {})\n\t// {}, key is cohortstr, value is list of supported chart types under this cohort\n\treturn chartTypesByCohort[activeCohortStr] || ['summary']\n}\n\nfunction getChartTypeList(self, state) {\n\t/* returns a list all possible chart types supported in mass\n\teach char type will generate a button under the nav bar\n\ta dataset can support a subset of these charts\n\n\tallow some chart button objects to be dynamically generated based on state\n\n\tdesign goal is that chart specific logic should not leak into mass UI\n\n\tdesign idea is that a button click will trigger a callback to do one of following things\n\tin which chart-type specific logic is not included\n\n\t1. show dictionary tree\n\t\tby calling showTree_select1term() or showTree_selectlst()\n\t2. prep chart\n\t\tby calling prepPlot()\n\t3. display chart-specific menu by importing plot code using importPlot()\n\t\tand call the imported function loadChartSpecificMenu()\n\n\t.label:\n\t\ttext to show in the button\n\n\t.chartType:\n\t\tvalues are controlled\n\t\tmust include for deciding if to display a chart button for a dataset\n\t\te.g. cumulative incidence plot will require \"condition\" term to be present in a dataset\n\t\tsee main()\n\n\t.clickTo:\n\t\tcallback to handle the button click event, may use any of the following renderer methods:\n\t\t- self.tree_select1term()\n\t\t\twill show a term tree to select a term\t\n\t\t- self.prepPlot()\n\t\t\tdispatch \"plot_prep\" action to produce a 'initiating' UI of this plot,\n\t\t\tfor user to fill in additional details to launch the plot\n\t\t\texample: regression, table, scatterplot which requires user to select two terms\n\t\t- self.plotCreate()\n\t\t\twhen using prepPlot this error was raised: No plot with id='${this.id}' found. Did you set this.id before this.api = getComponentApi(this). TODO consolidate\n\n\t.usecase:{}\n\t\trequired for clickTo=tree_select1term\n\t\tprovide to termdb app\n\n\t.config:{}\n\t\trequired for clickTo=prepPlot\n\t\tdescribe private details for creating a chart of a particular type\n\t\tto be attached to action and used by store\n\n\t.updateActionBySelectedTerms:\n\t\toptional callback. used for geneExpression and metabolicIntensity \"intermediary\" chart types which do not correspond to actual chart, but will route to an actual chart (summary/scatter/hierclust) based on number of selected terms. this callback will update the action based on selected terms to do the routing\n\n\tTODO order of buttons is hardcoded, may allow to customize order\n\t*/\n\n\tconst buttons = [\n\t\t////////////////////// PROFILE PLOTS START //////////////////////\n\t\t{\n\t\t\tlabel: 'Polar',\n\t\t\tchartType: 'profilePolar',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tconfig: { chartType: 'profilePolar' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Polar 2',\n\t\t\tchartType: 'profilePolar2',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tconfig: { chartType: 'profilePolar2' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Barchart',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'profileBarchart',\n\t\t\tconfig: { chartType: 'profileBarchart' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Barchart 2',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'profileBarchart2',\n\t\t\tconfig: { chartType: 'profileBarchart2' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Facility Radar',\n\t\t\tchartType: 'profileRadarFacility',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Facility Radar 2',\n\t\t\tchartType: 'profileRadarFacility2',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Radar',\n\t\t\tchartType: 'profileRadar',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Radar 2',\n\t\t\tchartType: 'profileRadar2',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Templates',\n\t\t\tchartType: 'profileForms',\n\t\t\tclickTo: self.showTree_select1term,\n\t\t\tusecase: { target: 'profileForms', detail: 'tw' },\n\t\t\tconfig: { chartType: 'profileForms' }\n\t\t},\n\t\t////////////////////// PROFILE PLOTS END //////////////////////\n\t\t// rest are general plots applicable to all ds\n\t\t{\n\t\t\tlabel: self.getBtnLabel_dict(state),\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'dictionary',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'dictionary'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t// currently only used by gdc, so hardcoding correlation input label\n\t\t\t// may allow for other labels if used by other datasets\n\t\t\tlabel: 'Correlation Input',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'summaryInput',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'summaryInput'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: self.getBtnLabel_report(state),\n\t\t\tchartType: 'report',\n\t\t\tclickTo: self.plotCreate,\n\t\t\tconfig: { chartType: 'report' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Sample View',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'sampleView',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'sampleView'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: self.getBtnLabel_sampleScatter(state),\n\t\t\tchartType: 'sampleScatter',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Run Chart',\n\t\t\tchartType: 'runChart2',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Frequency Chart',\n\t\t\tchartType: 'runChart2',\n\t\t\tclickTo: self.showTree_select1term,\n\t\t\tusecase: { target: 'runChart2', detail: 'xtw' }\n\t\t},\n\n\t\t{\n\t\t\tlabel: 'Cumulative Incidence',\n\t\t\tchartType: 'cuminc',\n\t\t\tclickTo: self.showTree_select1term,\n\t\t\tusecase: { target: 'cuminc', detail: 'term' }\n\t\t},\n\t\t{\n\t\t\tlabel: 'Survival',\n\t\t\tchartType: 'survival',\n\t\t\tclickTo: self.showTree_select1term,\n\t\t\tusecase: { target: 'survival', detail: 'term' }\n\t\t},\n\n\t\t{\n\t\t\tlabel: self.getBtnLabel_regression(state),\n\t\t\tchartType: 'regression',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\n\t\t{\n\t\t\tlabel: 'Sample Matrix',\n\t\t\tchartType: 'matrix',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Genome Browser',\n\t\t\tchartType: 'genomeBrowser',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\n\t\t// Commenting out this button since DE does not work without specifying two groups\n\t\t//{\n\t\t//\tlabel: 'Differential Expression',\n\t\t//\tchartType: 'DEanalysis',\n\t\t//\tclickTo: self.loadChartSpecificMenu\n\t\t//},\n\n\t\t{\n\t\t\tlabel: 'Data Download',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'dataDownload',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'dataDownload',\n\t\t\t\tterms: []\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Facet Table',\n\t\t\tclickTo: self.loadChartSpecificMenu,\n\t\t\tchartType: 'facet',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'facet'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Brain Imaging',\n\t\t\tclickTo: self.loadChartSpecificMenu,\n\t\t\tchartType: 'brainImaging',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'brainImaging'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Chat',\n\t\t\tclickTo: self.loadChartSpecificMenu,\n\t\t\tchartType: 'chat',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'chat'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Single Cell Plot',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tchartType: 'singleCellPlot',\n\t\t\tconfig: {\n\t\t\t\tchartType: 'singleCellPlot'\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t//This chart may be later on extended to support other gene expression data types\n\t\t\tlabel: 'Gene Expression',\n\t\t\tchartType: 'GeneExpInput',\n\t\t\tclickTo: self.prepPlot,\n\t\t\tconfig: {\n\t\t\t\tchartType: 'GeneExpInput',\n\t\t\t\ttermType: TermTypes.GENE_EXPRESSION\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Metabolite Intensity',\n\t\t\tchartType: 'metaboliteIntensity',\n\t\t\tclickTo: self.showTree_selectlst,\n\t\t\tusecase: { target: 'metaboliteIntensity', detail: 'term' },\n\t\t\tupdateActionBySelectedTerms: (action, termlst) => {\n\t\t\t\tconst twlst = termlst.map(term => ({\n\t\t\t\t\tterm: structuredClone(term),\n\t\t\t\t\tq: { mode: NumericModes.continuous }\n\t\t\t\t}))\n\t\t\t\tif (twlst.length == 1) {\n\t\t\t\t\t// violin\n\t\t\t\t\taction.config.chartType = 'summary'\n\t\t\t\t\taction.config.term = twlst[0]\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (twlst.length == 2) {\n\t\t\t\t\t// scatter\n\t\t\t\t\taction.config.chartType = 'summary'\n\t\t\t\t\taction.config.term = twlst[0]\n\t\t\t\t\taction.config.term2 = twlst[1]\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// 3 or more terms, launch clustering\n\t\t\t\taction.config.chartType = 'hierCluster'\n\t\t\t\taction.config.dataType = TermTypes.METABOLITE_INTENSITY\n\t\t\t\taction.config.termgroups = [{ name: 'Metabolite Intensity Cluster', lst: twlst, type: 'hierCluster' }]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tlabel: 'Protein View',\n\t\t\tchartType: 'proteinView',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Protein Abundance',\n\t\t\tchartType: 'proteomeAbundance',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: state.termdbConfig.numericDictTermCluster?.appName || 'Numeric Dictionary Term cluster',\n\t\t\tchartType: 'numericDictTermCluster',\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Correlation Volcano',\n\t\t\tchartType: 'correlationVolcano',\n\t\t\tusecase: { target: 'correlationVolcano', detail: 'numeric' },\n\t\t\tclickTo: self.showTree_select1term\n\t\t},\n\t\t{\n\t\t\tlabel: 'GRIN2',\n\t\t\tchartType: 'grin2',\n\t\t\tconfig: { chartType: 'grin2' },\n\t\t\tclickTo: self.prepPlot\n\t\t},\n\t\t{\n\t\t\tlabel: self.getBtnLabel_summarizeMutationTerm(state, 'Disease Type'),\n\t\t\tchartType: 'summarizeMutationDiagnosis', // type names of other similar charts should all begin with `summarize` to indcate they are based on summary plot\n\t\t\tusecase: { target: 'summarizeMutationDiagnosis' },\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: self.getBtnLabel_summarizeMutationTerm(state, 'Survival'),\n\t\t\tchartType: 'summarizeMutationSurvival',\n\t\t\tusecase: { target: 'summarizeMutationSurvival' },\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'CNV vs Mutation',\n\t\t\tchartType: 'summarizeMutationCnv',\n\t\t\tusecase: { target: 'summarizeMutationCnv' },\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'CNV vs GeneExp', // this is limited to cnv, and could be generalized to include snvindel/fusion\n\t\t\tchartType: 'summarizeCnvGeneexp',\n\t\t\tusecase: { target: 'summarizeCnvGeneexp' },\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'GeneExp vs Survival',\n\t\t\tchartType: 'summarizeGeneexpSurvival',\n\t\t\tusecase: { target: 'summarizeGeneexpSurvival' },\n\t\t\tclickTo: self.loadChartSpecificMenu\n\t\t},\n\t\t{\n\t\t\tlabel: 'Alpha Genome',\n\t\t\tchartType: 'alphaGenome',\n\t\t\tusecase: { target: 'alphaGenome' },\n\t\t\tclickTo: self.prepPlot,\n\t\t\tconfig: { chartType: 'alphaGenome' }\n\t\t}\n\t]\n\n\tconst renamedChartTypes = state?.termdbConfig.renamedChartTypes || {}\n\tfor (const btn of buttons) {\n\t\tbtn.stickyAncestor = self.stickyAncestor\n\t\tif (renamedChartTypes[btn.chartType]) btn.label = renamedChartTypes[btn.chartType]\n\t}\n\treturn buttons\n}\n\nfunction setRenderers(self) {\n\tself.makeButtons = function (state) {\n\t\tconst chartTypeList = getChartTypeList(self, state)\n\t\tself.dom.btns = self.dom.holder\n\t\t\t.selectAll('button')\n\t\t\t.data(chartTypeList)\n\t\t\t.enter()\n\t\t\t.append('button')\n\t\t\t.attr('data-testid', d => `sjpp-chart-btn-${d.label.toLowerCase().replace(/\\s/g, '-')}`)\n\t\t\t.style('margin', '10px')\n\t\t\t.style('padding', '10px 15px')\n\t\t\t.style('border-radius', '20px')\n\t\t\t.style('border-color', '#ededed')\n\t\t\t.html(d => d.label)\n\t\t\t.on('click', function (event, chart) {\n\t\t\t\tself.dom.tip.clear().showunder(this)\n\t\t\t\tchart.clickTo(chart)\n\t\t\t})\n\t\t\t.on('mouseover', (e, d) => {\n\t\t\t\tif (d.tooltip) self.dom.tooltip.clear().showunder(e.target).d.text(d.tooltip)\n\t\t\t})\n\t\t\t.on('mouseleave', (e, d) => {\n\t\t\t\tif (d.tooltip) self.dom.tooltip.hide()\n\t\t\t})\n\t}\n\n\t/*\t\n\t\tshow termdb tree to select a term\n\t\tonce selected, dispatch \"plot_create\" action (with the selected term) to produce the plot\n\t\texample: summary\n\t*/\n\tself.showTree_select1term = async chart => {\n\t\tif (chart.usecase.label) {\n\t\t\tself.dom.tip.d\n\t\t\t\t.append('div')\n\t\t\t\t.style('margin', '3px 5px')\n\t\t\t\t.style('padding', '3px 5px')\n\t\t\t\t.style('font-weight', 600)\n\t\t\t\t.html(chart.usecase.label)\n\t\t}\n\n\t\tconst action = {\n\t\t\ttype: 'plot_create',\n\t\t\tid: getId(),\n\t\t\tconfig: { chartType: chart.chartType, activeCohort: self.state.activeCohort }\n\t\t}\n\n\t\tif (chart.parentId) action.parentId = chart.parentId\n\n\t\tconst termdb = await import('../termdb/app')\n\t\ttermdb.appInit({\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\tholder: self.dom.tip.d.append('div'),\n\t\t\tstate: {\n\t\t\t\tactiveCohort: self.state.activeCohort,\n\t\t\t\tnav: {\n\t\t\t\t\theader_mode: 'search_only'\n\t\t\t\t},\n\t\t\t\ttree: { usecase: chart.usecase }\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tclick_term: term => {\n\t\t\t\t\t// summary/survival/cuminc all expect config.term{} to be a termsetting object, but not term (which is confusing)\n\t\t\t\t\t// thus convert term into a termwrapper (termsetting obj)\n\t\t\t\t\t// tw.q{} is missing and will be fill in with default settings\n\t\t\t\t\tconst tw = term.term ? term : { term }\n\t\t\t\t\taction.config[chart.usecase.detail] = tw\n\t\t\t\t\tself.dom.tip.hide()\n\t\t\t\t\tself.app.dispatch(action)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tself.showTree_selectlst = async chart => {\n\t\tif (chart.usecase?.label) {\n\t\t\tself.dom.tip.d\n\t\t\t\t.append('div')\n\t\t\t\t.style('margin', '3px 5px')\n\t\t\t\t.style('padding', '3px 5px')\n\t\t\t\t.style('font-weight', 600)\n\t\t\t\t.html(chart.usecase.label)\n\t\t}\n\n\t\tconst action = {\n\t\t\ttype: 'plot_create',\n\t\t\tid: getId(),\n\t\t\tconfig: { chartType: chart.chartType } // NOTE if chartType is intermediary, action will be updated on term selection\n\t\t}\n\t\tconst termdb = await import('../termdb/app')\n\t\tself.dom.submenu = self.dom.tip.d.append('div')\n\t\ttermdb.appInit({\n\t\t\tholder: self.dom.submenu,\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\tstate: {\n\t\t\t\tactiveCohort: self.state.activeCohort,\n\t\t\t\tnav: {\n\t\t\t\t\theader_mode: 'search_only'\n\t\t\t\t},\n\t\t\t\ttree: { usecase: chart.usecase }\n\t\t\t},\n\t\t\ttree: {\n\t\t\t\tsubmit_lst: termlst => {\n\t\t\t\t\tconst data = chart.processSelection ? chart.processSelection(termlst) : termlst\n\t\t\t\t\taction.config[chart.usecase.detail] = data\n\t\t\t\t\tif (chart.updateActionBySelectedTerms) chart.updateActionBySelectedTerms(action, termlst)\n\t\t\t\t\tself.dom.tip.hide()\n\t\t\t\t\tself.app.dispatch(action)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tself.loadChartSpecificMenu = async chart => {\n\t\tself.dom.tip.clear()\n\t\tconst _ = await importPlot(chart.chartType)\n\t\t_.makeChartBtnMenu(self.dom.tip.d, self, chart.chartType)\n\t}\n\n\tself.prepPlot = function (chart) {\n\t\tself.dom.tip.hide()\n\t\tconst action = { type: 'plot_prep', config: chart.config, id: getId() }\n\t\tself.app.dispatch(action)\n\t}\n\n\tself.plotCreate = function (chart) {\n\t\tself.dom.tip.hide()\n\t\tconst action = { type: 'plot_create', config: chart.config, id: getId() }\n\t\tself.app.dispatch(action)\n\t}\n}\n\n// idPrefix to assign chart ID to distinguish between chart instances,\n// will not be used if there is a user-assigned or recovered session chart ID;\n// the random string is in case this code is bundled as independent code in\n// different chunks\nconst idPrefix = '_CHART_AUTOID_' + Math.random().toString().slice(-6) + '_'\nlet id = Date.now().toString().slice(-6)\n\nfunction getId() {\n\treturn idPrefix + id++\n}\n", "import { roundValue } from '#shared/roundValue.js'\nimport { DNA_METHYLATION, GENE_EXPRESSION, SINGLECELL_CELLTYPE } from '#shared/terms.js'\nimport type {\n\tValidatedVolcanoSettings,\n\tGEVolcanoSettings,\n\tDMVolcanoSettings,\n\tDefaultVolcanoSettings\n} from '../settings/Settings'\n\n// The max sample cutoff for volcano rendering\nexport const maxSampleCutoff = 4000\n// The max sample cutoff for gene expression term type\nexport const maxGESampleCutoff = 3000\n\n/*********** Set default settings per termType ***********/\nexport function getDefaultVolcanoSettings(overrides = {}, opts: any): ValidatedVolcanoSettings {\n\tconst defaults = {\n\t\tdefaultSignColor: 'red',\n\t\tdefaultNonSignColor: 'black',\n\t\tdefaultHighlightColor: '#ffa200', // orange-yellow\n\t\tfoldChangeCutoff: 0.3,\n\t\theight: 400,\n\t\tpValue: roundValue(-Math.log10(0.05), 2),\n\t\tpValueType: 'adjusted',\n\t\t//Only declare this value in one place\n\t\tsampleNumCutoff: opts.termType == GENE_EXPRESSION ? maxGESampleCutoff : maxSampleCutoff,\n\t\tshowPValueTable: false,\n\t\twidth: 400,\n\t\tmaxInteractiveDots: 5000\n\t} satisfies DefaultVolcanoSettings\n\n\taddGEDefaults(opts.termType, defaults)\n\taddDMDefaults(opts.termType, defaults)\n\taddSCCTDefaults(opts.termType)\n\n\treturn Object.assign(defaults, overrides)\n}\n\nfunction addGEDefaults(termType: string, defaults: Partial<GEVolcanoSettings>) {\n\tif (termType != GENE_EXPRESSION) return\n\n\tconst features = JSON.parse(sessionStorage.getItem('optionalFeatures') as string)\n\tconst method = features?.runDE_methods?.includes('Wilcoxon') ? 'wilcoxon' : 'edgeR'\n\n\tdefaults.cpmCutoff = 1\n\tdefaults.method = method\n\tdefaults.minCount = 10\n\tdefaults.minTotalCount = 15\n\tdefaults.rankBy = 'abs(foldChange)'\n}\n\nfunction addDMDefaults(termType: string, defaults: Partial<DMVolcanoSettings>) {\n\tif (termType != DNA_METHYLATION) return\n\tdefaults.minSamplesPerGroup = 3\n}\n\nfunction addSCCTDefaults(termType: string) {\n\tif (termType != SINGLECELL_CELLTYPE) return\n\t//add SCCT specific defaults when there are any\n}\n\n/*********** Setting Validation Functions ***********\n * Validates user input settings after merging with defaults */\nexport function validateVolcanoSettings(config: any, opts: any) {\n\tif (config.termType == SINGLECELL_CELLTYPE) return\n\tif (!config.settings.volcano) return\n\n\tconst settings = config.settings.volcano\n\tconst sampleNum = getSampleNum(opts)\n\tif (sampleNum > maxSampleCutoff) {\n\t\tthrow new Error(\n\t\t\t`Sample size ${sampleNum} exceeds max sample size of ${maxSampleCutoff}. Please reduce sample size.`\n\t\t)\n\t}\n\n\tvalidateGESettings(config.termType, settings, sampleNum, opts)\n\tvalidateDMSettings(config.termType, settings)\n\tvalidateSCCTSettings(config.termType)\n}\n\nexport function getSampleNum(config: any) {\n\tif (config.termType == GENE_EXPRESSION) {\n\t\treturn config.samplelst.groups.reduce((sum: number, g: any) => sum + g.values.length, 0)\n\t}\n\tif (config.termType == DNA_METHYLATION) {\n\t\treturn config.samplelst.groups.reduce((sum: number, g: any) => sum + g.values.length, 0)\n\t}\n\tif (config.termType == SINGLECELL_CELLTYPE) {\n\t\t//Only returning maxSampleCutoff for now.\n\t\treturn maxSampleCutoff\n\t}\n}\n\nfunction validateGESettings(termType: string, settings: GEVolcanoSettings, sampleNum: number, opts: any) {\n\tif (termType != GENE_EXPRESSION) return\n\n\tconst largeNum = sampleNum > settings.sampleNumCutoff\n\tif (!opts.overrides && largeNum) {\n\t\tsettings.method = 'wilcoxon'\n\t} else if (largeNum && settings.method != 'wilcoxon') {\n\t\tthrow new Error(\n\t\t\t`${settings.method} is not supported for ${sampleNum} samples when termtype = ${termType}. Please use Wilcoxon.`\n\t\t)\n\t}\n}\n\nfunction validateDMSettings(termType: string, settings?: DMVolcanoSettings) {\n\tif (termType != DNA_METHYLATION || !settings) return\n\tconst min = settings.minSamplesPerGroup\n\tif (!Number.isFinite(min) || !Number.isInteger(min) || min < 3) {\n\t\tsettings.minSamplesPerGroup = 3\n\t}\n}\n\nfunction validateSCCTSettings(termType: string) {\n\tif (termType != SINGLECELL_CELLTYPE) return\n\t//add validations when there are settings for SCCT\n}\n", "import { getCompInit } from '#rx'\nimport { Menu, GeneSetEditUI, renderTable, table2col, sayerror, make_radios } from '#dom'\nimport {\n\tfilterInit,\n\tgetNormalRoot,\n\tfilterPromptInit,\n\tgetFilterItemByTag,\n\tnegateFilter,\n\tfilterJoin\n} from '#filter/filter'\nimport { appInit } from '#termdb/app'\nimport { fillTermWrapper, get$id } from '#termsetting'\nimport { getCurrentCohortChartTypes } from './charts'\nimport { getColors } from '#shared/common.js'\nimport { rgb } from 'd3-color'\nimport { TermTypes, isNumericTerm, termType2label } from '#shared/terms.js'\nimport { dofetch3 } from '#common/dofetch'\nimport { maxSampleCutoff, maxGESampleCutoff } from '../plots/volcano/settings/defaults.ts'\nimport { getGEunit } from '#tw/geneExpression'\n\n/*\nthis\n\tapp\n\t\tvocabApi\n\t\topts\n\t\t\tgenome{}\n\t\t\tstate\n\t\t\t\tvocab{}\n\tstate {}\n\t\tgroups []\n\t\t\tgroup.name=str\n\t\t\tgroup.filter={}\n\t\ttermfilter{}\n\t\t\tfilter{}\n*/\n\nconst colorScale = getColors(5)\n\nclass MassGroups {\n\tstatic type = 'groups'\n\n\tconstructor(opts = {}) {\n\t\tthis.type = MassGroups.type\n\t\tthis.selectedGroupsIdx = new Set() // set of array index for this.state.groups[], for those selected in table ui\n\t}\n\n\tasync init() {\n\t\tthis.dom = {\n\t\t\tholder: this.opts.holder.append('div').style('margin', '10px')\n\t\t}\n\t\tinitUI(this)\n\t\tthis.tip = new Menu({ padding: '0px' }) // custom term click menu\n\t\t// submenu based on this.tip; FIXME do not use fixed x offset\n\t\tthis.tip2 = new Menu({ padding: '0px', offsetX: 250, offsetY: -34, parent_menu: this.tip.d.node() })\n\t\tthis.tip3 = new Menu({ padding: '0px' }) // gene search tooltip\n\t}\n\n\tgetState(appState) {\n\t\tconst state = {\n\t\t\ttermfilter: appState.termfilter,\n\t\t\tgroups: rebaseGroupFilter(appState),\n\t\t\tcustomTerms: appState.customTerms,\n\t\t\tcurrentCohortChartTypes: getCurrentCohortChartTypes(appState),\n\t\t\tmatrixplots: this.app.vocabApi.termdbConfig.matrixplots\n\t\t}\n\t\treturn state\n\t}\n\n\tasync main() {\n\t\tawait updateUI(this)\n\t}\n\n\t//////////////// rest are app-specific logic\n\n\tgetMassFilter() {\n\t\tif (!this.state.termfilter.filter || this.state.termfilter.filter.lst.length == 0) {\n\t\t\treturn { type: 'tvslst', in: true, join: '', lst: [] }\n\t\t}\n\t\tconst f = getNormalRoot(structuredClone(this.state.termfilter.filter)) // strip tag\n\t\treturn f\n\t}\n\n\tasync groups2samplelst(groups) {\n\t\tconst samplelstGroups = []\n\t\tconst processedSamples = new Set(),\n\t\t\toverlap = []\n\t\tfor (const g of groups) {\n\t\t\tconst samples = await this.app.vocabApi.getFilteredSampleList(\n\t\t\t\tfilterJoin([g.filter, this.state.termfilter.filter])\n\t\t\t)\n\n\t\t\tconst items = []\n\t\t\tfor (const sample of samples) {\n\t\t\t\tconst item = { sampleId: sample.id }\n\t\t\t\tif ('name' in sample) {\n\t\t\t\t\titem.sample = sample.name\n\t\t\t\t}\n\t\t\t\t//items.push(item)\n\t\t\t\tif (!processedSamples.has(sample.id)) items.push(item)\n\t\t\t\telse {\n\t\t\t\t\tfor (const pg of samplelstGroups) {\n\t\t\t\t\t\t//if (pg.name === g.name) continue\n\t\t\t\t\t\tconst i = pg.items.findIndex(i => i.sampleId === sample.id)\n\t\t\t\t\t\tif (i !== -1) overlap.push(...pg.items.splice(i, 1))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tprocessedSamples.add(item.sampleId)\n\t\t\t}\n\t\t\tif (items.length) samplelstGroups.push({ name: g.name, items, color: g.color })\n\t\t}\n\n\t\tif (overlap.length) {\n\t\t\tconst ok = confirm(\n\t\t\t\t'Overlap detected: 1 or more samples belong to >1 groups. A new group will be created for these \"overlap\" samples.'\n\t\t\t)\n\t\t\tif (!ok) return\n\t\t\tsamplelstGroups.push({ name: 'Group overlap', items: overlap })\n\t\t}\n\n\t\tif (groups.length == 1) {\n\t\t\t/* request rest of samples not in this single group, to form group2\n\t\t\t */\n\t\t\tconst samples = await this.app.vocabApi.getFilteredSampleList(\n\t\t\t\tfilterJoin([negateFilter(groups[0].filter), this.state.termfilter.filter])\n\t\t\t)\n\t\t\tif (!samples.length) throw '0 samples for the other group'\n\t\t\tconst items = []\n\t\t\tfor (const sample of samples) {\n\t\t\t\tconst item = { sampleId: sample.id }\n\t\t\t\tif ('name' in sample) {\n\t\t\t\t\titem.sample = sample.name\n\t\t\t\t}\n\t\t\t\titems.push(item)\n\t\t\t}\n\t\t\tsamplelstGroups.push({ name: 'Not in ' + groups[0].name, items, color: '#ccc' })\n\t\t}\n\n\t\treturn getSamplelstTW2(samplelstGroups)\n\t}\n\n\tupdateLaunchButton() {\n\t\t// turn both off by default; selectively turn on\n\t\tthis.dom.newTermSpan.style('display', 'none')\n\t\tthis.dom.noGroupSelected.style('display', 'none')\n\n\t\tif (this.state.groups.length == 0) return // no groups\n\n\t\tif (this.state.groups.length == 1) {\n\t\t\t// only one group present, launch button is always on to work on this group\n\t\t\tthis.dom.newTermSpan.style('display', '')\n\t\t\tthis.dom.launchButton.text(`Create variable using \"${this.state.groups[0].name}\"`)\n\t\t\tthis.dom.newTermNameInput.property('value', this.state.groups[0].name + ' vs others')\n\t\t\treturn\n\t\t}\n\n\t\t// 2 or more groups, button is based on the number of selected groups\n\t\tconst lst = [...this.selectedGroupsIdx]\n\t\tif (lst.length == 0) {\n\t\t\t// none selected\n\t\t\tthis.dom.noGroupSelected.style('display', '')\n\t\t\treturn\n\t\t}\n\t\t// at least 1 selected, display button\n\t\tthis.dom.newTermSpan.style('display', '')\n\t\tif (lst.length == 1) {\n\t\t\t// only 1 selected\n\t\t\tthis.dom.launchButton.text(`Create variable using \"${this.state.groups[lst[0]]?.name}\"`)\n\t\t\tthis.dom.newTermNameInput.property('value', this.state.groups[lst[0]].name + ' vs others')\n\t\t\treturn\n\t\t}\n\t\tthis.dom.launchButton.text(`Create variable using ${lst.length} groups`)\n\t\tthis.dom.newTermNameInput.property('value', lst.map(i => this.state.groups[i].name).join(' vs '))\n\t}\n\n\tdisplayCustomTerms() {\n\t\tthis.dom.customTermDiv.selectAll('*').remove()\n\t\tif (this.state.customTerms.length == 0) {\n\t\t\tthis.dom.customTermDiv\n\t\t\t\t.append('div')\n\t\t\t\t.text('No custom variables. Use above controls to create new ones. Custom variables are added to dictionary.')\n\t\t\t\t.style('font-size', '.8em')\n\t\t\treturn\n\t\t}\n\t\tthis.dom.customTermDiv\n\t\t\t.append('div')\n\t\t\t.style('margin-bottom', '10px')\n\t\t\t.style('font-size', '.8em')\n\t\t\t.text('Following custom variables are available in all charts where variables are used. Click one to delete.')\n\t\tfor (const { name, tw } of this.state.customTerms) {\n\t\t\tconst div = this.dom.customTermDiv.append('div')\n\t\t\tdiv\n\t\t\t\t.text(name)\n\t\t\t\t.attr('class', 'sja_filter_tag_btn')\n\t\t\t\t.attr('data-testid', `sjpp-custom-term-btn`)\n\t\t\t\t.style('padding', '3px 6px')\n\t\t\t\t.style('border-radius', '6px')\n\t\t\t\t.style('margin-right', '5px')\n\t\t\t\t.on('click', event => {\n\t\t\t\t\tconst deleteCallback = () => this.app.vocabApi.deleteCustomTerm(name)\n\t\t\t\t\tthis.showGroupsMenu(event, tw, deleteCallback)\n\t\t\t\t})\n\t\t}\n\t}\n\n\tnewId() {\n\t\tthis.lastId = get$id()\n\t\treturn this.lastId\n\t}\n\n\tshowGroupsMenu(event, tw, deleteCallback) {\n\t\tconst samplelstTW = structuredClone(tw)\n\t\tthis.tip.clear().showunder(event.target)\n\t\tconst menuDiv = this.tip.d.append('div')\n\t\tconst id = this?.lastId\n\n\t\tconst groupsInfo = menuDiv.append('div').attr('data-testid', 'sjpp-groups-menu')\n\n\t\tconst table = table2col({ holder: groupsInfo })\n\t\ttable.table.style('scale', 0.9).style('margin-left', '0px')\n\t\tfor (const [grpKey, grp] of Object.entries(tw.term.values)) {\n\t\t\tconst colorSquare = grp.color\n\t\t\t\t? `<span style=\"display:inline-block; width:12px; height:12px; background-color:${grp.color}\" ></span>`\n\t\t\t\t: `<span style=\"display:inline-block; width:11px; height:11px; background-color:${'#fff'}; border: 0.1px solid black\" ></span>`\n\t\t\tconst [c1, c2] = table.addRow()\n\t\t\tc1.html(`${colorSquare} ${grp.label}`)\n\t\t\tc2.html(`${grp.othersGroupSampleNum || grp.list.length} samples`)\n\t\t}\n\n\t\tif (this.state.currentCohortChartTypes.includes('DA') && samplelstTW.q.groups.length == 2)\n\t\t\taddDiffAnalysisPlotMenuItem(menuDiv, this, samplelstTW)\n\t\taddSummarizeOptions(menuDiv, this, samplelstTW, id)\n\t\tmayAddHierClusterPlotMenuItem('geneExpression', menuDiv, 'Gene expression', this.tip2, samplelstTW, id, this, true)\n\t\tmayAddMatrixMenuItems(menuDiv, 'Matrix', this.tip2, samplelstTW, id, this, this.state, true, () => this.newId)\n\t\tmayAddSamplescatterOption(menuDiv, this, samplelstTW)\n\t\tmayAddGenomebrowserOption(menuDiv, this, samplelstTW)\n\n\t\t//show option to delete custom variable\n\t\tmenuDiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-delete-variable')\n\t\t\t.text('Delete variable')\n\t\t\t.on('click', event => {\n\t\t\t\tdeleteCallback()\n\t\t\t\tthis.tip.hide()\n\t\t\t})\n\t}\n}\n\nexport const groupsInit = getCompInit(MassGroups)\n\nfunction addSummarizeOptions(menuDiv, self, samplelstTW, id) {\n\tconst d = menuDiv\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.attr('data-testid', 'sjpp-summarize-option')\n\t\t.text('Summarize')\n\td.on('click', async () => {\n\t\tshowTree(\n\t\t\td,\n\t\t\tterm => {\n\t\t\t\tconst tw = { term }\n\t\t\t\tif (isNumericTerm(term)) tw.q = { mode: 'continuous' }\n\t\t\t\topenSummaryPlot(tw, samplelstTW, self.app, id, () => self.newId)\n\t\t\t},\n\t\t\tself.app,\n\t\t\tself.tip2\n\t\t)\n\t})\n\td.insert('div').html('\u203A').style('float', 'right')\n\n\tif (self.state.currentCohortChartTypes.includes('survival'))\n\t\taddPlotMenuItem('survival', menuDiv, 'Compare survival', self.tip2, samplelstTW, id, self, true)\n\tif (self.state.currentCohortChartTypes.includes('cuminc'))\n\t\taddPlotMenuItem('cuminc', menuDiv, 'Compare cumulative incidence', self.tip2, samplelstTW, id, self, true)\n}\n\nfunction mayAddGenomebrowserOption(menuDiv, self, samplelstTW) {\n\tif (!self.state.currentCohortChartTypes.includes('genomeBrowser')) return\n\tif (!self.app.vocabApi.termdbConfig.queries?.snvindel) return // for now only allow for snvindel\n\tif (self.app.vocabApi.termdbConfig.queries.snvindel.details) return // allows to disable this option for sjlife\n\tif (samplelstTW.q.groups.length != 2) return // hardcoded to only support 2 groups\n\tmenuDiv\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.attr('data-testid', 'sjpp-genome-browser-option')\n\t\t.text('Compare mutations')\n\t\t.on('click', () => {\n\t\t\tself.tip.hide()\n\t\t\tself.tip2.hide()\n\t\t\tself.tip3.hide()\n\t\t\tconst [f1, f2] = makeFiltersFromTwoSampleGroups(samplelstTW)\n\t\t\tconst config = {\n\t\t\t\tchartType: 'genomeBrowser',\n\t\t\t\tsnvindel: { shown: true, filter: f1 }, // code filter in 1st tk\n\t\t\t\tsubMds3Tks: [{ filterObj: f2 }] // code filter in 2nd tk\n\t\t\t}\n\t\t\tself.app.dispatch({\n\t\t\t\ttype: 'plot_create',\n\t\t\t\tconfig\n\t\t\t})\n\t\t})\n}\n\nfunction makeFiltersFromTwoSampleGroups(tw) {\n\tconst [g1, g2] = tw.q.groups\n\tif (!g1 || !g2) throw 'not 2 groups in tw.q.groups[]'\n\treturn [\n\t\t{\n\t\t\tin: g1.in,\n\t\t\tjoin: '',\n\t\t\ttype: 'tvslst',\n\t\t\tlst: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: {\n\t\t\t\t\t\t\tname: g1.name,\n\t\t\t\t\t\t\ttype: 'samplelst',\n\t\t\t\t\t\t\tvalues: {\n\t\t\t\t\t\t\t\t[g1.name]: {\n\t\t\t\t\t\t\t\t\tkey: g1.name,\n\t\t\t\t\t\t\t\t\tlabel: g1.name,\n\t\t\t\t\t\t\t\t\tlist: g1.values\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\tin: g2.in,\n\t\t\tjoin: '',\n\t\t\ttype: 'tvslst',\n\t\t\tlst: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'tvs',\n\t\t\t\t\ttvs: {\n\t\t\t\t\t\tterm: {\n\t\t\t\t\t\t\tname: g2.name,\n\t\t\t\t\t\t\ttype: 'samplelst',\n\t\t\t\t\t\t\tvalues: {\n\t\t\t\t\t\t\t\t[g2.name]: {\n\t\t\t\t\t\t\t\t\tkey: g2.name,\n\t\t\t\t\t\t\t\t\tlabel: g2.name,\n\t\t\t\t\t\t\t\t\tlist: g2.values\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}\n\nfunction mayAddSamplescatterOption(menuDiv, self, samplelstTW) {\n\t// this is only for pre-made scatterplots\n\tif (!self.app.vocabApi.termdbConfig.scatterplots) return\n\tfor (const plot of self.app.vocabApi.termdbConfig.scatterplots) {\n\t\tif (plot.colorTW)\n\t\t\t//the plot supports overlay by a color term\n\t\t\tmenuDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t\t.attr('data-testid', `sjpp-samplescatter-option-${plot.name.toLowerCase()}`)\n\t\t\t\t.text(`Overlay on ${plot.name}`)\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tself.tip2.hide() // in case tip2 is already opened through another option\n\t\t\t\t\tlet config = {\n\t\t\t\t\t\tchartType: 'sampleScatter',\n\t\t\t\t\t\tname: plot.name\n\t\t\t\t\t}\n\t\t\t\t\tif (plot.sampleCategory)\n\t\t\t\t\t\t//if the plot filters by a sample category, like D1, R1\n\t\t\t\t\t\tconfig.sampleCategory = {\n\t\t\t\t\t\t\ttw: structuredClone(plot.sampleCategory.tw),\n\t\t\t\t\t\t\torder: plot.sampleCategory.order,\n\t\t\t\t\t\t\tdefaultValue: plot.sampleCategory.defaultValue\n\t\t\t\t\t\t}\n\t\t\t\t\tif (plot.sampleType) config.sampleType = plot.sampleType //if the plot specifies the sample type to customize the legend\n\t\t\t\t\tconfig.colorTW = structuredClone(samplelstTW)\n\n\t\t\t\t\tif (plot.settings) config.settings = structuredClone(plot.settings) //if the plot specifies settings\n\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\tconfig: config\n\t\t\t\t\t})\n\t\t\t\t\tself.tip.hide()\n\t\t\t\t})\n\t}\n}\n\nfunction addDiffAnalysisPlotMenuItem(div, self, samplelstTW) {\n\t// DA app can be applied to multiple datatypes. show options based on availability for each datatype\n\tif (self.app.vocabApi.termdbConfig.queries?.rnaseqGeneCount) {\n\t\t// hardcoded! rnaseq genecount will correspond to gene exp term type on DA ui\n\t\tconst itemDiv = div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-da-option')\n\t\t\t.text(`Differential ${termType2label(TermTypes.GENE_EXPRESSION)} Analysis`)\n\t\t\t.on('click', async e => {\n\t\t\t\t// self.tip2.hide() // in case tip2 is already opened through another option\n\t\t\t\t//Move this to diff analysis plot??\n\t\t\t\t//Do the check but not add to the state??\n\t\t\t\tconst groups = []\n\t\t\t\tfor (const group of samplelstTW.q.groups) {\n\t\t\t\t\tif (group.values && group.values.length > 0) {\n\t\t\t\t\t\tgroups.push(group)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow 'group does not contain samples for differential analysis'\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// get actual numbers of samples with rnaseq count\n\t\t\t\tconst body = {\n\t\t\t\t\tgenome: self.app.vocabApi.vocab.genome,\n\t\t\t\t\tdslabel: self.app.vocabApi.vocab.dslabel,\n\t\t\t\t\tsamplelst: { groups },\n\t\t\t\t\tfilter: self.state.termfilter.filter,\n\t\t\t\t\tfilter0: self.state.termfilter.filter0,\n\t\t\t\t\tpreAnalysis: true\n\t\t\t\t}\n\t\t\t\tconst preAnalysisData = await dofetch3('termdb/DE', { body })\n\n\t\t\t\tconst tip = self.tip2\n\t\t\t\tif (!preAnalysisData?.data) {\n\t\t\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\t\t\t\t\tsayerror(tip.d.append('div'), 'Error retrieving pre-analysis data')\n\t\t\t\t\tthrow new Error('no data returned from pre-analysis request')\n\t\t\t\t}\n\n\t\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\n\t\t\t\trenderPreAnalysisData({ preAnalysisData, samplelstTW, groups, tip, self })\n\t\t\t})\n\t}\n\n\tif (self.app.vocabApi.termdbConfig.queries?.dnaMethylation?.promoter) {\n\t\tconst itemDiv = div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.attr('data-testid', 'sjpp-da-dnaMeth-option')\n\t\t\t.text(`Differential ${termType2label(TermTypes.DNA_METHYLATION)} Analysis`)\n\t\t\t.on('click', async () => {\n\t\t\t\tconst groups = []\n\t\t\t\tfor (const group of samplelstTW.q.groups) {\n\t\t\t\t\tif (group.values && group.values.length > 0) {\n\t\t\t\t\t\tgroups.push(group)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow 'group does not contain samples for differential analysis'\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// get actual numbers of samples with methylation data\n\t\t\t\tconst body = {\n\t\t\t\t\tgenome: self.app.vocabApi.vocab.genome,\n\t\t\t\t\tdslabel: self.app.vocabApi.vocab.dslabel,\n\t\t\t\t\tsamplelst: { groups },\n\t\t\t\t\tfilter: self.state.termfilter.filter,\n\t\t\t\t\tfilter0: self.state.termfilter.filter0,\n\t\t\t\t\tpreAnalysis: true\n\t\t\t\t}\n\t\t\t\tconst preAnalysisData = await dofetch3('termdb/diffMeth', { body })\n\n\t\t\t\tconst tip = self.tip2\n\t\t\t\tif (!preAnalysisData?.data) {\n\t\t\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\t\t\t\t\tsayerror(tip.d.append('div'), 'Error retrieving pre-analysis data')\n\t\t\t\t\tthrow new Error('no data returned from pre-analysis request')\n\t\t\t\t}\n\n\t\t\t\tconst numControl = preAnalysisData.data[samplelstTW.q.groups[0].name]\n\t\t\t\tconst numCase = preAnalysisData.data[samplelstTW.q.groups[1].name]\n\n\t\t\t\tif (numControl + numCase > maxSampleCutoff) {\n\t\t\t\t\tif (preAnalysisData.data.alert)\n\t\t\t\t\t\tpreAnalysisData.data.alert += ` | Sample size ${\n\t\t\t\t\t\t\tnumControl + numCase\n\t\t\t\t\t\t} exceeds max sample size of ${maxSampleCutoff}. Please reduce sample size.`\n\t\t\t\t\telse\n\t\t\t\t\t\tpreAnalysisData.data.alert = `Sample size ${\n\t\t\t\t\t\t\tnumControl + numCase\n\t\t\t\t\t\t} exceeds max sample size of ${maxSampleCutoff}. Please reduce sample size.`\n\t\t\t\t}\n\n\t\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\t\t\t\tconst menuDiv = tip.d.append('div')\n\t\t\t\tconst table = table2col({ holder: menuDiv })\n\t\t\t\ttable.table.style('margin-left', '5px').style('padding', '5px 10px')\n\t\t\t\t{\n\t\t\t\t\tconst controlGColor = samplelstTW.term.values[samplelstTW.q.groups[0].name].color\n\t\t\t\t\tconst colorSquareCtrl = controlGColor\n\t\t\t\t\t\t? `<span style=\"display:inline-block; width:12px; height:12px; background-color:${controlGColor}\" ></span>`\n\t\t\t\t\t\t: `<span style=\"display:inline-block; width:11px; height:11px; background-color:${'#fff'}; border: 0.1px solid black\" ></span>`\n\t\t\t\t\tconst [c1, c2] = table.addRow()\n\t\t\t\t\tc1.html(\n\t\t\t\t\t\t`<span style=\"font-size:.8em;font-weight:bold\">CONTROL</span> ${colorSquareCtrl} ${samplelstTW.q.groups[0].name}`\n\t\t\t\t\t)\n\t\t\t\t\tc2.html(`${numControl} samples`)\n\t\t\t\t}\n\t\t\t\t{\n\t\t\t\t\tconst caseGColor = samplelstTW.term.values[samplelstTW.q.groups[1].name].color\n\t\t\t\t\tconst colorSquareCase = caseGColor\n\t\t\t\t\t\t? `<span style=\"display:inline-block; width:12px; height:12px; background-color:${caseGColor}\" ></span>`\n\t\t\t\t\t\t: `<span style=\"display:inline-block; width:11px; height:11px; background-color:${'#fff'}; border: 0.1px solid black\" ></span>`\n\t\t\t\t\tconst [c1, c2] = table.addRow()\n\t\t\t\t\tc1.html(\n\t\t\t\t\t\t`<span style=\"font-size:.8em;font-weight:bold\">CASE</span> ${colorSquareCase} ${samplelstTW.q.groups[1].name}`\n\t\t\t\t\t)\n\t\t\t\t\tc2.html(`${numCase} samples`)\n\t\t\t\t}\n\n\t\t\t\tconst alertDiv = menuDiv.append('div')\n\t\t\t\tif (preAnalysisData.data.alert) {\n\t\t\t\t\tsayerror(alertDiv, preAnalysisData.data.alert)\n\t\t\t\t}\n\n\t\t\t\tif (!preAnalysisData.data.alert) {\n\t\t\t\t\tconst launchDiv = menuDiv.append('div').style('margin', '8px 5px').style('padding', '5px 10px')\n\t\t\t\t\tlaunchDiv\n\t\t\t\t\t\t.append('button')\n\t\t\t\t\t\t.style('border', 'none')\n\t\t\t\t\t\t.style('border-radius', '20px')\n\t\t\t\t\t\t.style('padding', '10px 15px')\n\t\t\t\t\t\t.text(`Run Differential ${termType2label(TermTypes.DNA_METHYLATION)} Analysis`)\n\t\t\t\t\t\t.on('click', async () => {\n\t\t\t\t\t\t\tconst config = {\n\t\t\t\t\t\t\t\tchartType: 'differentialAnalysis',\n\t\t\t\t\t\t\t\tstate: self.state,\n\t\t\t\t\t\t\t\tsamplelst: { groups },\n\t\t\t\t\t\t\t\ttermType: TermTypes.DNA_METHYLATION,\n\t\t\t\t\t\t\t\ttw: samplelstTW\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\t\tself.tip.hide()\n\t\t\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\t\tconfig\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\tif (self.app.vocabApi.termdbConfig.allowedTermTypes?.includes(TermTypes.METABOLITE_INTENSITY)) {\n\t\tdiv.append('div').text('DA should support metabolite')\n\t}\n\n\tif (self.app.vocabApi.termdbConfig.allowedTermTypes?.includes(TermTypes.PROTEOME_ABUNDANCE)) {\n\t\tdiv.append('div').text('DA should support whole proteome abundance')\n\t}\n\t// small text to explain which is case/control. always show this for all DA\n\tdiv\n\t\t.append('div')\n\t\t.html(\n\t\t\t`<span style=\"font-size:.8em;font-weight:bold\">CASE</span> ${samplelstTW.q.groups[1].name}\n\t\t \n\t\t<span style=\"font-size:.8em;font-weight:bold\">CONTROL</span> ${samplelstTW.q.groups[0].name}`\n\t\t)\n\t\t.style('font-size', '0.8em')\n\t\t.style('opacity', 0.8)\n\t\t.style('padding', '3px 3px 3px 10px')\n}\n\nexport function renderPreAnalysisData(arg) {\n\tconst { preAnalysisData, samplelstTW, groups, holder, tip, self } = arg\n\n\tif (!preAnalysisData?.data) return\n\n\tconst numControl = preAnalysisData.data[samplelstTW.q.groups[0].name]\n\tconst numCase = preAnalysisData.data[samplelstTW.q.groups[1].name]\n\n\tif (numControl + numCase > maxSampleCutoff) {\n\t\tif (preAnalysisData.data.alert)\n\t\t\tpreAnalysisData.data.alert += ` | Sample size ${\n\t\t\t\tnumControl + numCase\n\t\t\t} exceeds max sample size of ${maxSampleCutoff}. Please reduce sample size.`\n\t\telse\n\t\t\tpreAnalysisData.data.alert = `Sample size ${\n\t\t\t\tnumControl + numCase\n\t\t\t} exceeds max sample size of ${maxSampleCutoff}. Please reduce sample size.`\n\t}\n\n\t// display actual numbers of samples with rnaseq count\n\tconst menuDiv = tip ? tip.d.append('div') : holder.append('div')\n\tconst table = table2col({ holder: menuDiv })\n\ttable.table.style('margin-left', '5px').style('padding', '5px 10px')\n\t{\n\t\tconst controlGColor = samplelstTW.term.values[samplelstTW.q.groups[0].name].color\n\t\tconst colorSquareCtrl = controlGColor\n\t\t\t? `<span style=\"display:inline-block; width:12px; height:12px; background-color:${controlGColor}\" ></span>`\n\t\t\t: `<span style=\"display:inline-block; width:11px; height:11px; background-color:${'#fff'}; border: 0.1px solid black\" ></span>`\n\t\tconst [c1, c2] = table.addRow()\n\t\tc1.html(\n\t\t\t`<span style=\"font-size:.8em;font-weight:bold\">CONTROL</span> ${colorSquareCtrl} ${samplelstTW.q.groups[0].name}`\n\t\t)\n\t\tc2.html(`${numControl} samples`)\n\t}\n\t{\n\t\tconst caseGColor = samplelstTW.term.values[samplelstTW.q.groups[1].name].color\n\t\tconst colorSquareCase = caseGColor\n\t\t\t? `<span style=\"display:inline-block; width:12px; height:12px; background-color:${caseGColor}\" ></span>`\n\t\t\t: `<span style=\"display:inline-block; width:11px; height:11px; background-color:${'#fff'}; border: 0.1px solid black\" ></span>`\n\t\tconst [c1, c2] = table.addRow()\n\t\tc1.html(\n\t\t\t`<span style=\"font-size:.8em;font-weight:bold\">CASE</span> ${colorSquareCase} ${samplelstTW.q.groups[1].name}`\n\t\t)\n\t\tc2.html(`${numCase} samples`)\n\t}\n\n\t// display errors\n\tconst alertDiv = menuDiv.append('div')\n\tif (preAnalysisData.data.alert) {\n\t\tsayerror(alertDiv, preAnalysisData.data.alert)\n\t}\n\n\t// option to launch DE\n\tconst sample_size_limit = 8\n\tif (!preAnalysisData.data.alert) {\n\t\tconst options =\n\t\t\tnumControl + numCase >= maxGESampleCutoff\n\t\t\t\t? [{ label: 'Wilcoxon', value: 'wilcoxon' }]\n\t\t\t\t: numControl <= sample_size_limit && numCase <= sample_size_limit\n\t\t\t\t? [\n\t\t\t\t\t\t{ label: 'edgeR', value: 'edgeR' },\n\t\t\t\t\t\t{ label: 'Limma', value: 'limma' }\n\t\t\t\t ]\n\t\t\t\t: [\n\t\t\t\t\t\t{ label: 'edgeR', value: 'edgeR' },\n\t\t\t\t\t\t{ label: 'Wilcoxon', value: 'wilcoxon' },\n\t\t\t\t\t\t{ label: 'Limma', value: 'limma' }\n\t\t\t\t ]\n\n\t\tconst launchDEDiv = menuDiv.append('div').style('margin', '8px 5px').style('padding', '5px 10px')\n\t\tconst radioRow = launchDEDiv.append('tr')\n\t\tlet selectedMethod = options[0].value\n\n\t\tradioRow\n\t\t\t.append('td')\n\t\t\t.html('Method')\n\t\t\t.attr('aria-label', 'DE Method')\n\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t.style('padding', '5px')\n\n\t\tconst cell = radioRow.append('td')\n\t\tconst radioBtnDiv = cell.append('div')\n\n\t\tmake_radios({\n\t\t\tholder: radioBtnDiv,\n\t\t\tinputName: `de-method-${Date.now()}`,\n\t\t\toptions: options.map((o, i) => ({\n\t\t\t\t...o,\n\t\t\t\ttitle: `${o.label} method`,\n\t\t\t\tchecked: i === 0 // preselect first option\n\t\t\t})),\n\t\t\tstyles: {\n\t\t\t\tdisplay: 'inline-block',\n\t\t\t\tpadding: '0 12px 0 0'\n\t\t\t},\n\t\t\tcallback: v => (selectedMethod = v)\n\t\t})\n\n\t\tlaunchDEDiv\n\t\t\t.append('button')\n\t\t\t.style('border', 'none')\n\t\t\t.style('border-radius', '20px')\n\t\t\t.style('padding', '10px 15px')\n\t\t\t.text(`Run Differential ${termType2label(TermTypes.GENE_EXPRESSION)} Analysis`)\n\t\t\t.on('click', async () => {\n\t\t\t\tconst config = {\n\t\t\t\t\tchartType: 'differentialAnalysis',\n\t\t\t\t\tstate: self.state,\n\t\t\t\t\tsamplelst: { groups },\n\t\t\t\t\ttermType: TermTypes.GENE_EXPRESSION,\n\t\t\t\t\ttw: samplelstTW,\n\t\t\t\t\tsettings: { volcano: { method: selectedMethod } }\n\t\t\t\t}\n\t\t\t\tif (tip) tip.hide()\n\t\t\t\tif (self.tip) self.tip.hide()\n\t\t\t\tself.app.dispatch({\n\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\tconfig\n\t\t\t\t})\n\t\t\t})\n\t}\n}\n\nfunction initUI(self) {\n\tself.dom.filterTableDiv = self.dom.holder.append('div').style('margin-bottom', '10px')\n\n\t// row of buttons\n\tconst btnRow = self.dom.holder.append('div')\n\n\t// btn 1: prompt to add new group\n\tself.dom.addNewGroupBtnHolder = btnRow.append('span').style('margin-right', '20px')\n\n\t// btn 2: patch of controls to create new term\n\tself.dom.newTermSpan = btnRow.append('span') // contains \"create button\" and <input>, so they can toggle on/off together\n\tself.dom.newTermSpan.append('span').style('padding-left', '15px').text('Add variable:')\n\tself.dom.newTermNameInput = self.dom.newTermSpan.append('input').attr('type', 'text')\n\n\tself.dom.launchButton = self.dom.newTermSpan\n\t\t.append('span')\n\t\t.attr('class', 'sja_menuoption')\n\t\t.attr('data-testid', 'sjpp-create-new-variable-btn')\n\t\t.on('click', () => clickLaunchBtn(self))\n\n\t// msg: none selected\n\tself.dom.noGroupSelected = btnRow.append('span').text('No groups selected').style('opacity', 0.5)\n\n\t// bottom box to list custom terms\n\tself.dom.customTermDiv = self.dom.holder\n\t\t.append('div')\n\t\t.style('margin', '20px')\n\t\t.style('border-left', 'solid 1px black')\n\t\t.style('padding', '10px')\n}\n\nasync function updateUI(self) {\n\t// prompt button is an instance to a blank filter, can only make the button after state is filled\n\t// but not in instance.init()\n\n\t// create \"Add new group\" button as needed\n\tif (!self.filterPrompt) {\n\t\tself.filterPrompt = await filterPromptInit({\n\t\t\tholder: self.dom.addNewGroupBtnHolder,\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\temptyLabel: 'Add group',\n\t\t\ttermdbConfig: self.app.vocabApi.termdbConfig,\n\t\t\tcallback: f => {\n\t\t\t\taddNewGroup(self.app, f, self.state.groups)\n\t\t\t},\n\t\t\tdebug: self.opts.debug\n\t\t})\n\t}\n\n\t// filterPrompt.main() always empties the filterUiRoot data\n\tself.filterPrompt.main(self.getMassFilter()) // provide mass filter to limit the term tree\n\n\t// duplicate groups[] array to mutate and add to action.state for dispatching\n\tconst groups = structuredClone(self.state.groups)\n\n\tif (!groups.length) {\n\t\t// no groups, do not show launch button, hide table\n\t\tself.updateLaunchButton()\n\t\tself.dom.filterTableDiv.style('display', 'none')\n\t\tself.displayCustomTerms()\n\t\treturn\n\t}\n\n\t// clear table and populate rows\n\tself.dom.filterTableDiv.style('display', '').selectAll('*').remove()\n\n\tconst tableArg = {\n\t\tdiv: self.dom.filterTableDiv,\n\t\tcolumns: [\n\t\t\t{}, // blank column to add delete buttons\n\t\t\t{\n\t\t\t\tlabel: 'NAME',\n\t\t\t\teditCallback: async (i, cell) => {\n\t\t\t\t\tconst newName = cell.value\n\t\t\t\t\tconst index = self.state.groups.findIndex(group => group.name == newName)\n\t\t\t\t\tif (index != -1) {\n\t\t\t\t\t\talert(`Group named ${newName} already exists`)\n\t\t\t\t\t\tupdateUI(self)\n\t\t\t\t\t} else\n\t\t\t\t\t\tawait self.app.dispatch({\n\t\t\t\t\t\t\ttype: 'rename_group',\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tnewName: cell.value\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: 'COLOR',\n\t\t\t\teditCallback: async (i, cell) => {\n\t\t\t\t\tawait self.app.dispatch({\n\t\t\t\t\t\ttype: 'change_color_group',\n\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\tnewColor: cell.color\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ label: '#SAMPLE' },\n\t\t\t{ label: 'FILTER' }\n\t\t],\n\t\trows: [],\n\t\tstriped: false, // no alternating row bg color so delete button appears more visible\n\t\tshowLines: false\n\t}\n\tfor (const [i, g] of groups.entries()) {\n\t\ttableArg.rows.push([\n\t\t\t{}, // blank cell to add delete button\n\t\t\t{ value: g.name, dataTestId: `sjpp-groups-name-${i}` }, // to allow click to show <input>\n\t\t\t{ color: g.color },\n\t\t\t{ value: 'Loading...' }, // sample count is lazily retrieved to not to hold up table rendering\n\t\t\t{} // blank cell to show filter ui\n\t\t])\n\t}\n\n\t// clear existing selected groups\n\tself.selectedGroupsIdx.clear()\n\n\tif (groups.length == 1) {\n\t\t// only one group, add index 0\n\t\tself.selectedGroupsIdx.add(0)\n\t} else {\n\t\t// more than 1 group, show checkboxes for each row\n\t\ttableArg.noButtonCallback = (i, node) => {\n\t\t\tif (node.checked) self.selectedGroupsIdx.add(i)\n\t\t\telse self.selectedGroupsIdx.delete(i)\n\t\t\tself.updateLaunchButton() // update button text, based on how many groups are selected\n\t\t}\n\t\t//\n\t\ttableArg.selectedRows = []\n\t\tfor (let i = 0; i < groups.length; i++) {\n\t\t\ttableArg.selectedRows.push(i) // check all rows by default\n\t\t\tself.selectedGroupsIdx.add(i)\n\t\t}\n\t}\n\n\trenderTable(tableArg)\n\n\t// after rendering table, iterate over rows again to fill cells with control elements\n\tfor (const [i, row] of tableArg.rows.entries()) {\n\t\t// add delete button in 1st cell\n\t\trow[0].__td\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t.attr('data-testid', 'sjpp-delete-group')\n\t\t\t.style('padding', '1px 6px')\n\t\t\t.html('×')\n\t\t\t.on('click', () => {\n\t\t\t\tconst group = groups[i]\n\t\t\t\tself.app.vocabApi.deleteGroup(group.name)\n\t\t\t})\n\n\t\t// create filter ui in its cell\n\t\tconst group = groups[i]\n\t\tfilterInit({\n\t\t\tholder: row[4].__td,\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\ttermdbConfig: self.app.vocabApi.termdbConfig,\n\t\t\tcallback: f => {\n\t\t\t\tif (!f || f.lst.length == 0) {\n\t\t\t\t\t// blank filter (user removed last tvs from this filter), delete this element from groups[]\n\t\t\t\t\tconst i = groups.findIndex(g => g.name == group.name)\n\t\t\t\t\tgroups.splice(i, 1)\n\t\t\t\t} else {\n\t\t\t\t\t// update filter\n\t\t\t\t\tgroup.filter = f\n\t\t\t\t}\n\t\t\t\tself.app.dispatch({\n\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\tstate: { groups }\n\t\t\t\t})\n\t\t\t}\n\t\t}).main(group.filter)\n\n\t\tself.app.vocabApi.getFilteredSampleCount(groups[i].filter).then(n => row[3].__td.text(n))\n\t}\n\n\tself.updateLaunchButton()\n\n\tself.displayCustomTerms()\n}\n\nasync function clickLaunchBtn(self) {\n\t// click button to create samplelst tw\n\t// collect groups in use\n\tconst groups = []\n\tfor (const i of self.selectedGroupsIdx) {\n\t\tconst g = self.state.groups[i]\n\t\tif (g) groups.push(g)\n\t}\n\n\tif (groups.length == 0) throw 'No groups, should not happen'\n\n\tconst name = self.dom.newTermNameInput.property('value')\n\n\t// 1 or more groups are in use, generate samplelst tw and save it to state\n\tconst tw = await self.groups2samplelst(groups)\n\tif (!tw) return\n\ttw.term.name = name\n\tself.app.vocabApi.addCustomTerm({ name, tw })\n\n\tself.dom.newTermSpan.style('display', 'none')\n}\n\n/*\ns = {groups[ {filter} ], termfilter{filter} }\ntermfilter is mass global filter\nif provided, need to \"rebase\" group's visible filter to it\na group filter contains the shadowy global filter from previous state. when new state is provided, need to replace it\n*/\nexport function rebaseGroupFilter(s) {\n\tif (!s.termfilter?.filter || s.termfilter.filter.lst.length == 0) {\n\t\t// blank filter\n\t\treturn s.groups\n\t}\n\tconst groups = [] // new groups\n\tfor (const g of s.groups) {\n\t\tconst f = getNormalRoot(structuredClone(s.termfilter.filter))\n\t\tconst f2 = getFilterItemByTag(g.filter, 'filterUiRoot')\n\t\tif (!f2) {\n\t\t\tgroups.push(g)\n\t\t\tcontinue\n\t\t}\n\t\tf.lst.push(f2)\n\t\tf.join = f.lst.length > 1 ? 'and' : ''\n\t\tconst g2 = {\n\t\t\tname: g.name,\n\t\t\tfilter: f,\n\t\t\tcolor: g.color\n\t\t}\n\t\tgroups.push(g2)\n\t}\n\treturn groups\n}\n\nexport async function openPlot(chartType, term, term2, app, id, newId) {\n\tlet config = {\n\t\tchartType,\n\t\tterm,\n\t\tterm2\n\t}\n\tif (id) config.insertBefore = id\n\tif (newId) config.id = newId()\n\tawait app.dispatch({\n\t\ttype: 'plot_create',\n\t\tconfig\n\t})\n}\n\nexport async function openSummaryPlot(tw, samplelstTW, app, id, newId) {\n\tconst config = {\n\t\tchartType: 'summary',\n\t\tchildType: tw.q?.mode == 'continuous' ? 'violin' : 'barchart',\n\t\tterm: tw,\n\t\tterm2: samplelstTW\n\t}\n\tif (id) config.insertBefore = id\n\tif (newId) config.id = newId()\n\tawait app.dispatch({\n\t\ttype: 'plot_create',\n\t\tconfig\n\t})\n}\n\nasync function showTree(\n\tdiv,\n\tcallback,\n\tapp,\n\ttip,\n\ttreeState = { tree: { usecase: { target: 'default', detail: 'term' } } }\n) {\n\tconst activeCohort = app.getState().activeCohort\n\tconst state = { activeCohort, ...treeState }\n\ttip.clear().showunderoffset(div.node())\n\tappInit({\n\t\tholder: tip.d,\n\t\tvocabApi: app.vocabApi,\n\t\tstate,\n\t\ttree: {\n\t\t\tclick_term: term => {\n\t\t\t\tcallback(term)\n\t\t\t\ttip.hide()\n\t\t\t\tif (tip.dnode.parent_menu) tip.dnode.parent_menu.style.display = 'none'\n\t\t\t}\n\t\t}\n\t})\n}\nfunction addPlotMenuItem(chartType, div, text, tip, samplelstTW, id, parent, openOnTop = false) {\n\tconst d = div\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.attr('data-testid', `sjpp-${chartType}-option`)\n\t\t.text(text)\n\t\t.on('click', e => {\n\t\t\tconst state = { tree: { usecase: { target: chartType, detail: 'term' } } }\n\t\t\tif (chartType == 'survival') state.nav = { header_mode: 'hide_search' }\n\t\t\tshowTree(\n\t\t\t\td,\n\t\t\t\tterm => {\n\t\t\t\t\topenPlot(chartType, term, samplelstTW, parent.app, id, openOnTop ? () => parent.newId : null)\n\t\t\t\t},\n\t\t\t\tparent.app,\n\t\t\t\ttip,\n\t\t\t\tstate\n\t\t\t)\n\t\t})\n\td.insert('div').html('\u203A').style('float', 'right')\n}\n\nfunction mayAddHierClusterPlotMenuItem(chartType, div, text, tip, samplelstTW, id, parent, openOnTop = false) {\n\tif (!parent.state.currentCohortChartTypes.includes('geneExpression')) return\n\tconst itemDiv = div\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.attr('data-testid', `sjpp-hiercluster-option`)\n\t\t.text(text)\n\t\t.on('click', () => {\n\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\n\t\t\tnew GeneSetEditUI({\n\t\t\t\tholder: tip.d,\n\t\t\t\tgenome: parent.app.opts.genome,\n\t\t\t\tgeneList: [],\n\t\t\t\tvocabApi: parent.app.vocabApi,\n\t\t\t\tmode: TermTypes.GENE_EXPRESSION,\n\t\t\t\tcallback: async ({ geneList, groupName }) => {\n\t\t\t\t\tconst group = { name: groupName, lst: [], type: 'hierCluster' }\n\t\t\t\t\tconst lst = group.lst.filter(tw => tw.term.type != 'geneExpression')\n\n\t\t\t\t\tconst tws = await Promise.all(\n\t\t\t\t\t\tgeneList.map(async d => {\n\t\t\t\t\t\t\tconst gene = d.symbol || d.gene\n\t\t\t\t\t\t\tconst unit = getGEunit(parent.app.vocabApi)\n\t\t\t\t\t\t\tconst name = `${gene} ${unit}`\n\t\t\t\t\t\t\tconst term = { gene, name, type: 'geneExpression' }\n\t\t\t\t\t\t\tlet tw = group.lst.find(tw => tw.term.name == d.symbol || tw.term.name == d.gene)\n\t\t\t\t\t\t\tif (!tw) {\n\t\t\t\t\t\t\t\ttw = { term, q: {} }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn tw\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\n\t\t\t\t\t// close geneset edit ui after clicking submit\n\t\t\t\t\ttip.hide()\n\t\t\t\t\tif (tip.dnode.parent_menu) tip.dnode.parent_menu.style.display = 'none'\n\n\t\t\t\t\tif (tws.length == 1) {\n\t\t\t\t\t\tconst tw = tws[0]\n\t\t\t\t\t\tparent.app.dispatch({\n\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\t\tchartType: 'summary',\n\t\t\t\t\t\t\t\tterm: tw,\n\t\t\t\t\t\t\t\tterm2: samplelstTW\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif (tws.length == 2) {\n\t\t\t\t\t\tconst tw = tws[0]\n\t\t\t\t\t\tconst tw2 = tws[1]\n\t\t\t\t\t\tparent.app.dispatch({\n\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\t\tchartType: 'summary',\n\t\t\t\t\t\t\t\tterm: tw,\n\t\t\t\t\t\t\t\tterm2: tw2,\n\t\t\t\t\t\t\t\tcolorTW: samplelstTW\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup.lst = [...lst, ...tws]\n\n\t\t\t\t\tparent.app.dispatch({\n\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tchartType: 'hierCluster',\n\t\t\t\t\t\t\ttermgroups: [group],\n\t\t\t\t\t\t\tdataType: TermTypes.GENE_EXPRESSION,\n\t\t\t\t\t\t\tdivideBy: samplelstTW,\n\t\t\t\t\t\t\tsettings: { hierCluster: { yDendrogramHeight: 0, clusterSamples: false } }\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\titemDiv.insert('div').html('\u203A').style('float', 'right')\n}\n\nfunction mayAddMatrixMenuItems(div, text, tip, samplelstTW, id, parent, state, openOnTop = false, newId) {\n\tif (!state.currentCohortChartTypes.includes('matrix')) return\n\tconst preBuiltMatrix = state.matrixplots\n\tconst hasSnvIndel = parent.app.vocabApi.termdbConfig?.queries?.snvindel\n\tif (!preBuiltMatrix && !hasSnvIndel) return\n\tconst itemDiv = div\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.attr('data-testid', `sjpp-matrix-option`)\n\t\t.text(text)\n\t\t.on('click', () => {\n\t\t\ttip.clear().showunderoffset(itemDiv.node())\n\n\t\t\tif (preBuiltMatrix) {\n\t\t\t\t// adding buttons to divide each pre-built matrix\n\t\t\t\tconst preBuiltMatrixDiv = tip.d.append('div')\n\t\t\t\tfor (const plot of preBuiltMatrix) {\n\t\t\t\t\tpreBuiltMatrixDiv\n\t\t\t\t\t\t.append('button')\n\t\t\t\t\t\t.style('margin', '10px')\n\t\t\t\t\t\t.style('padding', '10px 15px')\n\t\t\t\t\t\t.style('border-radius', '20px')\n\t\t\t\t\t\t.style('border-color', '#ededed')\n\t\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t\t.text('Divide ' + plot.name)\n\t\t\t\t\t\t.on('click', async () => {\n\t\t\t\t\t\t\tconst config = await parent.app.vocabApi.getMatrixByName(plot.name)\n\t\t\t\t\t\t\tconfig.divideBy = samplelstTW\n\t\t\t\t\t\t\tconfig.insertBefore = id\n\t\t\t\t\t\t\tconfig.settings.matrix.colw = 0\n\t\t\t\t\t\t\tif (newId) config.id = newId()\n\t\t\t\t\t\t\tparent.app.dispatch({\n\t\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\t\tconfig\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\t\ttip.dnode.parent_menu.style.display = 'none'\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hasSnvIndel) {\n\t\t\t\t// adding geneSet edit UI for building new matrix\n\t\t\t\tconst newMatrixDiv = tip.d.append('div')\n\t\t\t\tnew GeneSetEditUI({\n\t\t\t\t\tholder: newMatrixDiv,\n\t\t\t\t\tgenome: parent.app.opts.genome,\n\t\t\t\t\tgeneList: [],\n\t\t\t\t\tmode: TermTypes.GENE_VARIANT,\n\t\t\t\t\tvocabApi: parent.app.vocabApi,\n\t\t\t\t\tcallback: async ({ geneList, groupName }) => {\n\t\t\t\t\t\ttip.hide()\n\t\t\t\t\t\ttip.dnode.parent_menu.style.display = 'none'\n\t\t\t\t\t\tconst group = { name: groupName, lst: [] }\n\t\t\t\t\t\tconst lst = group.lst.filter(tw => tw.term.type != 'geneVariant')\n\n\t\t\t\t\t\tconst tws = await Promise.all(\n\t\t\t\t\t\t\tgeneList.map(async d => {\n\t\t\t\t\t\t\t\tconst term = {\n\t\t\t\t\t\t\t\t\tgene: d.symbol || d.gene,\n\t\t\t\t\t\t\t\t\tname: d.symbol || d.gene,\n\t\t\t\t\t\t\t\t\ttype: 'geneVariant'\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlet tw = group.lst.find(tw => tw.term.name == d.symbol || tw.term.name == d.gene)\n\t\t\t\t\t\t\t\tif (!tw) {\n\t\t\t\t\t\t\t\t\ttw = { term }\n\t\t\t\t\t\t\t\t\tawait fillTermWrapper(tw, parent.app.vocabApi)\n\t\t\t\t\t\t\t\t} else if (!tw.$id) {\n\t\t\t\t\t\t\t\t\ttw.$id = await get$id(parent.app.vocabApi.getTwMinCopy({ term }))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn tw\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t\tgroup.lst = [...lst, ...tws]\n\t\t\t\t\t\tparent.app.dispatch({\n\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\t\tchartType: 'matrix',\n\t\t\t\t\t\t\t\ttermgroups: [group],\n\t\t\t\t\t\t\t\tdataType: TermTypes.GENE_VARIANT,\n\t\t\t\t\t\t\t\tdivideBy: samplelstTW\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\titemDiv.insert('div').html('\u203A').style('float', 'right')\n}\n\nexport function addNewGroup(app, filter, groups) {\n\tgroups = JSON.parse(JSON.stringify(groups))\n\tlet name = 'New group'\n\tlet i = 0\n\twhile (1) {\n\t\tconst name2 = name + (i == 0 ? '' : ' ' + i)\n\t\tif (!groups.find(g => g.name == name2)) break\n\t\ti++\n\t}\n\tname = name + (i == 0 ? '' : ' ' + i)\n\tconst newGroup = {\n\t\tname,\n\t\tfilter,\n\t\tcolor: rgb(colorScale(groups.length)).formatHex()\n\t}\n\tgroups.push(newGroup)\n\tapp.dispatch({\n\t\ttype: 'app_refresh',\n\t\tstate: { groups }\n\t})\n}\n\nexport function getSamplelstTWFromIds(ids) {\n\tif (!ids) throw 'getSamplelstTWFromIds: ids is empty'\n\tif (!Array.isArray(ids)) throw 'getSamplelstTWFromIds: ids must be an array'\n\tconst name = 'group'\n\tconst values = ids.map(id => {\n\t\treturn { sampleId: id }\n\t})\n\tconst qgroup = {\n\t\tname: name,\n\t\tin: true,\n\t\tvalues\n\t}\n\n\tconst tw = {\n\t\tisAtomic: true,\n\t\tterm: { name, type: 'samplelst', values: { [name]: { key: name, list: values } } },\n\t\tq: {\n\t\t\tgroups: [qgroup]\n\t\t}\n\t}\n\treturn tw\n}\n\nexport function getSamplelstFilter(ids) {\n\tconst tw = getSamplelstTWFromIds(ids)\n\tconst filter = getFilter(tw)\n\treturn filter\n}\n\nexport function getFilter(samplelstTW) {\n\tlet i = 0\n\tlet noEdit = true\n\tfor (const field in samplelstTW.term.values) {\n\t\tconst values = samplelstTW.q.groups[i].values\n\t\tsamplelstTW.term.values[field].list = values\n\t\tif (values[0] && 'sample' in values[0]) noEdit = false\n\t\ti++\n\t}\n\tconst filter = {\n\t\ttype: 'tvslst',\n\t\tin: true,\n\t\tjoin: '',\n\t\tlst: [\n\t\t\t{\n\t\t\t\ttype: 'tvs',\n\t\t\t\ttvs: { term: samplelstTW.term },\n\t\t\t\tnoEdit\n\t\t\t}\n\t\t]\n\t}\n\treturn filter\n}\n\nexport function getSampleFilter(sampleId) {\n\tif (!sampleId) throw 'getSampleFilter: sampleId is empty'\n\tif (Array.isArray(sampleId)) throw 'getSampleFilter: sampleId arg cannot be an array'\n\tconst group = { name: '', index: 0, items: [{ sampleId }] }\n\tconst samplelst = getSamplelstTW([group], '', false)\n\tconst filter = getFilter(samplelst)\n\treturn filter\n}\n\n// no special handling when groups.length=1\nexport function getSamplelstTW2(groups) {\n\tconst values = {}\n\tconst qgroups = []\n\tfor (const group of groups) {\n\t\tconst samples = getGroupSamples(group)\n\t\tconst qgroup = {\n\t\t\tname: group.name,\n\t\t\tin: true,\n\t\t\tvalues: samples\n\t\t}\n\t\tqgroups.push(qgroup)\n\t\tvalues[group.name] = { key: group.name, label: group.name, color: group.color, list: samples } //samples need to be passed for the samplelst filter to work\n\t}\n\treturn {\n\t\tisAtomic: true,\n\t\tterm: { name: 'groups', type: 'samplelst', values },\n\t\tq: { groups: qgroups }\n\t}\n}\n\nexport function getSamplelstTW(groups, name = groups.length == 1 ? 'group' : 'groups', notIn = true) {\n\tconst values = {}\n\tconst qgroups = []\n\tlet samples\n\tfor (const group of groups) {\n\t\tsamples = getGroupSamples(group)\n\t\tconst qgroup = {\n\t\t\tname: group.name,\n\t\t\tin: true,\n\t\t\tvalues: samples\n\t\t}\n\t\tqgroups.push(qgroup)\n\t\tvalues[group.name] = { key: group.name, label: group.name, color: group.color, list: samples } //samples need to be passed for the samplelst filter to work\n\t}\n\tif (groups.length == 1 && notIn) {\n\t\tconst name2 = 'Not in ' + groups[0].name\n\t\tvalues[name2] = { key: name2, label: name2, color: '#aaa', list: samples, in: false }\n\t\tqgroups.push({\n\t\t\tname: name2,\n\t\t\tin: false,\n\t\t\tvalues: samples\n\t\t})\n\t}\n\tconst tw = {\n\t\tisAtomic: true,\n\t\tterm: { name, type: 'samplelst', values },\n\t\tq: { groups: qgroups }\n\t}\n\treturn tw\n}\nfunction getGroupSamples(group) {\n\tconst values = []\n\tfor (const item of group.items) {\n\t\tconst value = { sampleId: item.sampleId }\n\t\tif ('sample' in item) {\n\t\t\tvalue.sample = item.sample\n\t\t}\n\t\tvalues.push(value)\n\t}\n\treturn values\n}\n", "import { getCompInit, multiInit, sleep } from '../rx'\nimport { make_radios } from '#dom'\nimport { termsettingInit } from '#termsetting'\nimport { rgb } from 'd3-color'\nimport { select } from 'd3-selection'\n// import { TermTypes } from '#shared/terms.js'\n\n// unique element ID's are needed for to be used for assigning unique\n// radio button names by object instance\n// otherwise termdp app popups\n\n// instanceNum is incremented for each control menu instance,\n// may be optionally used for distinguishing menu instances, such as\n// for matrix controls where there are multiple menu buttons\nlet instanceNum = 1\n\n// controlNum is incremented when calling getElemId(),\n// which creates a unique string that can be used to name related radio inputs\n// or as a unique element ID to reference with aria-labelledby,\n// when the corresponding input is not wrapped by a label element\n// or does not have an aria-label attribute (Section 508 requirement)\nlet controlNum = 1\nfunction getElemId(instanceNum) {\n\treturn `sjpp-control-${controlNum++}-${instanceNum || Math.random().toString().slice(-4)}-${Math.random()\n\t\t.toString()\n\t\t.slice(-6)}`\n}\n\nclass TdbConfigUiInit {\n\tstatic type = 'controlsConfig'\n\n\tconstructor(opts) {\n\t\tthis.type = TdbConfigUiInit.type\n\t\tthis.app = opts.app\n\t\tthis.id = opts.id\n\t\tthis.instanceNum = instanceNum++\n\t\tsetRenderers(this)\n\t}\n\n\tasync init() {\n\t\ttry {\n\t\t\tconst dispatch = this.app.dispatch\n\t\t\tconst { table } = this.setDom()\n\t\t\tconst debug = this.opts.debug\n\t\t\tthis.inputs = {} // non-rx notified\n\t\t\tconst componentPromises = {} // rx-notified\n\n\t\t\tfor (const key of this.opts.inputs) {\n\t\t\t\tif (typeof key == 'object') {\n\t\t\t\t\tconst obj = key // reassign to be less confusing\n\t\t\t\t\tif (obj.type in initByInput) {\n\t\t\t\t\t\tthis.inputs[obj.settingsKey || obj.configKey] = await initByInput[obj.type](\n\t\t\t\t\t\t\tObject.assign({}, obj, {\n\t\t\t\t\t\t\t\tholder: this.dom.table.append('tr'),\n\t\t\t\t\t\t\t\tapp: this.app,\n\t\t\t\t\t\t\t\tid: this.id,\n\t\t\t\t\t\t\t\tinstanceNum: this.instanceNum,\n\t\t\t\t\t\t\t\tdebug: this.opts.debug,\n\t\t\t\t\t\t\t\tparent: this\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t} else if (key in initByInput) {\n\t\t\t\t\tthis.inputs[key] = await initByInput[key]({\n\t\t\t\t\t\tholder: this.dom.table.append('tr'),\n\t\t\t\t\t\tapp: this.app,\n\t\t\t\t\t\tid: this.id,\n\t\t\t\t\t\tinstanceNum: this.instanceNum,\n\t\t\t\t\t\tdebug: this.opts.debug,\n\t\t\t\t\t\tparent: this\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthrow `unsupported opts.inputs[] entry of '${key}' for controlsInit()`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.components = await multiInit(componentPromises)\n\t\t} catch (e) {\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tsetDom() {\n\t\tthis.dom = {\n\t\t\tholder: this.opts.holder\n\t\t\t\t.style('position', 'relative')\n\t\t\t\t.style('max-width', '50px')\n\t\t\t\t.style('height', 0)\n\t\t\t\t.style('vertical-align', 'top')\n\t\t\t\t/** Commenting out `transition` attrs. Causes\n\t\t\t\t * the control inputs to flicker on close instead\n\t\t\t\t * of smoothly fading out. */\n\t\t\t\t// .style('transition', '0.2s ease-in-out')\n\t\t\t\t//.style('overflow', 'hidden')\n\t\t\t\t.style('visibility', 'hidden'),\n\n\t\t\ttable: this.opts.holder.append('table').attr('cellpadding', 0).attr('cellspacing', 0),\n\t\t\t// .style('transition', '0.2s')\n\n\t\t\t// default loading div, see if there is an option to override this\n\t\t\tloadingDiv: this.opts.holder\n\t\t\t\t.append('div')\n\t\t\t\t.style('position', 'absolute')\n\t\t\t\t.style('top', 0)\n\t\t\t\t.style('left', 0)\n\t\t\t\t.style('height', '100%')\n\t\t\t\t.style('width', '100%')\n\t\t\t\t.style('background-color', `rgba(255,255,255,0.7)`)\n\t\t\t\t.style('display', 'none')\n\t\t}\n\n\t\tthis.dom.loadingDiv.append('div').attr('class', 'sjpp-spinner-small')\n\t\tthis.loadingMasks = [this.dom.loadingDiv]\n\t\tif (this.opts.loadingMasks) this.loadingMasks.push(...this.opts.loadingMasks)\n\n\t\treturn this.dom\n\t}\n\n\tgetState(appState) {\n\t\tconst config = appState.plots.find(p => p.id === this.id)\n\t\treturn {\n\t\t\tgenome: appState.genome,\n\t\t\tdslabel: appState.dslabel,\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\ttermfilter: appState.termfilter,\n\t\t\tconfig,\n\t\t\tisOpen: this.opts.isOpen()\n\t\t}\n\t}\n\n\tmain() {\n\t\tconst plot = this.state.config\n\t\tconst isOpen = this.opts.isOpen()\n\t\tthis.render(isOpen)\n\t\tfor (const name in this.inputs) {\n\t\t\tconst o = this.inputs[name]\n\t\t\to.main(o.usestate ? this.state : plot)\n\t\t}\n\t\tthis.dom.loadingDiv.style('display', 'none')\n\t\tif (this.opts.loadingMasks) {\n\t\t\tfor (const m of this.opts.loadingMasks) m.style('display', 'none')\n\t\t}\n\t}\n\n\trender(isOpen) {\n\t\tthis.dom.holder\n\t\t\t.style('visibility', isOpen ? 'visible' : 'hidden')\n\t\t\t.style('max-width', isOpen ? '' : '50px') //Previously 700px max when open, but we dont want to clip the data in the profile\n\t\t\t.style('height', isOpen ? '' : 0)\n\t\t\t.style('resize', isOpen ? 'both' : 'none')\n\n\t\tthis.dom.table\n\t\t\t.selectAll('tr')\n\t\t\t.filter(this.rowIsVisible)\n\t\t\t.selectAll('td')\n\t\t\t.style('border-top', '2px solid #FFECDD')\n\t\t\t.style('padding', '5px 10px')\n\t}\n}\n\nexport const configUiInit = getCompInit(TdbConfigUiInit)\n\nfunction setRenderers(self) {\n\tself.rowIsVisible = function () {\n\t\treturn this.style.display != 'none'\n\t}\n}\n\nfunction setNumberInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\tconst self = {\n\t\tid,\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('id', id)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.html(opts.label),\n\t\t\tinputs: {}\n\t\t},\n\t\tvalues: {}\n\t}\n\n\tif (!opts.inputs) {\n\t\topts.inputs = [\n\t\t\t{\n\t\t\t\tmin: opts.min,\n\t\t\t\tmax: opts.max,\n\t\t\t\tstep: opts.step,\n\t\t\t\twidth: opts.width,\n\t\t\t\tsettingsKey: opts.settingsKey\n\t\t\t}\n\t\t]\n\t\tif (opts.placeholder) opts.inputs[0].placeholder = opts.placeholder\n\t}\n\n\t// debounce by default\n\tconst debounceTimeout =\n\t\topts.debounceInterval ||\n\t\t('debounceInterval' in opts.parent?.app.opts ? opts.parent?.app.opts.debounceInterval : 100)\n\tfor (const input of opts.inputs) {\n\t\tlet dispatchTimer\n\t\tfunction debouncedDispatch(noDispatch = false) {\n\t\t\tif (dispatchTimer) clearTimeout(dispatchTimer)\n\t\t\tif (!noDispatch) dispatchTimer = setTimeout(dispatchChange, debounceTimeout)\n\t\t}\n\n\t\tfunction dispatchChange() {\n\t\t\tlet value = Number(self.dom.inputs[input.settingsKey].property('value'))\n\t\t\tif (input.max && input.max < value) value = input.max\n\t\t\tif (input.min && input.min > value) value = input.min\n\t\t\tif (opts.callback) opts.callback(value)\n\t\t\telse {\n\t\t\t\topts.app.dispatch({\n\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\tid: opts.id,\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t\t[input.settingsKey]: opts.processInput ? opts.processInput(value) : value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst inputTd = opts.holder\n\t\t\t.append('td')\n\t\t\t.style('text-align', opts.align || '')\n\t\t\t.attr('colspan', opts.colspan || '')\n\t\tif (!input.settingsKey) {\n\t\t\tinputTd.style('color', '#555').style('cursor', 'default').html(input.label)\n\t\t} else {\n\t\t\tself.dom.inputs[input.settingsKey] = inputTd\n\t\t\t\t.append('input')\n\t\t\t\t.attr('aria-labelledby', self.id)\n\t\t\t\t.attr('type', 'number')\n\t\t\t\t.attr('placeholder', 'placeholder' in input ? input.placeholder : '')\n\t\t\t\t.attr('min', 'min' in input ? input.min : null) // verify that null gives the default html input behavior\n\t\t\t\t.attr('max', 'max' in input ? input.max : null) // same\n\t\t\t\t.attr('step', input.step || opts.step || null) //step gives the amount by which user can increment\n\t\t\t\t.style('width', (input.width || opts.width || 100) + 'px')\n\t\t\t\t.on('keyup', event => {\n\t\t\t\t\tconst valueChanged =\n\t\t\t\t\t\tself.values[opts.settingsKey] !== Number(self.dom.inputs[input.settingsKey].property('value'))\n\t\t\t\t\tdebouncedDispatch(event.key !== 'Enter' && valueChanged)\n\t\t\t\t})\n\t\t\t\t.on('change', event => {\n\t\t\t\t\tdebouncedDispatch(false)\n\t\t\t\t})\n\t\t\t// the onchange event is too sensitive for a number input, and can cause premature dispatch\n\t\t\t//.on('change', debouncedDispatch)\n\t\t}\n\t}\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst display = opts.getDisplayStyle?.(plot) || 'table-row'\n\t\t\topts.holder.style('display', display)\n\t\t\tfor (const settingsKey in self.dom.inputs) {\n\t\t\t\tconst value = plot.settings[opts.chartType][settingsKey]\n\t\t\t\tself.dom.inputs[settingsKey].property('value', value)\n\t\t\t\tself.values[settingsKey] = value\n\t\t\t}\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setMathExprInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\tconst self = {\n\t\tid,\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('id', id)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.attr('overflow', 'visible')\n\t\t\t\t.html(opts.label),\n\t\t\tinputTd: opts.holder.append('td')\n\t\t}\n\t}\n\n\tconst textByNumber = {}\n\n\tself.dom.input = self.dom.inputTd\n\t\t.append('input')\n\t\t.attr('type', 'text')\n\t\t.attr('aria-labelledby', self.id)\n\t\t.style('width', (opts.width || 100) + 'px')\n\t\t.on('change', () => {\n\t\t\tconst value = self.dom.input.property('value')\n\t\t\tconst number = Number(value)\n\t\t\tif (isNaN(number)) throw `non-numeric value for ${opts.settingsKey}='${value}'`\n\t\t\ttextByNumber[number] = value\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t[opts.settingsKey]: number\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst value = plot.settings[opts.chartType][opts.settingsKey]\n\t\t\tconst number = typeof value == 'number' ? value : Number(value)\n\t\t\tif (typeof value != 'number') textByNumber[number] = value\n\t\t\tself.dom.input.property('value', value in textByNumber ? textByNumber[number] : value)\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setTextInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\tconst self = {\n\t\tid,\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('id', id)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.html(opts.label),\n\t\t\tinputTd: opts.holder.append('td')\n\t\t}\n\t}\n\n\tself.dom.input = self.dom.inputTd\n\t\t.append('input')\n\t\t.attr('type', 'text')\n\t\t.attr('placeholder', opts.placeholder)\n\t\t.attr('aria-labelledby', self.id)\n\t\t.style('width', (opts.width || 100) + 'px')\n\t\t.on('change', () => {\n\t\t\tconst value = self.dom.input.property('value')\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t[opts.settingsKey]: opts.processInput ? opts.processInput(value) : value\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tself.dom.input.property('value', plot.settings[opts.chartType][opts.settingsKey])\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setColorInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\tconst self = {\n\t\tid,\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('id', id)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.html(opts.label),\n\t\t\tinputTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('colspan', opts.colspan || '')\n\t\t\t\t.style('text-align', opts.align || '')\n\t\t}\n\t}\n\n\tself.dom.input = self.dom.inputTd\n\t\t.append('input')\n\t\t.attr('type', 'color')\n\t\t.attr('aria-labelledby', self.id)\n\t\t.on('change', () => {\n\t\t\tconst value = self.dom.input.property('value')\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t[opts.settingsKey]: opts.processInput ? opts.processInput(value) : value\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst color = plot.settings[opts.chartType][opts.settingsKey]\n\t\t\tself.dom.input.property('value', rgb(color).formatHex())\n\t\t\topts.holder.style('display', opts.getDisplayStyle?.(plot) || 'table-row')\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setRadioInput(opts) {\n\tconst self = {\n\t\tdom: {\n\t\t\trow: opts.holder,\n\t\t\tlabelTdb: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.html(opts.label)\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t},\n\t\tinputs: {}\n\t}\n\n\tconst inputs = opts.inputs\n\t\t? opts.inputs\n\t\t: [\n\t\t\t\t{\n\t\t\t\t\tsettingsKey: opts.settingsKey,\n\t\t\t\t\toptions: opts.options\n\t\t\t\t}\n\t\t ]\n\n\tfor (const input of inputs) {\n\t\tself.inputs[input.settingsKey] = make_radios({\n\t\t\tinputName: getElemId(opts.instanceNum),\n\t\t\tholder: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('colspan', opts.colspan || '')\n\t\t\t\t.style('text-align', opts.align || ''),\n\t\t\toptions: input.options,\n\t\t\t/** In now deleted radio2.js, vertical-align = top was the preference\n\t\t\t * for mass. Keep it as the default to maintain styling */\n\t\t\tstyles: Object.assign(opts.styles || {}, { 'vertical-align': 'top' }),\n\t\t\tlisteners: {\n\t\t\t\tinput(event, d) {\n\t\t\t\t\tif (event.key && event.key !== 'Enter') return\n\n\t\t\t\t\tif (opts.callback) {\n\t\t\t\t\t\topts.callback(d.value)\n\t\t\t\t\t} else {\n\t\t\t\t\t\topts.app.dispatch({\n\t\t\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\t\t\tid: opts.id,\n\t\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t\t\t\t[input.settingsKey]: d.value\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst display = opts.getDisplayStyle?.(plot) || 'table-row'\n\t\t\tself.dom.row.style('display', display)\n\t\t\tif (display == 'none') return\n\t\t\tfor (const settingsKey in self.inputs) {\n\t\t\t\tconst radio = self.inputs[settingsKey]\n\t\t\t\tradio.main(plot.settings[opts.chartType][settingsKey])\n\t\t\t\tradio.divs.style(\n\t\t\t\t\t'display',\n\t\t\t\t\td =>\n\t\t\t\t\t\td.getDisplayStyle?.(plot, opts.styles?.display) ||\n\t\t\t\t\t\topts.labelDisplay ||\n\t\t\t\t\t\topts.styles?.display ||\n\t\t\t\t\t\t'inline-block'\n\t\t\t\t)\n\t\t\t\t//radio.labels.style('display', d => opts.labelDisplay || 'span')\n\t\t\t\tif (opts.setRadioLabel) radio.labels.html(opts.setRadioLabel)\n\t\t\t}\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setDropdownInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\tconst self = {\n\t\tid,\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder.append('td').attr('id', id).html(opts.label).attr('class', 'sja-termdb-config-row-label'),\n\t\t\tinputTd: opts.holder.append('td')\n\t\t}\n\t}\n\tlet timeoutId // for delayed multiselect change event\n\tself.dom.select = self.dom.inputTd\n\t\t.append('select')\n\t\t.attr('aria-labelledby', id)\n\t\t.property('disabled', opts.disabled)\n\t\t.property('multiple', opts.multiple)\n\t\t.on('mousedown', e => {\n\t\t\tif (!opts.multiple) return\n\t\t\te.preventDefault() //prevent default to allow add on click\n\t\t\tconst option = e.target\n\t\t\tif (option.tagName === 'OPTION') {\n\t\t\t\tclearTimeout(timeoutId) // clear any previous timeout\n\t\t\t\toption.selected = !option.selected // Toggle selection\n\n\t\t\t\t// Set a new timeout to execute the desired logic after 500ms\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\tconst options = self.dom.select.node().options\n\t\t\t\t\tconst values = []\n\t\t\t\t\tfor (const option of options) {\n\t\t\t\t\t\tif (option.selected) values.push(option.value)\n\t\t\t\t\t}\n\t\t\t\t\tconst value = values\n\t\t\t\t\tcallbackOrDispatch(opts, value)\n\t\t\t\t}, 1000) // 1000 milliseconds delay\n\t\t\t}\n\t\t})\n\t\t.on('change', e => {\n\t\t\tif (!opts.multiple) {\n\t\t\t\tconst value = self.dom.select.property('value')\n\t\t\t\tcallbackOrDispatch(opts, value)\n\t\t\t}\n\t\t})\n\n\tif (opts.multiple) self.dom.select.attr('size', opts.options.length > 10 ? 10 : opts.options.length)\n\t//Commented max-width to not clip the data in the profile\n\t//self.dom.select.style('max-width', '300px')\n\tself.dom.select\n\t\t.selectAll('option')\n\t\t.data(opts.options)\n\t\t.enter()\n\t\t.append('option')\n\t\t.property('disabled', d => d.disabled)\n\t\t.attr('value', d => d.value)\n\t\t.attr('selected', d => d.selected)\n\t\t.html(d => ' ' + d.label + ' ')\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\topts.holder.style('display', opts.getDisplayStyle?.(plot) || 'table-row')\n\t\t\tself.dom.select.property('value', plot.settings[opts.chartType][opts.settingsKey])\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction callbackOrDispatch(opts, value) {\n\tif (opts.callback) opts.callback(value)\n\telse\n\t\topts.app.dispatch({\n\t\t\ttype: 'plot_edit',\n\t\t\tid: opts.id,\n\t\t\tconfig: {\n\t\t\t\tsettings: {\n\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t[opts.settingsKey]: opts.processInput ? opts.processInput(value) : value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t})\n}\n\nfunction setCheckboxInput(opts) {\n\tconst id = getElemId(opts.instanceNum)\n\n\tconst self = {\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTdb: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('id', id)\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.html(opts.label)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label'),\n\t\t\tinputTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('colspan', opts.colspan || '')\n\t\t\t\t.style('text-align', opts.align || '')\n\t\t}\n\t}\n\n\tconst label = self.dom.inputTd.append(opts.boxLabel ? 'label' : 'span')\n\n\tself.dom.input = label\n\t\t.append('input')\n\t\t.attr('type', 'checkbox')\n\t\t.attr('aria-labelledBy', opts.boxLabel ? undefined : id)\n\t\t.attr('data-testid', opts.testid)\n\t\t.on('change', () => {\n\t\t\tconst value = self.dom.input.property('checked')\n\t\t\tif (opts.callback) opts.callback(value)\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t[opts.settingsKey]: opts.processInput ? opts.processInput(value) : value\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\tlabel.append('span').html(' ' + opts.boxLabel)\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst value = plot.settings[opts.chartType][opts.settingsKey]\n\t\t\tself.dom.input.property('checked', opts.processInput ? opts.processInput(value) : value)\n\t\t\topts.holder.style('display', opts.getDisplayStyle?.(plot) || 'table-row')\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\n/*\n\tUse for array of allowed values\n\n\tOptions are rendered descending in equal sizes down columns. \n\n\tUse opts.style to control the checkboxes layout\n\tstyle: {\n\t\tcolNum: number -> number of columns to display. Default is 2\n\t\tgap: number -> gap between columns in px. Default is 5\n\t}\n*/\nfunction setMultiCheckbox(opts) {\n\tconst numCols = opts.style?.colNum || 2\n\tconst numRows = Math.ceil(opts.options.length / numCols)\n\n\tconst self = {\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTdb: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.html(opts.label)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label'),\n\t\t\tinputTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.attr('colspan', opts.colspan || '')\n\t\t\t\t.style('text-align', opts.align || '')\n\t\t\t\t.style('padding', '5px')\n\t\t}\n\t}\n\n\t/** Check/Uncheck All option appears above all checkboxes */\n\tself.dom.selectAllDiv = self.dom.inputTd.append('div').style('padding', '5px 0').append('label')\n\n\tself.dom.selectAll = self.dom.selectAllDiv\n\t\t.append('input')\n\t\t.attr('type', 'checkbox')\n\t\t.attr('title', 'Check or uncheck all')\n\t\t.on('change', () => {\n\t\t\tconst checked = self.dom.selectAll.property('checked')\n\t\t\tself.dom.inputs.property('checked', checked)\n\t\t\tconst values = checked ? opts.options.map(d => d.value) : []\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t[opts.settingsKey]: opts.processInput?.(values) || values\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\tself.dom.selectAllDiv.append('span').text('Check/Uncheck All').style('opacity', 0.65).style('font-size', '0.9em')\n\n\t/** Grid layout for options.\n\t * Renders options down columns of equal sizes.*/\n\tself.dom.optionsDiv = self.dom.inputTd\n\t\t.append('div')\n\t\t.style('display', 'grid')\n\t\t.style('grid-template-columns', `repeat(${numCols}, 1fr)`)\n\t\t.style('grid-template-rows', `repeat(${numRows}, auto)`)\n\t\t.style('grid-auto-flow', 'column')\n\t\t.style('gap', `${opts.style.gap || 5}px`)\n\n\tself.dom.labels = self.dom.optionsDiv\n\t\t.selectAll('label')\n\t\t.data(opts.options)\n\t\t.enter()\n\t\t.append('label')\n\t\t.style('margin-right', '8px')\n\t\t.each(function (d) {\n\t\t\tconst label = select(this)\n\t\t\tself.dom.input = label\n\t\t\t\t.append('input')\n\t\t\t\t.attr('type', 'checkbox')\n\t\t\t\t.attr('name', d => d.label)\n\t\t\t\t.attr('value', d => d.value)\n\t\t\t\t.on('change', () => {\n\t\t\t\t\tconst checked = []\n\t\t\t\t\tconst value = self.dom.labels.selectAll('input').each(function (d) {\n\t\t\t\t\t\tif (this.checked) checked.push(d.value)\n\t\t\t\t\t})\n\t\t\t\t\topts.app.dispatch({\n\t\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\t\tid: opts.id,\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\t\t[opts.chartType]: {\n\t\t\t\t\t\t\t\t\t[opts.settingsKey]: opts.processInput?.(checked) || checked\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\n\t\t\tlabel.append('span').html(d.label)\n\t\t})\n\n\tself.dom.inputs = self.dom.labels.selectAll('input')\n\n\tconst api = {\n\t\tmain(plot) {\n\t\t\tconst values = plot.settings[opts.chartType][opts.settingsKey]\n\t\t\tconst checkedValues = opts.processInput?.(values) || values\n\t\t\t/** Appears checked or unchecked if all or none, respectively,\n\t\t\t * of the options are checked. */\n\t\t\tself.dom.selectAll.property('checked', checkedValues.length === opts.options.length)\n\t\t\tself.dom.inputs.property('checked', d => checkedValues.includes(d.value))\n\t\t\tself.dom.labels.style('display', d => d.getDisplayStyle?.(plot) || '')\n\t\t\topts.holder.style('display', opts.getDisplayStyle?.(plot) || 'table-row')\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\nfunction setCustomInput(opts) {\n\tconst self = {\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.html(opts.label)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title)\n\t\t\t\t.style('vertical-align', 'top'),\n\t\t\tinputTd: opts.holder.append('td')\n\t\t}\n\t}\n\n\tself.api = opts.init(self)\n\n\tif (opts.debug) self.api.Inner = self\n\treturn Object.freeze(self.api)\n}\n\n/*\n\tthis is a generalized control wrapper for termsetting pill,\n\tintended to eventually replace the more specific term1, overlay, and divide components\n\n\tmany of the options are mapped to the arguments of termsettingInit()\n*/\nasync function setTermInput(opts) {\n\tconst self = {\n\t\tdom: {\n\t\t\trow: opts.holder.style('display', 'table-row'),\n\t\t\tlabelTd: opts.holder\n\t\t\t\t.append('td')\n\t\t\t\t.html(opts.label)\n\t\t\t\t.attr('class', 'sja-termdb-config-row-label')\n\t\t\t\t.attr('aria-label', opts.title),\n\t\t\tinputTd: opts.holder.append('td')\n\t\t}\n\t}\n\n\tconst pill = await termsettingInit({\n\t\tmenuOptions: opts.menuOptions || '*',\n\t\tnumericEditMenuVersion: opts.numericEditMenuVersion || ['continuous', 'discrete'],\n\t\tvocabApi: opts.vocabApi || opts.app.vocabApi,\n\t\tvocab: opts.state?.vocab,\n\t\tactiveCohort: opts.state?.activeCohort,\n\t\tholder: self.dom.inputTd.append('div'),\n\t\tdebug: opts.debug,\n\t\tusecase: opts.usecase,\n\t\tdisable_terms: opts.disable_terms,\n\t\tgetBodyParams: opts.getBodyParams,\n\t\tdefaultQ4fillTW: opts.defaultQ4fillTW,\n\t\tgeneVariantEditMenuOnlyGrp: opts.geneVariantEditMenuOnlyGrp,\n\t\tloadingMasks: opts.parent.loadingMasks,\n\t\ttestids: opts.testids,\n\t\tcallback: async tw => {\n\t\t\t// showing \"processing data ...\"\" before pill is set\n\t\t\tif (opts.parent.dom.loadingDiv && opts.parent.dom.svg) {\n\t\t\t\topts.parent.dom.loadingDiv.selectAll('*').remove()\n\t\t\t\topts.parent.dom.loadingDiv.html('').style('display', '').style('position', 'relative').style('left', '45%')\n\t\t\t\topts.parent.dom.loadingDiv.html('Processing data ...')\n\t\t\t\topts.parent.dom.svg.style('opacity', 0.1).style('pointer-events', 'none')\n\t\t\t}\n\n\t\t\t// data is object with only one needed attribute: q, never is null\n\t\t\tif (tw && !tw.q) throw 'data.q{} missing from pill callback'\n\t\t\tif (opts.processInput) await opts.processInput(tw)\n\t\t\tawait pill.main(tw ? tw : { term: null, q: null })\n\n\t\t\tconst config = {\n\t\t\t\t[opts.configKey]: tw\n\t\t\t}\n\n\t\t\tif (opts.processConfig) opts.processConfig(config) // do the custom config modification inside the processConfig function\n\n\t\t\topts.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: opts.id,\n\t\t\t\tconfig\n\t\t\t})\n\t\t}\n\t})\n\n\tconst api = {\n\t\tusestate: true,\n\t\tmain(plot) {\n\t\t\tconst display = opts.getDisplayStyle?.(plot) || 'table-row'\n\t\t\topts.holder.style('display', display)\n\t\t\tconst { config, activeCohort, termfilter } = JSON.parse(JSON.stringify(plot))\n\t\t\tconst tw = plot[opts.configKey] || (config && config[opts.configKey]) || {}\n\t\t\tconst selectedTerms = getSelectedTerms(opts, config)\n\t\t\tconst arg = {\n\t\t\t\tterm: tw.term || null,\n\t\t\t\tq: tw.q,\n\t\t\t\tactiveCohort,\n\t\t\t\tfilter: termfilter && termfilter.filter,\n\t\t\t\tdisable_terms: getSelectedTerms(opts, config)\n\t\t\t}\n\t\t\tif ('$id' in tw) arg.$id = tw.$id\n\t\t\tpill.main(arg)\n\t\t\tself.dom.labelTd.datum(tw).html(opts.label)\n\t\t}\n\t}\n\n\tif (opts.debug) api.Inner = self\n\treturn Object.freeze(api)\n}\n\n// get selected terms across all term inputs\n// will disable these terms in termdb tree to prevent\n// entering the same term in multiple inputs\nfunction getSelectedTerms(opts, config) {\n\tconst inputs = opts.inputs || opts.parent?.opts?.inputs\n\tif (!inputs) return []\n\tconst termInputs = inputs.filter(i => i.type === 'term')\n\tconst selectedTerms = []\n\tfor (const termInput of termInputs) {\n\t\tconst tw = config[termInput.configKey]\n\t\tif (tw) selectedTerms.push(tw.term)\n\t}\n\treturn selectedTerms\n}\n\nexport const initByInput = {\n\tnumber: setNumberInput,\n\tmath: setMathExprInput,\n\ttext: setTextInput,\n\tcolor: setColorInput,\n\tradio: setRadioInput,\n\tdropdown: setDropdownInput,\n\tcheckbox: setCheckboxInput,\n\tmultiCheckbox: setMultiCheckbox,\n\tcustom: setCustomInput,\n\tterm: setTermInput\n}\n", "import { getCompInit, multiInit } from '../rx'\nimport { topBarInit } from './controls.btns'\nimport { configUiInit } from './controls.config'\nimport { TermTypes } from '#shared/terms.js'\n\n/*\nconstructor options:\n\n.inputs = []\n\tsee an example\n\n*/\n\nconst panel_bg_color = '#fdfaf4'\nconst panel_border_color = '#D3D3D3'\nlet i = 0 // track controls \"instances\" for assigning unambiguous unique input names\n// defaultQ for term0/term2\nexport const term0_term2_defaultQ = {\n\t[TermTypes.GENE_VARIANT]: { type: 'predefined-groupset' },\n\t[TermTypes.GENE_EXPRESSION]: { mode: 'discrete' },\n\t[TermTypes.METABOLITE_INTENSITY]: { mode: 'discrete' },\n\t[TermTypes.PROTEOME_ABUNDANCE]: { mode: 'discrete' },\n\t[TermTypes.DNA_METHYLATION]: { mode: 'discrete' }\n}\n\nclass TdbPlotControls {\n\tstatic type = 'plotControls'\n\n\tconstructor(opts) {\n\t\tthis.opts = opts\n\t\tthis.type = TdbPlotControls.type\n\t\tthis.customEvents = ['downloadClick', 'infoClick', 'helpClick']\n\t\tthis.isOpen = opts.isOpen || false\n\t\tthis.showTopBar = opts.hasOwnProperty('showTopBar') ? opts.showTopBar : true\n\t\tsetInteractivity(this)\n\t\tsetRenderers(this)\n\t}\n\n\tasync init() {\n\t\ttry {\n\t\t\tthis.setDom()\n\t\t\t// not using this.components since these will be manually updated later in main(),\n\t\t\t// instead of updating these via notifyComponents() from app.dispatch\n\t\t\tconst arg = {\n\t\t\t\tconfig: configUiInit({\n\t\t\t\t\tapp: this.app,\n\t\t\t\t\tid: this.id,\n\t\t\t\t\tholder: this.dom.config_div,\n\t\t\t\t\tisOpen: () => this.isOpen,\n\t\t\t\t\ttip: this.app.tip,\n\t\t\t\t\tinputs: this.opts.inputs,\n\t\t\t\t\tloadingMasks: this.opts.loadingMasks\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (this.showTopBar) {\n\t\t\t\targ.topbar = topBarInit({\n\t\t\t\t\tapp: this.app,\n\t\t\t\t\tid: this.id,\n\t\t\t\t\tholder: this.dom.topbar,\n\t\t\t\t\tcallback: this.toggleVisibility,\n\t\t\t\t\tisOpen: () => this.isOpen,\n\t\t\t\t\tdownloadHandler: event => this.bus.emit('downloadClick', event),\n\t\t\t\t\tinfoHandler: isOpen =>\n\t\t\t\t\t\tthis.app.dispatch({\n\t\t\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\t\t\tid: this.opts.id,\n\t\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\t\t\ttermInfo: {\n\t\t\t\t\t\t\t\t\t\tisVisible: isOpen\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\thelpHandler: () => this.bus.emit('helpClick'),\n\t\t\t\t\ttitle: this.opts.title\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.features = await multiInit(arg)\n\t\t} catch (e) {\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tsetDom() {\n\t\tconst dataTestId = `sjpp-plot-controls-${this.id}`\n\t\tconst topbar = this.opts.holder.append('div').attr('data-testid', `${dataTestId}-topbar`)\n\t\tconst config_div = this.opts.holder.append('div').attr('data-testid', `${dataTestId}-config`)\n\n\t\tthis.dom = {\n\t\t\tholder: this.opts.holder.style('vertical-align', 'top').attr('data-testid', `${dataTestId}-holder`),\n\t\t\t// these are listed in the displayed top-down order of input elements\n\t\t\ttopbar,\n\t\t\tconfig_div\n\t\t}\n\t}\n\n\tgetState(appState) {\n\t\tconst config = appState.plots.find(p => p.id === this.id)\n\t\tif (!config) {\n\t\t\tthrow `No plot with id='${this.id}' found.`\n\t\t}\n\t\treturn {\n\t\t\tgenome: appState.genome,\n\t\t\tdslabel: appState.dslabel,\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\ttermfilter: appState.termfilter,\n\t\t\tconfig\n\t\t}\n\t}\n\n\tmain(isOpen = undefined) {\n\t\tif (!this.state) return\n\t\tif (typeof isOpen == 'boolean') this.isOpen = isOpen\n\t\telse {\n\t\t\tconst controls = this.state.config.settings.controls\n\t\t\tif (controls && 'isOpen' in controls) this.isOpen = controls.isOpen\n\t\t}\n\n\t\tthis.render()\n\t\tconst appState = this.app.getState()\n\t\tfor (const name in this.features) {\n\t\t\tthis.features[name].update({ state: this.state, appState })\n\t\t}\n\t}\n}\n\nexport const controlsInit = getCompInit(TdbPlotControls)\n\nfunction setRenderers(self) {\n\tself.render = function () {\n\t\tself.dom.holder.style('background', self.isOpen ? panel_bg_color : '')\n\t}\n}\n\nfunction setInteractivity(self) {\n\tself.toggleVisibility = () => {\n\t\tconst controls = self.state?.config.settings.controls\n\t\tif (controls && 'isOpen' in controls) {\n\t\t\tself.app.dispatch({\n\t\t\t\ttype: 'plot_edit',\n\t\t\t\tid: self.id,\n\t\t\t\tconfig: {\n\t\t\t\t\tsettings: {\n\t\t\t\t\t\tcontrols: { isOpen: !controls.isOpen }\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t_scope_: 'none'\n\n\t\t\t\t// may be used to limit the dispatch notification, if it is reliably known that\n\t\t\t\t// no components above or outside the _notificationRoot_ should react to this action\n\t\t\t\t//_notificationRoot_: [self.api]\n\t\t\t})\n\t\t} else {\n\t\t\tself.main(!self.isOpen)\n\t\t}\n\t}\n}\n\nexport function renderTerm1Label(tw) {\n\tif (!tw || !Object.keys(tw).length) return ''\n\tswitch (tw.term.type) {\n\t\tcase TermTypes.CATEGORICAL:\n\t\t\treturn 'Group categories'\n\t\tcase TermTypes.INTEGER:\n\t\tcase TermTypes.FLOAT:\n\t\t\treturn tw.q.mode == 'discrete' ? 'Customize bins' : 'Customize'\n\t\tcase TermTypes.GENE_VARIANT:\n\t\t\treturn 'Group variants'\n\t\tcase TermTypes.SNP:\n\t\t\treturn 'Group genotypes'\n\t\tdefault:\n\t\t\treturn 'Customize'\n\t}\n}\n", "import type { AppApi, ComponentApi } from '#rx'\nimport { TwRouter, routedTermTypes } from '#tw'\n\nexport class PlotBase {\n\t//type: string\n\t//id: string\n\tapi?: ComponentApi\n\topts: any\n\tapp: AppApi\n\tid: string\n\tstate: any\n\tparentId?: string\n\n\tdom: {\n\t\t[name: string]: any\n\t} = {}\n\n\tcomponents: {\n\t\t[name: string]: ComponentApi | { [name: string]: ComponentApi }\n\t} = {}\n\n\t// dom: any\n\t// config: any\n\tconfigTermKeys?: string[]\n\n\tconstructor(opts, plotApi?: ComponentApi) {\n\t\tif (plotApi) this.api = plotApi\n\t\tthis.opts = opts\n\t\tthis.id = opts?.id\n\t\tthis.app = opts?.app\n\t\tthis.parentId = opts?.parentId\n\t}\n\n\tasync getMutableConfig() {\n\t\t// TODO: may improve to not require a full copy??\n\t\tconst config = structuredClone(this.state.config)\n\t\tif (!config || !this.configTermKeys?.length) return structuredClone(config)\n\n\t\tconst opts = {\n\t\t\tvocabApi: this.app.vocabApi\n\t\t}\n\n\t\tfor (const key of this.configTermKeys) {\n\t\t\tconst value = config[key.split('.')[0]]\n\t\t\t// const orig = this.state.config[key] // TODO: may reuse the original copy if there's a better way to mutate\n\t\t\tif (!value) continue\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tfor (const [i, v] of value.entries()) {\n\t\t\t\t\tif (key.includes('.')) {\n\t\t\t\t\t\tconst k = key.split('.')[1]\n\t\t\t\t\t\tconst _v = v[k]\n\t\t\t\t\t\tif (Array.isArray(_v)) {\n\t\t\t\t\t\t\tfor (const [j, tw] of (_v as any[]).entries()) {\n\t\t\t\t\t\t\t\tif (tw.type && routedTermTypes.has(tw.term?.type)) {\n\t\t\t\t\t\t\t\t\t_v[j] = await TwRouter.init(tw, opts)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (_v.type && routedTermTypes.has(_v.term?.type)) v[k] = await TwRouter.init(_v, opts)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (v.type && routedTermTypes.has(v.term?.type)) config[key][i] = await TwRouter.init(v, opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} /*else if (typeof orig == 'object' && orig.contructor?.name != 'Object') {\n\t\t\t\tconfig[key] = orig\n\t\t\t}*/ else if (value.type && routedTermTypes.has(value.term?.type)) {\n\t\t\t\tconfig[key] = await TwRouter.initRaw(value, opts)\n\t\t\t}\n\t\t}\n\n\t\treturn config\n\t}\n}\n\n// default UI labels\n// used by plot controls and tooltips\nexport const defaultUiLabels = {\n\tSamples: 'Samples',\n\tsamples: 'samples',\n\tSample: 'Sample',\n\tsample: 'sample',\n\tTerms: 'Variables',\n\tterms: 'variables',\n\tTerm: 'Variable',\n\tterm: 'Variable',\n\tMutations: 'Mutations',\n\tterm2: { label: 'Overlay', title: 'Overlay data' },\n\tterm0: { label: 'Divide by', title: 'Divide by data' }\n}\n", "import { getCompInit, copyMerge, deepEqual } from '../rx'\nimport getHandlers from './barchart.events'\nimport barsRenderer from './bars.renderer'\nimport { rendererSettings, plotLength } from './bars.settings'\nimport { htmlLegend, /** svgLegend, */ renderTable, DownloadMenu } from '#dom'\nimport { select } from 'd3-selection'\nimport { rgb } from 'd3-color'\nimport { controlsInit, term0_term2_defaultQ, renderTerm1Label } from './controls'\n// import { to_svg } from '../src/client'\nimport { fillTermWrapper } from '#termsetting'\nimport { getColors, mclass, plotColor } from '#shared/common.js'\nimport { isNumericTerm } from '#shared/terms.js'\nimport { roundValueAuto } from '#shared/roundValue.js'\nimport { getCombinedTermFilter } from '#filter'\nimport { PlotBase, defaultUiLabels } from '#plots/PlotBase.js'\nimport { rebaseGroupFilter } from '../mass/groups.js'\nimport { isSingleCellTerm } from '#shared/terms.js'\n\nexport class Barchart extends PlotBase {\n\tstatic type = 'barchart'\n\n\tconfigTermKeys = ['term', 'term0', 'term2']\n\n\tconstructor(opts) {\n\t\t// rx.getComponentInit() will set this.app, this.id, this.opts\n\t\tsuper(opts)\n\t\tthis.type = Barchart.type\n\t}\n\t//freeze the api of this class. don't want embedder functions to modify it.\n\tpreApiFreeze(api) {\n\t\tapi.download = this.download\n\t\tapi.getChartImages = () => this.getChartImages()\n\t}\n\n\tasync init(appState) {\n\t\tconst opts = this.opts\n\t\tconst controls = this.opts.controls ? null : opts.holder.append('div')\n\t\tconst holder = opts.controls ? opts.holder : opts.holder.append('div')\n\t\tthis.dom = {\n\t\t\tloadingDiv: holder.append('div').style('display', 'none').style('padding', '24px').html('Loading ...'),\n\t\t\theader: opts.header,\n\t\t\tcontrols,\n\t\t\tholder,\n\t\t\tbanner: holder\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'none')\n\t\t\t\t.style('text-align', 'center')\n\t\t\t\t.style('padding', '24px')\n\t\t\t\t.style('font-size', '16px'),\n\t\t\tbarDiv: holder\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'flex')\n\t\t\t\t.style('flex-direction', 'row')\n\t\t\t\t.style('flex-wrap', 'wrap')\n\t\t\t\t.style('max-width', '100vw'),\n\t\t\tlegendDiv: holder.append('div').style('margin', '5px 5px 15px 5px')\n\t\t}\n\t\tif (this.dom.header) this.dom.header.html('Barchart')\n\t\tthis.settings = JSON.parse(rendererSettings)\n\n\t\tsetRenderers(this)\n\t\tsetInteractivity(this)\n\n\t\tthis.renderers = {}\n\t\tthis.legendRenderer = htmlLegend(\n\t\t\tthis.dom.legendDiv,\n\t\t\t{\n\t\t\t\tsettings: {\n\t\t\t\t\tlegendOrientation: 'vertical'\n\t\t\t\t},\n\t\t\t\thandlers: this.handlers\n\t\t\t},\n\t\t\tthis.dom.barDiv\n\t\t)\n\t\tthis.controls = {}\n\t\tthis.term2toColor = {}\n\n\t\tif (this.opts.bar_click_override) {\n\t\t\t// will use this as callback to bar click\n\t\t\t// and will not set up bar click menu\n\t\t} else if (!this.opts.bar_click_opts) {\n\t\t\tthis.opts.bar_click_opts = ['hide_bar']\n\t\t\tif (this.app.getState().nav.header_mode === 'with_tabs') this.opts.bar_click_opts.push('add_filter', 'add_group')\n\t\t}\n\t}\n\n\tasync setControls() {\n\t\tconst state = this.state\n\t\tconst controlLabels = state.config.controlLabels\n\t\tif (!controlLabels) throw 'controls labels not found'\n\t\tthis.dom.controls.selectAll('*').remove()\n\t\tif (this.opts.controls) {\n\t\t\tthis.opts.controls.on('downloadClick.barchart', this.download)\n\t\t} else {\n\t\t\tthis.dom.holder.attr('class', 'pp-termdb-plot-viz').style('display', 'inline-block').style('min-width', '300px')\n\t\t\t//.style('margin-left', '10px')\n\n\t\t\tlet specialCase = 'default'\n\t\t\tif (isSingleCellTerm(this.state.config.term.term)) {\n\t\t\t\t//Do not prevent from loading if no sample is specified but log the error.\n\t\t\t\tif (!this.state.config.term.term.sample)\n\t\t\t\t\tconsole.error('single cell term without sample specified in config, unexpected')\n\t\t\t\telse {\n\t\t\t\t\tspecialCase = {\n\t\t\t\t\t\ttype: 'singleCell',\n\t\t\t\t\t\tconfig: { sample: this.state.config.term.term.sample }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst inputs = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'term',\n\t\t\t\t\tconfigKey: 'term',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tusecase: { target: 'barchart', detail: 'term' },\n\t\t\t\t\tlabel: controlLabels.term1?.label || renderTerm1Label,\n\t\t\t\t\tvocabApi: this.app.vocabApi,\n\t\t\t\t\tmenuOptions: 'edit',\n\t\t\t\t\tdefaultQ4fillTW: { geneVariant: { type: 'custom-groupset' } },\n\t\t\t\t\tgetBodyParams: () => {\n\t\t\t\t\t\tconst tw = this.config['term']\n\t\t\t\t\t\tif (!tw) return { skip_categories: true }\n\t\t\t\t\t\tif (tw.term.categories) return { categories: tw.term.categories }\n\t\t\t\t\t\treturn {}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'term',\n\t\t\t\t\tconfigKey: 'term2',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tusecase: { target: 'barchart', detail: 'term2', specialCase },\n\t\t\t\t\ttitle: controlLabels.term2.title || controlLabels.term2.label,\n\t\t\t\t\tlabel: controlLabels.term2.label,\n\t\t\t\t\tvocabApi: this.app.vocabApi,\n\t\t\t\t\tnumericEditMenuVersion: this.opts.numericEditMenuVersion || ['continuous', 'discrete'],\n\t\t\t\t\tdefaultQ4fillTW: term0_term2_defaultQ,\n\t\t\t\t\tgetDisplayStyle: () => (this.isCategoricalTermCollection() ? 'none' : ''),\n\t\t\t\t\tprocessConfig: config => {\n\t\t\t\t\t\t//config.settings not usually passed for logic check below\n\t\t\t\t\t\tconst s = this.state.config.settings.barchart\n\t\t\t\t\t\tif (!config.settings) config.settings = { barchart: {} }\n\t\t\t\t\t\t//Prevent showing Log option when overlay is selected\n\t\t\t\t\t\tif (config.term2 && s.unit == 'log') config.settings.barchart.unit = 'abs'\n\t\t\t\t\t\t//Revert back to Linear radio when Proportion is selected\n\t\t\t\t\t\t//but the overlay term is removed\n\t\t\t\t\t\tif (!config.term2 && s.unit == 'pct') config.settings.barchart.unit = 'abs'\n\t\t\t\t\t},\n\t\t\t\t\tgetBodyParams: () => {\n\t\t\t\t\t\tconst tw = this.config['term2']\n\t\t\t\t\t\tif (!tw) return { skip_categories: true }\n\t\t\t\t\t\tif (tw.term.categories) return { categories: tw.term.categories }\n\t\t\t\t\t\treturn {}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'term',\n\t\t\t\t\tconfigKey: 'term0',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tusecase: { target: 'barchart', detail: 'term0', specialCase },\n\t\t\t\t\ttitle: controlLabels.term0.title || controlLabels.term0.label,\n\t\t\t\t\tlabel: controlLabels.term0.label,\n\t\t\t\t\tvocabApi: this.app.vocabApi,\n\t\t\t\t\t// by default, do not allow continuous mode for divide-by term, since\n\t\t\t\t\t// it will create a separate violin-overlay group per unique float or integer value\n\t\t\t\t\t// and there will nonsensical tens/hundreds of these charts based on the cohort size\n\t\t\t\t\tnumericEditMenuVersion: this.opts.numericEditMenuVersion || ['discrete'],\n\t\t\t\t\tdefaultQ4fillTW: term0_term2_defaultQ,\n\t\t\t\t\tgetDisplayStyle: () => (this.isCategoricalTermCollection() ? 'none' : ''),\n\t\t\t\t\tgetBodyParams: () => {\n\t\t\t\t\t\tconst tw = this.config['term0']\n\t\t\t\t\t\tif (!tw) return { skip_categories: true }\n\t\t\t\t\t\tif (tw.term.categories) return { categories: tw.term.categories }\n\t\t\t\t\t\treturn {}\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Bar orientation',\n\t\t\t\t\ttype: 'radio',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'orientation',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{ label: 'Vertical', value: 'vertical' },\n\t\t\t\t\t\t{ label: 'Horizontal', value: 'horizontal' }\n\t\t\t\t\t]\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Scale',\n\t\t\t\t\ttype: 'radio',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'unit',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{ label: 'Linear', value: 'abs' },\n\t\t\t\t\t\t/** Option not available when term2 is present:\n\t\t\t\t\t\t * 1. The scale for the plot renders incorrectly\n\t\t\t\t\t\t * 2. The bars do not appear to be rendering correctly as a result\n\t\t\t\t\t\t * TODOs: Investigate the cause of the rendering issue\n\t\t\t\t\t\t */\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Log',\n\t\t\t\t\t\t\tvalue: 'log',\n\t\t\t\t\t\t\tgetDisplayStyle: (plot, computedDisplay = 'inline-block') => (plot.term2 ? 'none' : computedDisplay)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: 'Proportion',\n\t\t\t\t\t\t\tvalue: 'pct',\n\t\t\t\t\t\t\tgetDisplayStyle: (plot, computedDisplay = 'inline-block') => (plot.term2 ? computedDisplay : 'none')\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Multicolor bars',\n\t\t\t\t\ttitle: 'Color bars',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'colorBars',\n\t\t\t\t\tboxLabel: 'Yes',\n\t\t\t\t\tgetDisplayStyle: plot => (plot.term2 ? 'none' : 'table-row')\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Deduplicate',\n\t\t\t\t\ttitle: 'Use separate bars samples that has multiple values or belong to multiple groups',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'dedup',\n\t\t\t\t\tboxLabel: 'Yes',\n\t\t\t\t\tgetDisplayStyle: plot =>\n\t\t\t\t\t\tthis.chartsData?.charts.find(\n\t\t\t\t\t\t\tc =>\n\t\t\t\t\t\t\t\tc.dedupedSerieses?.length &&\n\t\t\t\t\t\t\t\t!deepEqual(\n\t\t\t\t\t\t\t\t\tc.serieses.map(s => s.seriesId),\n\t\t\t\t\t\t\t\t\tc.dedupedSerieses.map(s => s.seriesId)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? 'table-row'\n\t\t\t\t\t\t\t: 'none'\n\t\t\t\t}\n\t\t\t]\n\t\t\tif (isNumericTerm(this.config.term.term))\n\t\t\t\tinputs.push({\n\t\t\t\t\tlabel: 'Show stats',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'showStats',\n\t\t\t\t\tboxLabel: 'Yes'\n\t\t\t\t})\n\t\t\tif (!this.config.term2)\n\t\t\t\tinputs.push({\n\t\t\t\t\tlabel: 'Show percent',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'showPercent',\n\t\t\t\t\tboxLabel: 'Yes'\n\t\t\t\t})\n\t\t\telse\n\t\t\t\tinputs.push({\n\t\t\t\t\tlabel: 'Show association tests',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'showAssociationTests',\n\t\t\t\t\tboxLabel: 'Yes'\n\t\t\t\t})\n\t\t\tif (state.config.settings.barchart.colorBars && (state.config.term2 || state.config.term0))\n\t\t\t\tinputs.splice(7, 0, {\n\t\t\t\t\tlabel: 'Assign colors to',\n\t\t\t\t\ttitle: `Colors bars either considering all the categories or the present categories. If there are many categories and only few are present the present choice will provide more contrast.`,\n\t\t\t\t\ttype: 'radio',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'colorUsing',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{ label: 'All values', value: 'all' },\n\t\t\t\t\t\t{ label: 'Present values', value: 'present' }\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\telse if (!state.config.settings.barchart.colorBars)\n\t\t\t\tinputs.splice(6, 0, {\n\t\t\t\t\tlabel: 'Default color',\n\t\t\t\t\ttitle: 'Default color for bars when there is no overlay',\n\t\t\t\t\ttype: 'color',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'defaultColor'\n\t\t\t\t\t//getDisplayStyle: plot => (plot.settings.barchart.colorBars || plot.term2 ? 'none' : 'table-row')\n\t\t\t\t})\n\n\t\t\tinputs.push({\n\t\t\t\tlabel: 'Plot length',\n\t\t\t\ttitle: `Set the plot length in pixels between 200 and 800.`,\n\t\t\t\ttype: 'number',\n\t\t\t\tchartType: 'barchart',\n\t\t\t\tsettingsKey: 'plotLength',\n\t\t\t\tmin: 200,\n\t\t\t\tmax: 800,\n\t\t\t\tstep: 10\n\t\t\t})\n\n\t\t\tconst multipleTestingCorrection = this.app.getState().termdbConfig.multipleTestingCorrection\n\t\t\tif (multipleTestingCorrection) {\n\t\t\t\t// a checkbox to allow users to show or hide asterisks on bars\n\t\t\t\tinputs.push({\n\t\t\t\t\tlabel: 'Asterisks',\n\t\t\t\t\tboxLabel: 'Visible',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'asterisksVisible',\n\t\t\t\t\ttitle: 'Display the asterisks'\n\t\t\t\t})\n\t\t\t\tconst mtcMethod = multipleTestingCorrection.method\n\t\t\t\tif (!mtcMethod) throw 'no multiple testing correction method specified'\n\t\t\t\tinputs.push({\n\t\t\t\t\tlabel: `Multiple testing correction (${mtcMethod == 'bon' ? 'Bonferroni' : mtcMethod})`,\n\t\t\t\t\tboxLabel: '',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchartType: 'barchart',\n\t\t\t\t\tsettingsKey: 'multiTestingCorr',\n\t\t\t\t\ttitle: `Perform multiple testing correction (${mtcMethod == 'bon' ? 'Bonferroni' : mtcMethod})`\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis.components = {\n\t\t\t\tcontrols: await controlsInit({\n\t\t\t\t\tapp: this.app,\n\t\t\t\t\tid: this.id,\n\t\t\t\t\tholder: this.dom.controls.style('display', 'inline-block'),\n\t\t\t\t\tinputs\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis.components.controls.on('downloadClick.barchart', this.download)\n\t\t}\n\t}\n\n\treactsTo(action) {\n\t\tif (action.type.startsWith('plot_')) {\n\t\t\treturn (\n\t\t\t\t(action.id === this.id || action.id == this.parentId) &&\n\t\t\t\t(!action.config?.childType || action.config?.childType == this.type)\n\t\t\t)\n\t\t}\n\t\treturn true\n\t}\n\n\tgetState(appState) {\n\t\tconst config = appState.plots.find(p => p.id === this.id)\n\t\tif (!config) {\n\t\t\tthrow `No plot with id='${this.id}' found. Did you set this.id before this.api = getComponentApi(this)?`\n\t\t}\n\t\tconst parentConfig = this.parentId && appState.plots.find(p => p.id === this.parentId)\n\t\t// TODO: may need to combine parentConfig.filter with local config.filter\n\t\tconst termfilter = getCombinedTermFilter(appState, config.filter || parentConfig?.filter)\n\t\treturn {\n\t\t\tnav: {\n\t\t\t\theader_mode: appState.nav.header_mode\n\t\t\t},\n\t\t\ttermfilter,\n\t\t\tconfig: Object.assign({}, config, {\n\t\t\t\tsettings: {\n\t\t\t\t\tbarchart: config.settings.barchart,\n\t\t\t\t\tcommon: config.settings.common\n\t\t\t\t},\n\t\t\t\tdisplaySampleIds: appState.termdbConfig.displaySampleIds && this.app.vocabApi.hasVerifiedToken()\n\t\t\t}),\n\t\t\tmultipleTestingCorrection: appState.termdbConfig.multipleTestingCorrection,\n\t\t\tbar_click_menu: appState.bar_click_menu || {},\n\t\t\tgroups: rebaseGroupFilter(appState),\n\t\t\tparentError: this.app.getComponents(`plots.${this.parentId}`)?.getError?.()\n\t\t}\n\t}\n\n\tasync main() {\n\t\tconst c = this.state.config\n\t\tif (c.chartType != this.type && c.childType != this.type) return\n\t\tif (this.state.parentError) throw this.state.parentError\n\t\ttry {\n\t\t\tthis.config = await this.getMutableConfig(c)\n\t\t\tif (!this.currServerData) this.dom.barDiv.style('max-width', window.innerWidth + 'px')\n\t\t\tthis.prevConfig = this.config || {}\n\t\t\tif (this.dom.header)\n\t\t\t\tthis.dom.header.html(\n\t\t\t\t\tthis.config.term.term.name + ` <span style=\"opacity:.6;font-size:.7em;margin-left:10px;\">BARCHART</span>`\n\t\t\t\t)\n\n\t\t\tthis.toggleLoadingDiv()\n\n\t\t\tconst reqOpts = this.getDataRequestOpts()\n\t\t\tawait this.getDescrStats()\n\t\t\tawait this.setControls() //needs to be called after getDescrStats() to set hasStats\n\t\t\tconst results = await this.app.vocabApi.getNestedChartSeriesData(reqOpts, this.api.getAbortSignal())\n\t\t\tif (results.error) throw results\n\t\t\tconst data = results.data\n\t\t\tthis.charts = data.charts\n\t\t\tthis.sampleType = results.sampleType\n\t\t\tthis.bins = results.bins\n\t\t\tif (results.chartid2dtterm) this.chartid2dtterm = results.chartid2dtterm\n\t\t\tthis.toggleLoadingDiv('none')\n\t\t\tthis.app.vocabApi.syncTermData(this.config, data, this.prevConfig)\n\t\t\tthis.currServerData = data\n\t\t\tif (this.currServerData.refs && this.currServerData.refs.q) {\n\t\t\t\tfor (const q of this.currServerData.refs.q) {\n\t\t\t\t\tif (q.error) throw q.error\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.term1toColor = {}\n\t\t\tthis.term2toColor = {} // forget any assigned overlay colors when refreshing a barchart\n\t\t\tthis.hasMultiCategoryKeys = this.isCategoricalTermCollection()\n\t\t\tthis.updateSettings(this.config)\n\t\t\tfor (const chart of data.charts) {\n\t\t\t\tconst categoriesPerSerie = chart.serieses.map(s => s.data.length)\n\t\t\t\tconst hasOverlay = this.config.term2 || this.hasMultiCategoryKeys\n\t\t\t\tconst numColors = hasOverlay ? Math.max(...categoriesPerSerie) : chart.serieses.length\n\t\t\t\tchart.colorScale = getColors(numColors)\n\t\t\t}\n\t\t\tthis.chartsData = this.processData(this.currServerData)\n\t\t\tthis.render()\n\t\t\tthis.dom.barDiv.style('display', 'flex')\n\t\t} catch (e) {\n\t\t\tif (this.app.isAbortError(e)) return\n\t\t\tthis.toggleLoadingDiv('none')\n\t\t\tthis.dom.barDiv.style('display', 'none')\n\t\t\tthrow e\n\t\t}\n\t}\n\n\t// creates an opts object for the vocabApi.getNestedChartsData()\n\tgetDataRequestOpts() {\n\t\tconst c = this.config\n\t\tconst opts = { term: c.term, filter: this.state.termfilter.filter }\n\t\tif (this.state.termfilter.filter0) opts.filter0 = this.state.termfilter.filter0\n\t\tif (c.term2) opts.term2 = c.term2\n\t\tif (c.term0) opts.term0 = c.term0\n\t\treturn opts\n\t}\n\n\tasync getDescrStats() {\n\t\t// get descriptive statistics for numerical terms\n\t\tconst terms = [this.config.term]\n\t\tif (this.config.term2) terms.push(this.config.term2)\n\t\tif (this.config.term0) terms.push(this.config.term0)\n\n\t\tfor (const t of terms) {\n\t\t\tif (isNumericTerm(t.term)) {\n\t\t\t\tconst data = await this.app.vocabApi.getDescrStats(t, this.state.termfilter, null, this.api.getAbortSignal())\n\t\t\t\tif (data.error) throw data.error\n\t\t\t\tt.q.descrStats = data\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateSettings(config) {\n\t\tif (!config) return\n\t\t// translate relevant config keys to barchart settings keys\n\t\tconst obj = this.state\n\t\tconst settings = {\n\t\t\tterm0: config.term0 ? config.term0.term.id : '', // convenient reference to the term id\n\t\t\tterm1: config.term.term.id, // convenient reference to the term2 id\n\t\t\tterm2: config.term2 ? config.term2.term.id : '',\n\t\t\tunit: config.settings.barchart.unit,\n\t\t\torientation: config.settings.barchart.orientation,\n\t\t\tasterisksVisible: config.settings.barchart.asterisksVisible,\n\t\t\tmultiTestingCorr: config.settings.barchart.multiTestingCorr,\n\t\t\tdefaultColor: config.settings.barchart.defaultColor,\n\t\t\tcolorBars: config.settings.barchart.colorBars,\n\t\t\tdedup: config.settings.barchart.dedup,\n\t\t\tplotLength: config.settings.barchart.plotLength,\n\t\t\t// normalize bar thickness regardless of orientation\n\t\t\tcolw: config.settings.barchart.barwidth,\n\t\t\trowh: config.settings.barchart.barwidth,\n\t\t\tcolspace: config.settings.barchart.barspace,\n\t\t\trowspace: config.settings.barchart.barspace,\n\t\t\tcolorUsing: config.settings.barchart.colorUsing,\n\t\t\tshowStats: config.settings.barchart.showStats,\n\t\t\tshowAssociationTests: config.settings.barchart.showAssociationTests\n\t\t}\n\n\t\t/* mayResetHidden() was added before to prevent showing empty chart due to automatic hiding uncomputable categories\n\t\tthis has following problems:\n\t\t1. when term1=diaggrp and term2=hrtavg, uncomputable categories from term2 can show up by default.\n\t\t2. inconsistent behavior: when term1=agedx, term2=hrtavg the uncomputable categories are hidden by default\n\n\t\tside effect of disabling this function can cause empty chart, but seems to be minor given above\n\t\t*/\n\t\t//this.mayResetHidden(this.config.term, this.config.term2, this.config.term0)\n\n\t\tthis.setExclude(this.config.term, this.config.term2)\n\t\tObject.assign(this.settings, settings, this.currServerData.refs || {}, {\n\t\t\texclude: this.settings.exclude\n\t\t})\n\n\t\tthis.settings.cols = this.settings.dedup ? this.currServerData.refs.dedupCols : this.currServerData.refs.cols\n\t\tthis.settings.numCharts = this.currServerData.charts ? this.currServerData.charts.length : 0\n\t\tif (!config.term2 && this.settings.unit == 'pct') {\n\t\t\tthis.settings.unit = 'abs'\n\t\t}\n\t}\n\n\tmayResetHidden(term, term2, term0) {\n\t\tconst combinedTermIds = (term && term.term.id) + ';;' + (term2 && term2.term.id) + ';;' + (term0 && term0.term.id)\n\t\tif (combinedTermIds === this.currCombinedTermIds) return\n\t\t// only reset hidden if terms have changed\n\t\tfor (const chart of this.currServerData.charts) {\n\t\t\tif (term.q && term.q.hiddenValues) {\n\t\t\t\tthis.mayEditHiddenValues(term, chart.serieses.length, 'term')\n\t\t\t}\n\t\t\tif (term2 && term2.q && term2.q.hiddenValues) {\n\t\t\t\tfor (const series of chart.serieses) {\n\t\t\t\t\tthis.mayEditHiddenValues(term2, series.data.length, 'term2')\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.currCombinedTermIds = combinedTermIds\n\t}\n\n\tmayEditHiddenValues(term, numAvailable, termNum) {\n\t\tconst numHidden = Object.keys(term.q.hiddenValues).filter(key => term.q.hiddenValues[key]).length\n\t\tif (numHidden < numAvailable) return\n\t\t/*\n\t\t\tif all the serieses are assigned to be hidden on first render,\n\t\t\tshow the usually hidden values instead to avoid confusion\n\t\t\twith an empty plot\n\t\t*/\n\t\tfor (const key in term.q.hiddenValues) {\n\t\t\tif (!term.q.hiddenValues[key]) return\n\t\t\tdelete term.q.hiddenValues[key]\n\t\t}\n\t\t// since config.[term | term2 | term0] are copies of appState,\n\t\t// must save the changes to q.hiddenValues in the stored state\n\t\t// for consistent behavior in later app.dispatch or barchart updates\n\t\tthis.app.save({\n\t\t\ttype: 'plot_edit',\n\t\t\tid: this.id,\n\t\t\tconfig: {\n\t\t\t\t[termNum]: term\n\t\t\t}\n\t\t})\n\t}\n\n\tsetExclude(term, term2) {\n\t\t// a non-numeric term.id is used directly as seriesId or dataId\n\t\tthis.settings.exclude.cols = Object.keys(term.q?.hiddenValues || {})\n\t\t\t.filter(id => term.q.hiddenValues[id])\n\t\t\t.map(id => {\n\t\t\t\treturn term.term.type == 'categorical'\n\t\t\t\t\t? id\n\t\t\t\t\t: this.settings.cols?.includes(id)\n\t\t\t\t\t? id\n\t\t\t\t\t: term.term.values[id]?.label\n\t\t\t\t\t? term.term.values[id].label\n\t\t\t\t\t: id\n\t\t\t})\n\n\t\tthis.settings.exclude.rows = !term2?.q?.hiddenValues\n\t\t\t? []\n\t\t\t: Object.keys(term2.q.hiddenValues)\n\t\t\t\t\t.filter(id => term2.q.hiddenValues[id])\n\t\t\t\t\t.map(id =>\n\t\t\t\t\t\tterm2.term.type == 'categorical'\n\t\t\t\t\t\t\t? id\n\t\t\t\t\t\t\t: this.settings.rows?.includes(id)\n\t\t\t\t\t\t\t? id\n\t\t\t\t\t\t\t: term2.term.values[id]?.label\n\t\t\t\t\t\t\t? term2.term.values[id].label\n\t\t\t\t\t\t\t: id\n\t\t\t\t\t)\n\t}\n\n\tprocessData(chartsData) {\n\t\tthis.seriesOrder = this.setMaxVisibleTotals(chartsData)\n\t\tif (!chartsData.charts.length) {\n\t\t\tthis.seriesOrder = []\n\t\t} else if (chartsData.refs.useColOrder) {\n\t\t\tthis.seriesOrder = this.settings.cols\n\t\t}\n\n\t\tconst rows = chartsData.refs.rows\n\n\t\tthis.barSorter = (a, b) => this.seriesOrder.indexOf(a) - this.seriesOrder.indexOf(b)\n\t\tthis.overlaySorter = chartsData.refs.useRowOrder\n\t\t\t? (a, b) => rows.indexOf(a.dataId) - rows.indexOf(b.dataId)\n\t\t\t: (a, b) =>\n\t\t\t\t\tthis.totalsByDataId[b.dataId] > this.totalsByDataId[a.dataId]\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: this.totalsByDataId[b.dataId] < this.totalsByDataId[a.dataId]\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: a.dataId < b.dataId\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: 1\n\n\t\tthis.visibleCharts = chartsData.charts.filter(chart => chart.visibleSerieses.length)\n\n\t\tconst t1 = this.config.term\n\t\tconst t2 = this.config.term2\n\t\tconst chartsTests = chartsData.tests\n\n\t\t//get term1 and term2 labels\n\t\tfor (const chartId in chartsTests) {\n\t\t\tconst chartTests = chartsTests[chartId]\n\t\t\tfor (const t1c of chartTests) {\n\t\t\t\tconst t1label =\n\t\t\t\t\tt1.term.values && t1c.term1comparison in t1.term.values\n\t\t\t\t\t\t? t1.term.values[t1c.term1comparison].label\n\t\t\t\t\t\t: t1c.term1comparison\n\t\t\t\tt1c.term1Label = t1label\n\n\t\t\t\tfor (const t2t of t1c.term2tests) {\n\t\t\t\t\tconst t2label =\n\t\t\t\t\t\tt2.term.values && t2t.term2id in t2.term.values ? t2.term.values[t2t.term2id].label : t2t.term2id\n\t\t\t\t\tt2t.term2Label = t2label\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn chartsData\n\t}\n\n\tsetMaxVisibleTotals(chartsData) {\n\t\t// chartsData = this.currServerData\n\t\tthis.totalsByDataId = {}\n\t\tconst t1 = this.config.term\n\t\tconst t2 = this.config.term2\n\t\t// this will prioritize sorting series totals in the first chart,\n\t\t// then serieses in the subsequent chart that are not already in the first chart, and so on\n\t\tconst visibleTotalsByChartSeriesId = {}\n\t\tlet maxVisibleAcrossCharts = 0\n\t\tfor (const chart of chartsData.charts) {\n\t\t\tif (!chart.settings) chart.settings = JSON.parse(rendererSettings)\n\t\t\tObject.assign(chart.settings, this.settings)\n\t\t\tchart.visibleTotal = 0\n\t\t\tconst serieses = this.settings.dedup ? chart.dedupedSerieses : chart.serieses\n\t\t\tchart.visibleSerieses = serieses.filter(series => {\n\t\t\t\tif (chart.settings.exclude.cols.includes(series.seriesId)) return false\n\t\t\t\tseries.visibleData = series.data.filter(d => !chart.settings.exclude.rows.includes(d.dataId))\n\t\t\t\tseries.visibleTotal = series.visibleData.reduce((sum, a) => sum + a.total, 0)\n\t\t\t\tif (!series.visibleTotal) return false\n\t\t\t\tchart.visibleTotal += series.visibleTotal\n\t\t\t\tif (!(series.seriesId in visibleTotalsByChartSeriesId))\n\t\t\t\t\tvisibleTotalsByChartSeriesId[series.seriesId] = series.visibleTotal\n\t\t\t\tfor (const data of series.data) {\n\t\t\t\t\tdata.seriesId = series.seriesId\n\t\t\t\t\tif (\n\t\t\t\t\t\t(t1.term.type == 'geneVariant' && t1.q.type == 'values') ||\n\t\t\t\t\t\t(t2?.term.type == 'geneVariant' && t2?.q.type == 'values')\n\t\t\t\t\t) {\n\t\t\t\t\t\t// term1 or term2 is a geneVariant term not using groupsetting\n\t\t\t\t\t\t// need specialized processing\n\t\t\t\t\t\tif (!(data.dataId in this.totalsByDataId)) {\n\t\t\t\t\t\t\tthis.totalsByDataId[data.dataId] = {}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.totalsByDataId[data.dataId][chart.chartId] = this.totalsByDataId[data.dataId][chart.chartId]\n\t\t\t\t\t\t\t? this.totalsByDataId[data.dataId][chart.chartId] + data.total\n\t\t\t\t\t\t\t: 0 + data.total\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!(data.dataId in this.totalsByDataId)) {\n\t\t\t\t\t\t\tthis.totalsByDataId[data.dataId] = 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.totalsByDataId[data.dataId] += data.total\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t})\n\t\t\tchart.settings.colLabels = chart.visibleSerieses.map(series => {\n\t\t\t\tconst id = series.seriesId\n\t\t\t\tconst label = t1.term.values && id in t1.term.values ? t1.term.values[id].label : id\n\t\t\t\tconst af = series && 'AF' in series ? ', AF=' + series.AF : ''\n\t\t\t\tconst ntotal =\n\t\t\t\t\tt2 && t2.term.type == 'condition' && t2.q.value_by_computable_grade ? '' : `, n=${series.visibleTotal}`\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\tlabel: label + af + ntotal\n\t\t\t\t}\n\t\t\t})\n\t\t\tchart.maxVisibleSeriesTotal = chart.visibleSerieses.reduce((max, series) => {\n\t\t\t\treturn series.visibleTotal > max ? series.visibleTotal : max\n\t\t\t}, 0)\n\t\t\tif (chart.maxVisibleSeriesTotal > maxVisibleAcrossCharts) {\n\t\t\t\tmaxVisibleAcrossCharts = chart.maxVisibleSeriesTotal\n\t\t\t}\n\t\t}\n\t\tfor (const chart of chartsData.charts) {\n\t\t\tchart.maxVisibleAcrossCharts = maxVisibleAcrossCharts\n\t\t}\n\n\t\treturn Object.keys(visibleTotalsByChartSeriesId).sort(\n\t\t\t(a, b) => visibleTotalsByChartSeriesId[b] - visibleTotalsByChartSeriesId[a]\n\t\t)\n\t}\n\n\tsortStacking(series, chart, chartsData) {\n\t\tthis.term1toColor[series.seriesId] = this.settings.colorBars\n\t\t\t? this.getColor(chart, this.config.term, series.seriesId, this.bins?.[1])\n\t\t\t: this.settings.defaultColor\n\n\t\tseries.visibleData.sort(this.overlaySorter)\n\t\tlet seriesLogTotal = 0\n\t\tfor (const result of series.visibleData) {\n\t\t\tresult.colgrp = '-'\n\t\t\tresult.rowgrp = '-'\n\t\t\tresult.chartId = chart.chartId\n\t\t\tresult.seriesId = series.seriesId\n\t\t\tif (chartsData.tests) {\n\t\t\t\t// statistical tests result exist\n\t\t\t\t// put the pvalues corresponding to series.seriesId to result.groupPvalues\n\t\t\t\tresult.groupPvalues = chartsData.tests[chart.chartId].find(x => x.term1comparison === series.seriesId)\n\t\t\t}\n\t\t\tresult.seriesTotal = series.total\n\t\t\tresult.chartTotal = chart.visibleTotal\n\t\t\tresult.logTotal = Math.log10(result.total)\n\t\t\tseriesLogTotal += result.logTotal\n\t\t\tthis.setTerm2Color(chart, result)\n\t\t\tresult.color = this.term2toColor[result.dataId] || this.term1toColor[series.seriesId]\n\t\t}\n\t\tif (seriesLogTotal > chart.maxSeriesLogTotal) {\n\t\t\tchart.maxSeriesLogTotal = seriesLogTotal\n\t\t}\n\t\t// assign color to hidden data for use in legend\n\t\tfor (const result of series.data) {\n\t\t\tif (result.color) continue\n\t\t\tthis.setTerm2Color(chart, result)\n\t\t\tresult.color = this.term2toColor[result.dataId] || this.term1toColor[series.seriesId]\n\t\t}\n\t}\n\n\tsetTerm2Color(chart, result) {\n\t\tif (this.hasMultiCategoryKeys && !this.config.term2) {\n\t\t\tthis.term2toColor[result.dataId] = rgb(chart.colorScale(result.dataId)).toString()\n\t\t\treturn\n\t\t}\n\t\tif (!this.config.term2) return\n\t\tthis.term2toColor[result.dataId] = this.getColor(chart, this.config.term2, result.dataId, this.bins?.[2])\n\t}\n\n\tisCategoricalTermCollection() {\n\t\tconst t1 = this.config.term\n\t\treturn t1?.term?.type === 'termCollection' && t1.term.memberType === 'categorical'\n\t}\n\n\tgetCategoryKeyLabel(t1, t2, dataId) {\n\t\tif (t2?.term?.values && dataId in t2.term.values) return t2.term.values[dataId].label\n\t\tif (this.hasMultiCategoryKeys && t1?.term?.termlst?.length) {\n\t\t\t// for categorical termCollection, dataId is the term name (from server JOIN); find by name\n\t\t\tconst memberTerm = t1.term.termlst.find(mt => mt.name === dataId)\n\t\t\tif (memberTerm?.name) return memberTerm.name\n\t\t\t// fallback: look up category value label from member term values dict (numeric collection)\n\t\t\tfor (const mt of t1.term.termlst) {\n\t\t\t\tif (mt.values && dataId in mt.values) return mt.values[dataId].label\n\t\t\t}\n\t\t}\n\t\treturn dataId\n\t}\n\n\tgetColor(chart, t, label, bins) {\n\t\tif (!t.term) return\n\t\tif (t.q.type == 'predefined-groupset' || t.q.type == 'custom-groupset') {\n\t\t\tconst groupset =\n\t\t\t\tt.q.type == 'predefined-groupset' ? t.term.groupsetting.lst[t.q.predefined_groupset_idx] : t.q.customset\n\t\t\tif (!groupset) throw 'groupset is missing'\n\t\t\tconst group = groupset.groups.find(g => g.name == label)\n\t\t\tif (group?.color) return group.color\n\t\t}\n\t\t//use predefined colors unless colorBars is set to true.\n\t\t// Assigning colors to bars uses a better color scale as the scale considers the categories present, not in all the categories\n\t\tif (t.term.values && this.settings.colorUsing == 'all') {\n\t\t\tfor (const [key, v] of Object.entries(t.term.values)) {\n\t\t\t\tif (!v.color) continue\n\t\t\t\tif (key === label) return v.color\n\t\t\t\tif (v.label === label) return v.color\n\t\t\t}\n\t\t}\n\t\tconst bin = bins?.find(bin => bin.label == label)\n\t\tif (bin?.color) return bin.color\n\n\t\tif (t.term.type == 'geneVariant' && t.q.type == 'values') return this.getMutationColor(label)\n\t\treturn rgb(chart.colorScale(label)).toString()\n\t}\n\n\t// should move this outside of setTerm2Color(),\n\t// otherwise it will get *** recreated on every call *** to setTerm2Color()\n\tgetMutationColor(label) {\n\t\t// for (const [key, mc] of Object.entries(mclass)) if (mc.label == label) return mc.color\n\n\t\t// key is not used in loop above, can do this instead\n\t\tfor (const mc of Object.values(mclass)) if (mc.label === label && mc.color) return mc.color\n\n\t\t// can loop on the object directly\n\t\tfor (const key in mclass) {\n\t\t\tif (mclass[key].label === label && mclass[key].color) return mclass[key].color\n\t\t}\n\t}\n\n\t/*\n\t when term1 or term2 is a geneVariant term, return legendGrps: \n\t\t[ \n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tname: \"...\", \n\t\t\t\t\titems: [...]\n\t\t\t\t},\n\t\t\t\t...\n\t\t\t],\n\t\t\t... \n\t\t]\n\t*/\n\tgetLegendGrps() {\n\t\tconst t1 = this.config.term\n\t\tconst t2 = this.config.term2\n\t\tif (\n\t\t\t(t1.term.type == 'geneVariant' && t1.q.type == 'values') ||\n\t\t\t(t2?.term.type == 'geneVariant' && t2?.q.type == 'values')\n\t\t) {\n\t\t\tconst legendGrps = []\n\t\t\tfor (const chart of this.chartsData.charts) {\n\t\t\t\tlegendGrps.push(this.getOneLegendGrps(chart))\n\t\t\t}\n\t\t\treturn legendGrps\n\t\t}\n\t\treturn this.getOneLegendGrps()\n\t}\n\n\t//Used by getLegendGrps to get one legendGrps\n\tgetOneLegendGrps(chart) {\n\t\tconst legendGrps = []\n\t\tconst s = this.settings\n\t\tconst t1 = this.config.term\n\t\tconst t2 = this.config.term2\n\t\t// changed color from #aaa to address Section 508 contrast issue\n\t\tconst headingStyle = 'color: #555; font-weight: 400'\n\n\t\t// descriptive statistics\n\t\tif (t1.q.descrStats && s.showStats) {\n\t\t\t// term1 has descriptive stats\n\t\t\tconst items = Object.values(t1.q.descrStats).map(stat => {\n\t\t\t\treturn {\n\t\t\t\t\ttext: `${stat.label}: ${stat.value}`,\n\t\t\t\t\tnoIcon: true\n\t\t\t\t}\n\t\t\t})\n\t\t\t// title of descriptive stats should include the term1 name if term2 is present\n\t\t\tconst title = t2 ? `Descriptive statistics: ${t1.term.name}` : 'Descriptive statistics'\n\t\t\tconst name = `<span style=\"${headingStyle}\">${title}</span>`\n\t\t\tlegendGrps.push({ name, items })\n\t\t}\n\t\tif (t2?.q.descrStats && s.showAssociationTests) {\n\t\t\t// term2 has descriptive stats\n\t\t\tconst items = Object.values(t2.q.descrStats).map(stat => {\n\t\t\t\treturn {\n\t\t\t\t\ttext: `${stat.label}: ${stat.value}`,\n\t\t\t\t\tnoIcon: true\n\t\t\t\t}\n\t\t\t})\n\t\t\t// title of descriptive stats will include the term2 name\n\t\t\t// because two terms are present\n\t\t\tconst title = `Descriptive statistics: ${t2.term.name}`\n\t\t\tconst name = `<span style=\"${headingStyle}\">${title}</span>`\n\t\t\tlegendGrps.push({ name, items })\n\t\t}\n\n\t\tif (s.cols && s.exclude.cols.length) {\n\t\t\tconst reducer = (sum, b) => sum + b.total\n\t\t\tconst items = s.exclude.cols\n\t\t\t\t.filter(collabel => s.cols.includes(collabel)) // && (!t1.term.values || collabel in t1.term.values))\n\t\t\t\t.flatMap(collabel => {\n\t\t\t\t\tconst filter = c => c.seriesId == collabel\n\t\t\t\t\tconst total =\n\t\t\t\t\t\tt2?.term?.type == 'condition'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: (t1.term.type == 'geneVariant' && t1.q.type == 'values') ||\n\t\t\t\t\t\t\t (t2?.term.type == 'geneVariant' && t2?.q.type == 'values')\n\t\t\t\t\t\t\t? chart.serieses.filter(filter).reduce(reducer, 0)\n\t\t\t\t\t\t\t: this.currServerData.charts.reduce((sum, chart) => {\n\t\t\t\t\t\t\t\t\treturn sum + chart.serieses.filter(filter).reduce(reducer, 0)\n\t\t\t\t\t\t\t }, 0)\n\t\t\t\t\tif (!total && !t2?.term?.type) return []\n\t\t\t\t\tconst label = t1.term.values && collabel in t1.term.values ? t1.term.values[collabel].label : collabel\n\t\t\t\t\tconst ntotal = total ? ', n=' + total : ''\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: collabel,\n\t\t\t\t\t\t\ttext: label + ntotal,\n\t\t\t\t\t\t\tcolor: '#fff',\n\t\t\t\t\t\t\ttextColor: '#000',\n\t\t\t\t\t\t\tborder: '1px solid #333',\n\t\t\t\t\t\t\t//inset: total ? \"n=\"+total : '',\n\t\t\t\t\t\t\tnoIcon: true,\n\t\t\t\t\t\t\ttype: 'col',\n\t\t\t\t\t\t\tisHidden: true,\n\t\t\t\t\t\t\thiddenOpacity: 1\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t\t.sort(this.barSorter)\n\n\t\t\tif (items.length) {\n\t\t\t\tconst name = t2 ? t1.term.name : 'Other categories'\n\t\t\t\tlegendGrps.push({\n\t\t\t\t\tname: `<span style=\"${headingStyle}\">${name}</span>`,\n\t\t\t\t\titems\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tconst showOverlayLegend = (t2 || this.hasMultiCategoryKeys) && Object.keys(this.term2toColor).length\n\t\tif (s.rows && !s.hidelegend && showOverlayLegend) {\n\t\t\tconst value_by_label =\n\t\t\t\t!t2 || t2.term.type != 'condition' || !t2.q\n\t\t\t\t\t? ''\n\t\t\t\t\t: t2.q.value_by_max_grade\n\t\t\t\t\t? 'max. grade'\n\t\t\t\t\t: t2.q.value_by_most_recent\n\t\t\t\t\t? 'most recent'\n\t\t\t\t\t: ''\n\t\t\tconst legendName =\n\t\t\t\tthis.hasMultiCategoryKeys && !t2 ? 'Category' : t2.term.type == 'geneVariant' ? '' : t2.term.name\n\t\t\tlegendGrps.push({\n\t\t\t\tname: `<span style=\"${headingStyle}\">` + legendName + (value_by_label ? ', ' + value_by_label : '') + '</span>',\n\t\t\t\titems: s.rows\n\t\t\t\t\t.flatMap(d => {\n\t\t\t\t\t\tconst total = chart ? this.totalsByDataId[d]?.[chart.chartId] : this.totalsByDataId[d]\n\t\t\t\t\t\tif (!total) return []\n\t\t\t\t\t\tconst ntotal = total ? ', n=' + total : ''\n\t\t\t\t\t\tconst label = this.getCategoryKeyLabel(t1, t2, d)\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdataId: d,\n\t\t\t\t\t\t\t\ttext: label + ntotal,\n\t\t\t\t\t\t\t\tcolor: this.term2toColor[d],\n\t\t\t\t\t\t\t\ttype: 'row',\n\t\t\t\t\t\t\t\tisHidden: s.exclude.rows.includes(d)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t})\n\t\t\t\t\t.sort(this.overlaySorter)\n\t\t\t})\n\t\t}\n\t\tif (t2 && this.state.multipleTestingCorrection) {\n\t\t\t// the dataset requires multiple testing correction and therefore needs to show this legend of Statistical Significance\n\t\t\t// calculate total number of unskipped tests\n\t\t\tlet testNum = 0\n\t\t\tfor (const chartId in this.chartsData.tests) {\n\t\t\t\ttestNum += this.chartsData.tests[chartId].reduce((a, b) => a + b.term2tests.filter(a => !a.skipped).length, 0)\n\t\t\t}\n\t\t\tconst items =\n\t\t\t\ttestNum > 1 && this.state.config.settings.barchart.multiTestingCorr\n\t\t\t\t\t? [{ text: `* p-value < (0.05 / ${testNum} tests)`, noEditColor: true }]\n\t\t\t\t\t: [{ text: `* p-value < 0.05`, noEditColor: true }]\n\t\t\tlegendGrps.push({\n\t\t\t\tname: `<span style=\"${headingStyle}\"> </span>`,\n\t\t\t\titems\n\t\t\t})\n\t\t}\n\n\t\treturn legendGrps\n\t}\n\n\t// helper so that 'Loading...' does not flash when not needed\n\ttoggleLoadingDiv(display = '') {\n\t\tif (display != 'none') {\n\t\t\tthis.dom.loadingDiv\n\t\t\t\t.style('opacity', 0)\n\t\t\t\t.style('display', display)\n\t\t\t\t.transition()\n\t\t\t\t.duration('loadingWait' in this ? this.loadingWait : 0)\n\t\t\t\t.style('opacity', 1)\n\t\t} else {\n\t\t\tthis.dom.loadingDiv.style('display', display)\n\t\t}\n\t\t// do not transition on initial chart load\n\t\tthis.loadingWait = 1000\n\t}\n}\n\nexport const barInit = getCompInit(Barchart)\n// this alias will allow abstracted dynamic imports\nexport const componentInit = barInit\n\nfunction setRenderers(self) {\n\tself.render = function () {\n\t\tconst charts = self.dom.barDiv.selectAll('.pp-sbar-div').data(self.visibleCharts, chart => chart.chartId)\n\n\t\tcharts.exit().each(self.exitChart)\n\t\tcharts.each(self.updateChart)\n\t\tcharts.enter().append('div').each(self.addChart)\n\n\t\tself.dom.holder.selectAll('.pp-chart-title').style('display', self.visibleCharts.length < 2 ? 'none' : 'block')\n\t\tconst grps = self.getLegendGrps()\n\t\tself.legendRenderer(grps)\n\n\t\tif (!self.visibleCharts.length) {\n\t\t\tconst clickLegendMessage =\n\t\t\t\tself.settings.exclude.cols.length || self.settings.exclude.rows.length\n\t\t\t\t\t? `<br/><span>click on a legend label below to display the barchart</span>`\n\t\t\t\t\t: ''\n\t\t\tself.dom.banner\n\t\t\t\t.html(`<span>No visible barchart data to render</span>${clickLegendMessage}`)\n\t\t\t\t.style('display', 'block')\n\t\t\tself.dom.legendDiv.selectAll('*').remove()\n\t\t} else {\n\t\t\tself.dom.banner.text('').style('display', 'none')\n\t\t}\n\t}\n\n\tself.exitChart = function (chart) {\n\t\tdelete self.renderers[chart.chartId]\n\t\tselect(this).remove()\n\t}\n\n\tself.updateChart = function (chart) {\n\t\t// this.dom.legendDiv.remove(\"*\")\n\t\tchart.settings.cols.sort(self.barSorter)\n\t\tchart.maxAcrossCharts = self.chartsData.maxAcrossCharts\n\t\tchart.handlers = self.handlers\n\t\tchart.maxSeriesLogTotal = 0\n\t\tchart.visibleSerieses.forEach(series => self.sortStacking(series, chart, self.chartsData))\n\t\tself.renderers[chart.chartId] = barsRenderer(self, select(this)) //rerender as settings may have changed\n\t\tself.renderers[chart.chartId](chart)\n\n\t\tconst div = select(this)\n\t\tdiv.style('display', 'inline-block')\n\t\tdiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'pp-sbar-div-chartLengends')\n\t\t\t.attr('data-testid', 'sjpcb-bars-chartLengends')\n\t\t\t.style('vertical-align', 'top')\n\t\t\t.style('margin', '10px 10px 10px 30px')\n\t\t\t.style('display', 'none')\n\t\tif (\n\t\t\tself.chartsData.tests &&\n\t\t\tself.chartsData.tests[chart.chartId] &&\n\t\t\tself.config.settings.barchart.showAssociationTests\n\t\t) {\n\t\t\t//chart has pvalues\n\t\t\tgeneratePvalueTable(chart, div)\n\t\t}\n\t}\n\n\tself.addChart = function (chart, i) {\n\t\tconst div = select(this)\n\t\t\t.attr('class', 'pp-sbar-div')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('padding', '20px')\n\t\t\t.style('vertical-align', 'top')\n\t\tself.renderers[chart.chartId] = barsRenderer(self, select(this))\n\t\t//self.updateChart.call(this, chart)\n\t\tchart.settings.cols.sort(self.barSorter)\n\t\tchart.maxAcrossCharts = self.chartsData.maxAcrossCharts\n\t\tchart.handlers = self.handlers\n\t\tchart.maxSeriesLogTotal = 0\n\t\tchart.visibleSerieses.forEach(series => self.sortStacking(series, chart, self.chartsData))\n\t\tself.renderers[chart.chartId](chart)\n\n\t\t// div for chart-specific legends\n\t\tdiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'pp-sbar-div-chartLengends')\n\t\t\t.attr('data-testid', 'sjpcb-bars-chartLengends')\n\t\t\t.style('vertical-align', 'top')\n\t\t\t.style('margin', '10px 10px 10px 30px')\n\t\t\t.style('display', 'none')\n\t\tif (\n\t\t\tself.chartsData.tests &&\n\t\t\tself.chartsData.tests[chart.chartId] &&\n\t\t\tself.config.settings.barchart.showAssociationTests\n\t\t) {\n\t\t\t//chart has pvalues\n\t\t\tgeneratePvalueTable(chart, div)\n\t\t}\n\t}\n\n\t/*\n\tA function to generate a p-value table for Chi-squared/Fisher's exact tests\n\t*/\n\tfunction generatePvalueTable(chart, div) {\n\t\tconst holder = div\n\t\t\t.select('.pp-sbar-div-chartLengends')\n\t\t\t.style('display', 'inline-block')\n\t\t\t.style('vertical-align', 'top')\n\t\t\t.style('text-align', 'center')\n\t\t\t.append('div')\n\t\t// sort term1 categories based on self.chartsData.refs.cols\n\t\t// const cols = self.settings.dedup ? self.chartsData.refs.cols\n\t\tself.chartsData.tests[chart.chartId].sort(function (a, b) {\n\t\t\treturn self.settings.cols.indexOf(a.term1comparison) - self.settings.cols.indexOf(b.term1comparison)\n\t\t})\n\n\t\t// sort term2 categories based on self.chartsData.refs.rows\n\t\tfor (const t1c of self.chartsData.tests[chart.chartId]) {\n\t\t\tt1c.term2tests.sort(function (a, b) {\n\t\t\t\treturn self.chartsData.refs.rows.indexOf(a.term2id) - self.chartsData.refs.rows.indexOf(b.term2id)\n\t\t\t})\n\t\t}\n\t\tconst columns = [\n\t\t\t{ label: 'Row 1' },\n\t\t\t{ label: 'Row 2' },\n\t\t\t{ label: 'Column 1' },\n\t\t\t{ label: 'Column 2' },\n\t\t\t{ label: 'P-value' }\n\t\t]\n\t\tconst noSkipped = self.chartsData.tests[chart.chartId].every(term1 =>\n\t\t\tterm1.term2tests.every(term2 => !term2.skipped)\n\t\t)\n\t\tconst rows = []\n\n\t\tconst visibleTests = self.chartsData.tests[chart.chartId].filter(term1Data =>\n\t\t\tchart.visibleSerieses.some(visibleTerm1 => visibleTerm1.seriesId === term1Data.term1comparison)\n\t\t)\n\t\tfor (const [index, term1] of visibleTests.entries()) {\n\t\t\tif (visibleTests.length == 2 && index == 1) {\n\t\t\t\t// when term1 has only 2 categories, then only a single category needs to be tested in the\n\t\t\t\t// association test (because the other category will get tested in that same test).\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst visibleTerm1Data = chart.visibleSerieses.find(\n\t\t\t\tvisibleTerm1 => visibleTerm1.seriesId === term1.term1comparison\n\t\t\t)\n\t\t\tconst visibleTerm2Data = term1.term2tests.filter(term2Data =>\n\t\t\t\tvisibleTerm1Data.visibleData.some(visibleTerm2 => visibleTerm2.dataId === term2Data.term2id)\n\t\t\t)\n\t\t\tfor (const [index2, term2] of visibleTerm2Data.entries()) {\n\t\t\t\tif (chart.settings.rows.length - chart.settings.exclude.rows.length == 2 && index2 == 1) {\n\t\t\t\t\t// when term2 has only 2 visible categories, then only a single category needs to be tested in the\n\t\t\t\t\t// association test (because the other category will get tested in that same test).\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlet negateTerm2Label = negateTermLabel(term2.term2Label)\n\t\t\t\tif (chart.settings.rows.length - chart.settings.exclude.rows.length == 2) {\n\t\t\t\t\t// when term2 has only 2 visible categories, Col2 would be the other category instead of \"not Col1\"\n\t\t\t\t\tconst visibleTerm2CatsKeys = chart.settings.rows.filter(row => !chart.settings.exclude.rows.includes(row))\n\t\t\t\t\tconst visibleTerm2Labels = visibleTerm2CatsKeys\n\t\t\t\t\t\t.map(catK => self.config.term2?.term?.values?.[catK]?.label)\n\t\t\t\t\t\t.filter(x => x != undefined)\n\t\t\t\t\tif (visibleTerm2Labels?.length == 2)\n\t\t\t\t\t\tnegateTerm2Label = visibleTerm2Labels[0] == term2.term2Label ? visibleTerm2Labels[1] : visibleTerm2Labels[0]\n\t\t\t\t}\n\n\t\t\t\trows.push([\n\t\t\t\t\t{ value: `${term1.term1Label}` },\n\t\t\t\t\t// when term1 has only 2 categories, Row2 would be the other category instead of \"not Row1\"\n\t\t\t\t\t{ value: visibleTests.length == 2 ? visibleTests[1].term1Label : negateTermLabel(term1.term1Label) },\n\t\t\t\t\t{ value: term2.term2Label },\n\t\t\t\t\t{ value: negateTerm2Label },\n\t\t\t\t\t//if both chi-square and Fisher's exact tests were used. for the tests computed by Fisher's exact test, add a superscript letter 'a' after the pvalue.\n\t\t\t\t\t{\n\t\t\t\t\t\thtml: term2.skipped\n\t\t\t\t\t\t\t? 'N/A'\n\t\t\t\t\t\t\t: term2.pvalue > 1e-4\n\t\t\t\t\t\t\t? roundValueAuto(Number(term2.pvalue))\n\t\t\t\t\t\t\t: roundValueAuto(Number(term2.pvalue))\n\t\t\t\t\t}\n\t\t\t\t])\n\t\t\t}\n\t\t}\n\t\t//adding a title for the pvalue table\n\t\t//title is \"Group comparisons (Fisher's exact test)\" if all tests are Fisher's exact test, otherwise title is 'Group comparisons (Chi-square test)'\n\t\tconst title = holder\n\t\t\t.append('div')\n\t\t\t.style('font-weight', 'bold')\n\t\t\t.style('padding-bottom', '0.5em')\n\t\t\t.attr('data-testid', 'sjpp-massbarchart-2x2assotestlabel')\n\t\t\t.html(\"2x2 Association test (Fisher's exact test)\")\n\t\t\t.style('font-size', '0.9em')\n\n\t\tconst table = holder.append('div').style('font-size', '0.9em')\n\t\trenderTable({\n\t\t\tcolumns,\n\t\t\trows,\n\t\t\tdiv: table,\n\t\t\tshowLines: false,\n\t\t\tmaxWidth: '70vw',\n\t\t\tmaxHeight: `${chart.svgh - 100}px`,\n\t\t\tresize: true\n\t\t})\n\n\t\t//footnote: superscript letter 'a' indicates the pvalue was computed by Fisher's exact test\n\t\ttable\n\t\t\t.append('div')\n\t\t\t.style('margin-top', '10px')\n\t\t\t.style('text-align', 'left')\n\t\t\t.style('font-size', '10px')\n\t\t\t.style('font-weight', 'normal')\n\t\t\t.html(noSkipped ? '' : 'N/A: association test skipped because of limited sample size <br>')\n\t}\n}\n\nfunction setInteractivity(self) {\n\tself.handlers = getHandlers(self)\n\n\tself.getChartImages = function () {\n\t\tconst charts = []\n\n\t\tfor (const chart of self.charts) {\n\t\t\tconst name = `${this.config.term.term.name} ${chart.name ? chart.name : ''}`\n\t\t\tcharts.push({ name, svg: chart.svg })\n\t\t}\n\t\treturn charts\n\t}\n\n\tself.download = function (event) {\n\t\tconst charts = self.getChartImages()\n\t\tconst dm = new DownloadMenu(charts, self.config.term.term.name)\n\t\tdm.show(event.clientX, event.clientY, event.target)\n\t}\n\n\t/** Downloads all charts as a single svg image, including the legend for each barchart, needs review as it\n\t * has some glitches. The legend rendering may be moved to the same svg and then it will be included in the download or a callback may be provided\n\t * to the downloadMenu to use this download when generating a single svg, once it works well\n\t */\n\t// self.download = function () {\n\t// \tif (!self.state) return\n\t// \t// has to be able to handle multichart view\n\t// \tconst mainGs = []\n\t// \tconst translate = { x: undefined, y: undefined }\n\t// \tconst titles = []\n\t// \tlet maxw = 0,\n\t// \t\tmaxh = 0,\n\t// \t\ttboxh = 0\n\t// \tlet prevY = 0,\n\t// \t\tnumChartsPerRow = 0\n\n\t// \tself.dom.barDiv.selectAll('.sjpcb-bars-mainG').each(function () {\n\t// \t\tmainGs.push(this)\n\t// \t\tconst bbox = this.getBBox()\n\t// \t\tif (bbox.width > maxw) maxw = bbox.width\n\t// \t\tif (bbox.height > maxh) maxh = bbox.height\n\t// \t\tconst divY = Math.round(this.parentNode.parentNode.getBoundingClientRect().y)\n\t// \t\tif (!numChartsPerRow) {\n\t// \t\t\tprevY = divY\n\t// \t\t\tnumChartsPerRow++\n\t// \t\t} else if (Math.abs(divY - prevY) < 5) {\n\t// \t\t\tnumChartsPerRow++\n\t// \t\t}\n\t// \t\tconst xy = select(this)\n\t// \t\t\t.attr('transform')\n\t// \t\t\t.split('translate(')[1]\n\t// \t\t\t.split(')')[0]\n\t// \t\t\t.split(',')\n\t// \t\t\t.map(d => +d.trim())\n\t// \t\tif (translate.x === undefined || xy[0] > translate.x) translate.x = +xy[0]\n\t// \t\tif (translate.y === undefined || xy[1] > translate.y) translate.y = +xy[1]\n\n\t// \t\tconst title = this.parentNode.parentNode.firstChild\n\t// \t\tconst tbox = title.getBoundingClientRect()\n\t// \t\tif (tbox.width > maxw) maxw = tbox.width\n\t// \t\tif (tbox.height > tboxh) tboxh = tbox.height\n\t// \t\ttitles.push({ text: title.innerText, styles: window.getComputedStyle(title) })\n\t// \t})\n\n\t// \t// add padding between charts\n\t// \tmaxw += 30\n\t// \tmaxh += 30\n\n\t// \tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\n\t// \tconst svgSel = select(svg)\n\t// \t\t.style('display', 'block')\n\t// \t\t.style('opacity', 1)\n\t// \t\t.attr('width', numChartsPerRow * maxw)\n\t// \t\t.attr('height', Math.floor(mainGs.length / numChartsPerRow) * maxh)\n\n\t// \tconst svgStyles = window.getComputedStyle(document.querySelector('.pp-bars-svg'))\n\t// \tfor (const prop of svgStyles) {\n\t// \t\tif (prop.startsWith('font')) svgSel.style(prop, svgStyles.getPropertyValue(prop))\n\t// \t}\n\n\t// \tmainGs.forEach((g, i) => {\n\t// \t\tconst mainG = g.cloneNode(true)\n\t// \t\tconst colNum = i % numChartsPerRow\n\t// \t\tconst rowNum = Math.floor(i / numChartsPerRow)\n\t// \t\tconst corner = { x: colNum * maxw + translate.x, y: rowNum * maxh + translate.y }\n\t// \t\tconst title = select(svg)\n\t// \t\t\t.append('text')\n\t// \t\t\t.attr('transform', 'translate(' + corner.x + ',' + corner.y + ')')\n\t// \t\t\t.text(titles[i].text)\n\t// \t\tfor (const prop of titles[i].styles) {\n\t// \t\t\tif (prop.startsWith('font')) title.style(prop, titles[i].styles.getPropertyValue(prop))\n\t// \t\t}\n\n\t// \t\tselect(mainG).attr('transform', 'translate(' + corner.x + ',' + (corner.y + tboxh) + ')')\n\t// \t\tsvg.appendChild(mainG)\n\t// \t})\n\n\t// \t// svg + legend must be attached to DOM in order for getBBox() to work within svgLegendRenderer\n\t// \tconst hiddenDiv = select('body').append('div').style('opacity', 0)\n\t// \thiddenDiv.node().appendChild(svg)\n\n\t// \tself.svgLegendRenderer = svgLegend({\n\t// \t\tholder: svgSel.append('g'),\n\t// \t\trectFillFxn: d => d.color,\n\t// \t\ticonStroke: '#aaa'\n\t// \t})\n\n\t// \tconst s = self.settings\n\t// \tconst svg0 = self.dom.barDiv.select('svg').node().getBoundingClientRect()\n\t// \tlet data = self.getLegendGrps()\n\t// \tdata.forEach(d => {\n\t// \t\td.name = d.name.replace(/<[^>]*>?/gm, '')\n\t// \t\tif (d.items) d.items = d.items.filter(c => !c.isHidden)\n\t// \t})\n\t// \tdata = data.filter(d => d.items.length && !d.name.includes('tatistic'))\n\t// \tconst fontsize = 14\n\t// \tself.svgLegendRenderer(data, {\n\t// \t\tsettings: Object.assign(\n\t// \t\t\t{\n\t// \t\t\t\tontop: false,\n\t// \t\t\t\tlineh: 25,\n\t// \t\t\t\tpadx: 5,\n\t// \t\t\t\tpadleft: 0, //150,\n\t// \t\t\t\tpadright: 20,\n\t// \t\t\t\tpadbtm: 30,\n\t// \t\t\t\tfontsize,\n\t// \t\t\t\ticonh: fontsize - 2,\n\t// \t\t\t\ticonw: fontsize - 2,\n\t// \t\t\t\thangleft: 1,\n\t// \t\t\t\tlinesep: false\n\t// \t\t\t},\n\t// \t\t\t{\n\t// \t\t\t\tsvgw: self.visibleCharts.length * svg0.width,\n\t// \t\t\t\tsvgh: svg0.height,\n\t// \t\t\t\tdimensions: {\n\t// \t\t\t\t\txOffset: 50\n\t// \t\t\t\t},\n\t// \t\t\t\tpadleft: 50\n\t// \t\t\t}\n\t// \t\t)\n\t// \t})\n\n\t// \tconst box = self.dom.legendDiv.node().getBoundingClientRect()\n\t// \tselect(svg).attr('height', svg0.height + box.height + 30)\n\t// \tif (box.width > svg0.width) select(svg).attr('width', box.width)\n\t// \thiddenDiv.remove()\n\n\t// \tconst svg_name = self.config.term.term.name + ' barchart'\n\t// \tto_svg(svg, svg_name, { apply_dom_styles: true })\n\t// }\n}\n\nexport function getDefaultBarSettings(app) {\n\treturn {\n\t\tbarspace: 2,\n\t\tbarwidth: 20,\n\t\tplotLength,\n\t\torientation: 'horizontal',\n\t\tunit: 'abs',\n\t\toverlay: 'none',\n\t\tdivideBy: 'none',\n\t\trowlabelw: 250,\n\t\tasterisksVisible: app?.getState()?.termdbConfig?.multipleTestingCorrection ? true : false,\n\t\tmultiTestingCorr: app?.getState()?.termdbConfig?.multipleTestingCorrection?.applyByDefault ? true : false,\n\t\tdefaultColor: plotColor,\n\t\tcolorBars: false,\n\t\tcolorUsing: 'all',\n\t\tdedup: false,\n\t\tshowStats: true,\n\t\tshowAssociationTests: true,\n\t\tshowPercent: false\n\t}\n}\n\nexport async function getPlotConfig(opts, app) {\n\tif (!opts.term) throw 'barchart getPlotConfig: opts.term{} missing'\n\ttry {\n\t\topts.tw = await fillTermWrapper(opts.term, app.vocabApi)\n\t\tif (opts.term2) opts.term2 = await fillTermWrapper(opts.term2, app.vocabApi)\n\t\tif (opts.term0) opts.term0 = await fillTermWrapper(opts.term0, app.vocabApi)\n\t} catch (e) {\n\t\tconsole.log('Error reading config: ' + JSON.stringify(opts))\n\t\tconsole.error(e)\n\t\tthrow `${e} [barchart getPlotConfig()]`\n\t}\n\n\tconst config = {\n\t\tid: opts.term.term.id,\n\t\tcontrolLabels: Object.assign({}, defaultUiLabels, app.vocabApi.termdbConfig.uiLabels || {}),\n\t\tsettings: {\n\t\t\tcontrols: {\n\t\t\t\tterm2: null, // the previous overlay value may be displayed as a convenience for toggling\n\t\t\t\tterm0: null\n\t\t\t},\n\t\t\tcommon: {\n\t\t\t\tuse_logscale: false, // flag for y-axis scale type, 0=linear, 1=log\n\t\t\t\tuse_percentage: false\n\t\t\t\t// Moved to barchart settings\n\t\t\t\t// barheight: 300, // maximum bar length\n\t\t\t\t// barwidth: 20, // bar thickness\n\t\t\t\t// barspace: 2 // space between two bars\n\t\t\t},\n\t\t\tbarchart: getDefaultBarSettings(app)\n\t\t}\n\t}\n\n\t// may apply term-specific changes to the default object\n\treturn copyMerge(config, opts)\n}\n\n// a function used by generatePvalueTable to negate a term label\n// TODO: add more conditions for better negation than \"not termLable\"\nexport function negateTermLabel(termLabel) {\n\tconst termLabelStr = String(termLabel)\n\tif (termLabelStr.toUpperCase().startsWith('NOT ')) {\n\t\treturn termLabelStr.substring(4) // Remove the \"not\" prefix\n\t} else {\n\t\treturn 'not ' + termLabelStr // Otherwise, add \"not\" prefix\n\t}\n}\n", "import { Menu, renderTable } from '#dom'\nimport { dofetch3 } from '../common/dofetch'\nimport { mclass, dt2label } from '#shared/common.js'\nimport { newpane, export_data } from '../src/client'\nimport { filterJoin, getFilterItemByTag, getNormalRoot, findItemByTermId, normalizeProps } from '#filter'\nimport { rgb } from 'd3-color'\nimport { create } from 'd3-selection'\nimport { roundValueAuto } from '#shared/roundValue.js'\nimport { isNumericTerm } from '#shared/terms.js'\nimport { negateTermLabel } from './barchart'\nimport { getSamplelstFilter, getSamplelstTW, getFilter, addNewGroup } from '../mass/groups.js'\n\nexport default function getHandlers(self) {\n\tconst tip = new Menu({ padding: '5px' })\n\tself.dom.tip = tip\n\tconst s = self.settings\n\n\treturn {\n\t\tchart: {\n\t\t\ttitle(chart) {\n\t\t\t\tif (!self.config.term0) return chart.chartId\n\t\t\t\treturn self.config.term0.term.values && chart.chartId in self.config.term0.term.values\n\t\t\t\t\t? self.config.term0.term.values[chart.chartId].label\n\t\t\t\t\t: chart.chartId\n\t\t\t}\n\t\t},\n\t\tsvg: {\n\t\t\tmouseout: () => {\n\t\t\t\ttip.hide()\n\t\t\t}\n\t\t},\n\t\tseries: {\n\t\t\tmouseover(event, d) {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tconst hasOverlay = self.config.term2 || self.hasMultiCategoryKeys\n\t\t\t\tlet percent = hasOverlay ? (d.total / d.seriesTotal) * 100 : (d.seriesTotal / d.chartTotal) * 100\n\t\t\t\tpercent = percent.toFixed(1)\n\t\t\t\tconst t1 = self.config.term.term\n\t\t\t\tconst t2 = self.config.term2 && self.config.term2.term\n\t\t\t\tconst term1unit = t1.unit\n\t\t\t\tconst seriesLabel =\n\t\t\t\t\t(t1.values && d.seriesId in t1.values ? t1.values[d.seriesId].label : d.seriesId) +\n\t\t\t\t\t(t1.unit ? ' ' + t1.unit : '')\n\t\t\t\tlet dataLabel\n\t\t\t\tif (t2) {\n\t\t\t\t\tdataLabel =\n\t\t\t\t\t\t(t2.values && d.dataId in t2.values ? t2.values[d.dataId].label : d.dataId) + (t2.unit ? ' ' + t2.unit : '')\n\t\t\t\t} else if (self.hasMultiCategoryKeys) {\n\t\t\t\t\tdataLabel = self.getCategoryKeyLabel(self.config.term, null, d.dataId)\n\t\t\t\t} else {\n\t\t\t\t\tdataLabel = d.dataId\n\t\t\t\t}\n\t\t\t\tconst icon = !hasOverlay\n\t\t\t\t\t? ''\n\t\t\t\t\t: \"<div style='display:inline-block; width:14px; height:14px; margin: 2px 3px; vertical-align:top; background:\" +\n\t\t\t\t\t d.color +\n\t\t\t\t\t \"'> </div>\"\n\t\t\t\tconst rows = [`<tr><td colspan=2 style='padding:3px; text-align:center'>${seriesLabel}</td></tr>`]\n\t\t\t\tif (hasOverlay) {\n\t\t\t\t\trows.push(\n\t\t\t\t\t\t`<tr><td colspan=2 style='padding:3px; text-align:center'>${icon} <span>${dataLabel}</span></td></tr>`\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tconst uiLabels = self.config.controlLabels || self.app.vocabApi.termdbConfig.uiLabels\n\t\t\t\trows.push(\n\t\t\t\t\t`<tr><td style='padding:3px; color:#aaa'>#${\n\t\t\t\t\t\tuiLabels.Samples || 'Individuals'\n\t\t\t\t\t}</td><td style='padding:3px; text-align:center'>${d.total}</td></tr>`,\n\t\t\t\t\t`<tr><td style='padding:3px; color:#aaa'>percent</td><td style='padding:3px; text-align:center'>${percent}%</td></tr>`\n\t\t\t\t)\n\n\t\t\t\t//mouse-over p-value and 2x2 table\n\t\t\t\tif (t2) {\n\t\t\t\t\tconst pvalue = d.groupPvalues?.term2tests?.find(x => x.term2id === d.dataId).pvalue\n\t\t\t\t\tconst term1Label = d.groupPvalues.term1Label\n\t\t\t\t\tconst term2Label = d.groupPvalues.term2tests.find(x => x.term2id === d.dataId).term2Label\n\t\t\t\t\tconst tableValues = d.groupPvalues.term2tests.find(x => x.term2id === d.dataId).tableValues\n\t\t\t\t\tconst skipped = d.groupPvalues.term2tests.find(x => x.term2id === d.dataId).skipped\n\n\t\t\t\t\t// when term1 has only 2 categories, Row2 would be the other category instead of \"not Row1\"\n\t\t\t\t\tconst negateTerm1Label = !(\n\t\t\t\t\t\tself.settings.cols.length - self.settings.exclude.cols.length == 2 &&\n\t\t\t\t\t\tself.chartsData.tests[d.chartId].length == 2\n\t\t\t\t\t)\n\t\t\t\t\t\t? negateTermLabel(term1Label)\n\t\t\t\t\t\t: self.chartsData.tests[d.chartId][0].term1Label == term1Label\n\t\t\t\t\t\t? self.chartsData.tests[d.chartId][1].term1Label\n\t\t\t\t\t\t: self.chartsData.tests[d.chartId][0].term1Label\n\n\t\t\t\t\tlet negateTerm2Label = negateTermLabel(term2Label)\n\t\t\t\t\tif (self.settings.rows.length - self.settings.exclude.rows.length == 2) {\n\t\t\t\t\t\t// when term2 has only 2 visible categories, Col2 would be the other category instead of \"not Col1\"\n\t\t\t\t\t\tconst visibleTerm2CatsKeys = self.settings.rows.filter(row => !self.settings.exclude.rows.includes(row))\n\t\t\t\t\t\tconst visibleTerm2Labels = visibleTerm2CatsKeys\n\t\t\t\t\t\t\t.map(catK => self.config.term2?.term?.values?.[catK]?.label)\n\t\t\t\t\t\t\t.filter(x => x != undefined)\n\t\t\t\t\t\tif (visibleTerm2Labels?.length == 2)\n\t\t\t\t\t\t\tnegateTerm2Label = visibleTerm2Labels[0] == term2Label ? visibleTerm2Labels[1] : visibleTerm2Labels[0]\n\t\t\t\t\t}\n\n\t\t\t\t\t//Only show the p-value and 2x2 table in tooltip\n\t\t\t\t\t//when the user enabled association tests\n\t\t\t\t\t//from control panel\n\t\t\t\t\tif (self.settings.showAssociationTests) {\n\t\t\t\t\t\trows.push(\n\t\t\t\t\t\t\t`<tr>\n\t\t\t\t\t\t\t<td style='padding:3px; color:#aaa'>p-value</td>\n\t\t\t\t\t\t\t<td style='padding:3px; text-align:center'>${\n\t\t\t\t\t\t\t\tskipped ? 'N/A' : pvalue > 1e-4 ? Number(pvalue.toFixed(4)) : roundValueAuto(Number(pvalue))\n\t\t\t\t\t\t\t}</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<table style=\"margin: 5px; text-align:left; font-size: 0.8em; border-spacing: 5px; border-collapse: separate;\"\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td style='color:#aaa'></td>\n\t\t\t\t\t\t\t\t<td style='color:#aaa'>${term2Label}</td>\n\t\t\t\t\t\t\t\t<td style='color:#aaa'>${negateTerm2Label}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td style='color:#aaa'>${term1Label}</td>\n\t\t\t\t\t\t\t\t<td>${tableValues.R1C1}</td>\n\t\t\t\t\t\t\t\t<td>${tableValues.R1C2}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td style='color:#aaa'>${negateTerm1Label}</td>\n\t\t\t\t\t\t\t\t<td>${tableValues.R2C1}</td>\n\t\t\t\t\t\t\t\t<td>${tableValues.R2C2}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</table>`\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!t1.type == 'condition' && (!t2 || !t2.type == 'condition')) {\n\t\t\t\t\trows.push(\n\t\t\t\t\t\t`<tr><td style='padding:3px; color:#aaa'>Percentage</td><td style='padding:3px; text-align:center'>${(\n\t\t\t\t\t\t\t(100 * d.total) /\n\t\t\t\t\t\t\t(t2 ? d.seriesTotal : d.chartTotal)\n\t\t\t\t\t\t).toFixed(1)}%</td></tr>`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\ttip.show(event.clientX, event.clientY).d.html(`<table class='sja_simpletable'>${rows.join('\\n')}</table>`)\n\t\t\t},\n\t\t\tmouseout: () => {\n\t\t\t\ttip.hide()\n\t\t\t},\n\t\t\trectFill(d) {\n\t\t\t\treturn d.color\n\t\t\t},\n\t\t\tstrokeFill(d) {\n\t\t\t\tconst rgbColor = rgb(d.color)\n\t\t\t\tconst stroke = rgbColor.toString() == rgb('white').toString() ? rgbColor.darker() : rgbColor\n\t\t\t\treturn stroke\n\t\t\t},\n\t\t\tclick: self.opts.bar_click_override\n\t\t\t\t? (event, d) => self.opts.bar_click_override(getTermValues(d, self))\n\t\t\t\t: (event, d) => handle_click(event, self, d)\n\t\t},\n\t\tbarLabel: {\n\t\t\ttext: d => {\n\t\t\t\treturn 'label' in d\n\t\t\t\t\t? d.label\n\t\t\t\t\t: self.config.term.values && 'id' in d && d.id in self.config.term.values\n\t\t\t\t\t? self.config.term.values[d.id].label\n\t\t\t\t\t: d\n\t\t\t},\n\t\t\tclick: self.opts.bar_click_override\n\t\t\t\t? (event, d) => self.opts.bar_click_override(getTermValues(d, self))\n\t\t\t\t: (event, d) => handle_click(event, self, d),\n\t\t\tmouseover: event => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t},\n\t\t\tmouseout: () => {\n\t\t\t\ttip.hide()\n\t\t\t}\n\t\t},\n\t\tlegend: {\n\t\t\tonColorClick: e => handleLegendClick(e.target, self),\n\t\t\tclick: e => handleLegendClick(e.target, self),\n\t\t\tmouseover: event => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tconst d = event.target.__data__\n\t\t\t\tif (d === undefined) return\n\t\t\t\tif (d.isHidden) tip.show(event.clientX, event.clientY).d.html('Click to unhide bar')\n\t\t\t},\n\t\t\tmouseout: () => {\n\t\t\t\ttip.hide()\n\t\t\t}\n\t\t},\n\t\tyAxis: {\n\t\t\ttext: visibleTotal => {\n\t\t\t\tconst type = self.sampleType?.plural_name || 'samples'\n\t\t\t\tconst term = self.config.term\n\t\t\t\tif (s.orientation == 'vertical') {\n\t\t\t\t\t// Do not show the sum of serieses as (n=...) when serieses are 'Sub-condition', 'Most recent grade' or 'Any grade'\n\t\t\t\t\t// because a patient could have multiple 'Sub-condition', 'Most recent grade' or 'Any grade', and as a result could\n\t\t\t\t\t// be counted multiple times.\n\t\t\t\t\treturn s.unit == 'pct'\n\t\t\t\t\t\t? `% of ${type}`\n\t\t\t\t\t\t: `# of ${type} ` +\n\t\t\t\t\t\t\t\t(term.q.bar_by_children || term.q.value_by_most_recent || term.q.value_by_computable_grade\n\t\t\t\t\t\t\t\t\t? ''\n\t\t\t\t\t\t\t\t\t: `(n=${visibleTotal})`)\n\t\t\t\t} else {\n\t\t\t\t\treturn term.q.bar_by_children\n\t\t\t\t\t\t? 'Sub-condition'\n\t\t\t\t\t\t: term.q.value_by_max_grade\n\t\t\t\t\t\t? 'Maximum grade'\n\t\t\t\t\t\t: term.q.value_by_most_recent\n\t\t\t\t\t\t? 'Most recent grade'\n\t\t\t\t\t\t: term.q.value_by_computable_grade\n\t\t\t\t\t\t? 'Any grade'\n\t\t\t\t\t\t: term.type == 'categorical' || !term.unit\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: term.unit\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\txAxis: {\n\t\t\ttext: visibleTotal => {\n\t\t\t\tconst type = self.sampleType?.plural_name || 'samples'\n\t\t\t\tconst term = self.config.term\n\t\t\t\tif (s.orientation == 'vertical') {\n\t\t\t\t\treturn term.q.bar_by_children\n\t\t\t\t\t\t? 'Sub-condition'\n\t\t\t\t\t\t: term.q.value_by_max_grade\n\t\t\t\t\t\t? 'Maximum grade'\n\t\t\t\t\t\t: term.q.value_by_most_recent\n\t\t\t\t\t\t? 'Most recent grade'\n\t\t\t\t\t\t: term.q.value_by_computable_grade\n\t\t\t\t\t\t? 'Any grade'\n\t\t\t\t\t\t: term.type == 'categorical' || !term.unit\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: term.unit\n\t\t\t\t} else {\n\t\t\t\t\t// Do not show the sum of serieses as (n=...) when serieses are 'Sub-condition', 'Most recent grade' or 'Any grade'\n\t\t\t\t\t// because a patient could have multiple 'Sub-condition', 'Most recent grade' or 'Any grade', and as a result could\n\t\t\t\t\t// be counted multiple times.\n\t\t\t\t\treturn s.unit == 'pct'\n\t\t\t\t\t\t? `% of ${type}`\n\t\t\t\t\t\t: `# of ${type} ` +\n\t\t\t\t\t\t\t\t(term.q.bar_by_children || term.q.value_by_most_recent || term.q.value_by_computable_grade\n\t\t\t\t\t\t\t\t\t? ''\n\t\t\t\t\t\t\t\t\t: `(n=${visibleTotal})`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction handleColorClick(d, self, color) {\n\tconst termNum = d.type == 'col' ? 'term' : 'term2'\n\tconst term = self.config[termNum]\n\tlet dataId = d.dataId\n\tif (term.term.values && !term.term.values?.[dataId])\n\t\tfor (const [key, value] of Object.entries(term.term.values)) if (value.label == d.dataId) dataId = key\n\tif (term.term.values?.[dataId]) term.term.values[dataId].color = color\n\tif (term.term.type == 'geneVariant') {\n\t\tlet groupset\n\t\tif (term.q.type == 'predefined-groupset') {\n\t\t\tgroupset = term.term.groupsetting.lst[term.q.predefined_groupset_idx]\n\t\t} else if (term.q.type == 'custom-groupset') {\n\t\t\tgroupset = term.q.customset\n\t\t} else {\n\t\t\tthrow 'unexpected q.type'\n\t\t}\n\t\tconst group = groupset.groups.find(g => g.name == d.dataId)\n\t\tif (!group) throw 'group not found'\n\t\tgroup.color = color\n\t\tterm.q.type = 'custom-groupset'\n\t\tterm.q.customset = groupset\n\t}\n\tlet binColored = null\n\tif (self.bins[2].length > 0) {\n\t\t//term index: term0: 0, term: 1, term2: 2\n\t\tconst binMatched = self.bins[2].find(bin => bin.label == d.dataId)\n\t\tif (binMatched) {\n\t\t\tbinMatched.color = color\n\t\t\tbinColored = self.bins[2]\n\t\t}\n\t}\n\tself.app.dispatch({\n\t\ttype: 'plot_edit',\n\t\tid: self.id,\n\t\tconfig: {\n\t\t\t[termNum]: {\n\t\t\t\t$id: term.$id,\n\t\t\t\tid: term.id,\n\t\t\t\tisAtomic: true,\n\t\t\t\tterm: term.term,\n\t\t\t\tq: getUpdatedQfromClick(d, term, d.isHidden, binColored)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction handleLegendClick(target, self) {\n\tconst d = target.__data__\n\tif (d === undefined) return\n\tif (!('type' in d)) return\n\tconst termNum = d.type == 'col' ? 'term' : 'term2'\n\tconst term = self.config[termNum]\n\tconst isHidden =\n\t\t'isHidden' in d\n\t\t\t? !d.isHidden\n\t\t\t: !(term.q && term.q.hiddenValues && term.q.hiddenValues['dataId' in d ? d.dataId : d.id])\n\tconst tip = self.app.tip\n\tconst menu = tip.clear()\n\tmenu.showunder(target)\n\tconst div = menu.d.append('div')\n\tdiv\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t.text(!isHidden ? 'Show' : 'Hide')\n\t\t.on('click', () => {\n\t\t\tmenu.hide()\n\t\t\thideCategory(d, self, isHidden)\n\t\t})\n\tif (term.q.hiddenValues && Object.keys(term.q.hiddenValues).length > 1)\n\t\tdiv\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_menuoption sja_sharp_border')\n\t\t\t.text('Show all')\n\t\t\t.on('click', () => {\n\t\t\t\tmenu.hide()\n\t\t\t\tconst config = {}\n\t\t\t\tconst tw = structuredClone(term)\n\t\t\t\tdelete tw.q.hiddenValues\n\n\t\t\t\tself.app.dispatch({\n\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\tid: self.id,\n\t\t\t\t\tconfig: { [termNum]: tw }\n\t\t\t\t})\n\t\t\t})\n\tconst color = rgb(d.color).formatHex()\n\tif (color != '#ffffff') {\n\t\tconst input = div\n\t\t\t.append('div')\n\t\t\t.attr('class', 'sja_sharp_border')\n\t\t\t.style('padding', '0px 10px')\n\t\t\t.text('Color:')\n\t\t\t.append('input')\n\t\t\t.attr('type', 'color')\n\t\t\t.attr('value', color)\n\t\t\t.on('change', () => {\n\t\t\t\thandleColorClick(d, self, input.node().value)\n\t\t\t\tmenu.hide()\n\t\t\t})\n\t}\n}\n\nexport function hideCategory(d, self, isHidden) {\n\tconst termNum = d.type == 'col' ? 'term' : 'term2'\n\tconst term = self.config[termNum]\n\tself.app.dispatch({\n\t\ttype: 'plot_edit',\n\t\tid: self.id,\n\t\tconfig: {\n\t\t\t[termNum]: {\n\t\t\t\t//Fix for list samples options not working\n\t\t\t\t//after hiding a category\n\t\t\t\t$id: term?.$id,\n\t\t\t\tid: term.id,\n\n\t\t\t\tisAtomic: true,\n\t\t\t\tterm: term.term,\n\t\t\t\tq: getUpdatedQfromClick(d, term, isHidden)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction getUpdatedQfromClick(d, term, isHidden = false, binColored = null) {\n\tconst label = 'id' in d ? d.id : d.type == 'col' ? d.seriesId : d.dataId\n\tconst valueId = term.term.values && Object.keys(term.term.values).find(id => term.term.values[id].label === label)\n\tconst id = !valueId ? label : valueId\n\tconst q = JSON.parse(JSON.stringify(term.q))\n\tif (!q.hiddenValues) q.hiddenValues = {}\n\tif (isHidden) q.hiddenValues[id] = 1\n\telse delete q.hiddenValues[id]\n\tif (binColored) q.binColored = binColored\n\treturn q\n}\n\nfunction handle_click(event, self, chart) {\n\tconst d = event.target.__data__ || event.target.parentNode.__data__\n\t// bar label data only has {id,label},\n\t// while bar data has all required data including seriesId\n\tconst term1 = self.config.term.term\n\tconst term2 = self.config.term2 ? self.config.term2.term : null\n\tconst uncomp_term1 = term1.values ? Object.values(term1.values).map(v => v.label) : []\n\tconst uncomp_term2 = term2 && term2.values ? Object.values(term2.values).map(v => v.label) : []\n\tconst term1unit = term1.unit && !uncomp_term1.includes(d.seriesId || d.id) ? ' ' + term1.unit : ''\n\tconst term2unit = term2 && term2.unit && !uncomp_term2.includes(d.dataId || d.id) ? ' ' + term2.unit : ''\n\tconst seriesId = d.seriesId || d.id\n\tconst seriesLabel = (term1.values && seriesId in term1.values ? term1.values[seriesId].label : seriesId) + term1unit\n\tconst dataLabel =\n\t\t(term2 && term2.values && d.dataId in term2.values ? term2.values[d.dataId].label : d.dataId ? d.dataId : d.id) +\n\t\tterm2unit\n\tconst icon = !term2\n\t\t? ''\n\t\t: \"<div style='display:inline-block; width:14px; height:14px; margin: 2px 3px; vertical-align:top; background:\" +\n\t\t d.color +\n\t\t \"'> </div>\"\n\tconst header =\n\t\t`<div style='padding:2px'><b>${term1.name}</b>: ${seriesLabel}</div>` +\n\t\t(d.seriesId && term2 ? `<div style='padding:2px'><b>${term2.name}</b>: ${dataLabel} ${icon}</div>` : '')\n\n\tconst data = d.seriesId || d.seriesId === 0 ? d : { seriesId: d.id, dataId: d.dataId }\n\n\tconst options = []\n\tif (self.opts.bar_click_opts.includes('hide_bar')) {\n\t\tconst chartId = chart.chartId === undefined ? '' : chart.chartId\n\t\tconst visibleSerieses = chart.visibleSerieses || self.charts.find(c => c.chartId === chartId)?.visibleSerieses || []\n\t\tif (visibleSerieses.length > 1) {\n\t\t\toptions.push({\n\t\t\t\tlabel: data.seriesId ? 'Hide \"' + seriesLabel + '\"' : 'Hide',\n\t\t\t\tcallback: () => {\n\t\t\t\t\tconst term = self.config.term\n\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\t\tid: self.id,\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tterm: {\n\t\t\t\t\t\t\t\t$id: term.$id,\n\t\t\t\t\t\t\t\tid: term.id,\n\t\t\t\t\t\t\t\tisAtomic: true,\n\t\t\t\t\t\t\t\tterm: term.term,\n\t\t\t\t\t\t\t\tq: getUpdatedQfromClick({ id: data.seriesId, type: 'col' }, term, true)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tconst hasMultipleCells = visibleSerieses.some(s => s.visibleData.length > 1)\n\t\tif (hasMultipleCells && (data.dataId || data.dataId === 0)) {\n\t\t\toptions.push({\n\t\t\t\tlabel: 'Hide \"' + dataLabel + '\" ' + icon,\n\t\t\t\tcallback: () => {\n\t\t\t\t\tconst term2 = self.config.term2\n\t\t\t\t\tself.app.dispatch({\n\t\t\t\t\t\tisAtomic: true,\n\t\t\t\t\t\ttype: 'plot_edit',\n\t\t\t\t\t\tid: self.id,\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tterm2: {\n\t\t\t\t\t\t\t\tisAtomic: true,\n\t\t\t\t\t\t\t\tterm: term2.term,\n\t\t\t\t\t\t\t\tq: getUpdatedQfromClick({ id: data.dataId, type: 'row' }, term2, true)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tif (self.opts.bar_click_opts.includes('add_filter')) {\n\t\tconst item = findItemByTermId(self.state.termfilter.filter, self.config.term.term.id)\n\t\tif (!item) {\n\t\t\toptions.push({\n\t\t\t\tlabel: 'Add as filter',\n\t\t\t\tcallback: async (self, tvslst) => {\n\t\t\t\t\tconst arg = getListSamplesArg(event, self, data.seriesId, data.dataId, chart.chartId)\n\t\t\t\t\tawait menuoption_add_filter(self, tvslst, arg)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tif (self.opts.bar_click_opts.includes('add_group') && self.config.displaySampleIds) {\n\t\toptions.push({\n\t\t\tlabel: 'Add as group',\n\t\t\tcallback: async () => {\n\t\t\t\tconst arg = getListSamplesArg(event, self, data.seriesId, data.dataId, chart.chartId)\n\t\t\t\tawait addAsGroup(arg)\n\t\t\t}\n\t\t})\n\t}\n\n\tconst uiLabels = self.config.controlLabels || self.app.vocabApi.termdbConfig.uiLabels\n\t//disable sample listing temporarily\n\tif (self.config.displaySampleIds) {\n\t\toptions.push({\n\t\t\tlabel: `List ${uiLabels.samples}`,\n\t\t\tcallback: async () => {\n\t\t\t\tconst arg = getListSamplesArg(event, self, data.seriesId, data.dataId, chart.chartId)\n\t\t\t\ttry {\n\t\t\t\t\tawait listSamples(arg, data.seriesId, data.dataId, chart.chartId)\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.trace(e)\n\t\t\t\t\tthrow e\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\t// TODO: add to cart\n\t//\n\t// if (self.opts.bar_click_opts.includes('add_to_cart')) {\n\t// \toptions.push({\n\t// \t\tlabel: 'Add group to cart',\n\t// \t\tcallback: menuoption_select_group_add_to_cart\n\t// \t})\n\t// }\n\n\tif (!options.length) return\n\tself.app.tip.clear()\n\tif (header) {\n\t\tself.app.tip.d.append('div').html(header)\n\t}\n\tconst tvslst = getTermValues(data, self)\n\tself.app.tip.d\n\t\t.append('div')\n\t\t.selectAll('div')\n\t\t.data(options)\n\t\t.enter()\n\t\t.append('div')\n\t\t.attr('class', 'sja_menuoption')\n\t\t.html(d => d.label)\n\t\t.on('click', async (event, d) => {\n\t\t\tif (event.target._clicked) return\n\t\t\tevent.target._clicked = true\n\t\t\tevent.target.textContent = 'Loading...'\n\t\t\tawait d.callback(self, tvslst)\n\t\t\tself.app.tip.hide()\n\t\t})\n\tself.app.tip.show(event.clientX, event.clientY)\n}\n\nfunction getListSamplesArg(event, self, seriesId, dataId, chartId) {\n\tconst terms = [self.config.term]\n\tconst tvslst = {\n\t\ttype: 'tvslst',\n\t\tin: true,\n\t\tjoin: 'and',\n\t\tlst: []\n\t}\n\tconst geneVariant = {}\n\tconst tvs = getTvs(1, seriesId, self, geneVariant)\n\tif (tvs) tvslst.lst.push(tvs)\n\tif (self.config.term2) {\n\t\tterms.push(self.config.term2)\n\t\tconst tvs = getTvs(2, dataId, self, geneVariant)\n\t\tif (tvs) tvslst.lst.push(tvs)\n\t}\n\tif (self.config.term0) {\n\t\tterms.push(self.config.term0)\n\t\tconst tvs = getTvs(0, chartId, self, geneVariant)\n\t\tif (tvs) tvslst.lst.push(tvs)\n\t}\n\tconst arg = {\n\t\tevent,\n\t\tself,\n\t\tterms,\n\t\ttvslst,\n\t\tgeneVariant\n\t}\n\treturn arg\n}\n\nfunction getTvs(termIndex, value, self, geneVariant) {\n\tif (!value) return\n\tconst term = termIndex == 0 ? self.config.term0 : termIndex == 1 ? self.config.term : self.config.term2\n\tif (term.term.type == 'geneVariant') {\n\t\t// geneVariant filtering will be handled by mayFilterByGeneVariant()\n\t\tgeneVariant[`t${termIndex}value`] = value\n\t\treturn\n\t}\n\tlet tvs = {\n\t\ttype: 'tvs',\n\t\ttvs: {\n\t\t\tterm: term.term,\n\t\t\tvalues: [{ key: value }]\n\t\t}\n\t}\n\tif (term.q.type == 'custom-groupset' || term.q.type == 'predefined-groupset') {\n\t\tconst groupset =\n\t\t\tterm.q.type == 'custom-groupset' ? term.q.customset : term.term.groupsetting.lst[term.q.predefined_groupset_idx]\n\t\tconst group = groupset.groups.find(group => group.name == value)\n\t\tif (!group) throw 'group not found'\n\t\ttvs.tvs.values = group.values\n\t} else if (isNumericTerm(term.term)) {\n\t\tconst bins = self.bins[termIndex]\n\t\tif (!bins?.length) return null\n\t\ttvs.tvs.ranges = [bins.find(bin => bin.label == value)]\n\t} else if (term.term.type == 'samplelst') {\n\t\tconst list = term.term.values?.[value]?.list || []\n\t\tconst ids = list.map(s => s.sampleId)\n\t\tconst tvslst = getSamplelstFilter(ids)\n\t\ttvs = tvslst.lst[0] // tvslst only has the tvs for the samplelst term\n\t} else if (term.term.type == 'geneVariant' && term.q.type == 'values') {\n\t\tthrow 'no longer supported in barchart'\n\t}\n\treturn tvs\n}\n\nexport async function listSamples(arg, seriesId, dataId, chartId) {\n\t// validate arg\n\tfor (const k of Object.keys(arg)) {\n\t\tconst param = arg[k]\n\t\tif (!param) throw `parameter '${k}' is undefined`\n\t}\n\n\t// query sample data\n\tconst { event, self, terms, tvslst, geneVariant, tip } = arg\n\tconst { term0, term, term2 } = self.config\n\tconst _terms = structuredClone(terms)\n\tfor (const tw of _terms) {\n\t\tconst i = tw.$id === term0?.$id ? 0 : tw.$id === term2?.$id ? 2 : 1\n\t\tif (!self.bins[i].length) continue\n\t\t// reuse already computed bins so that the assigned bin labels\n\t\t// from '/termdb/barchart' response will be consistent with '/termdb?for=matrix'\n\t\ttw.q = {\n\t\t\tmode: 'discrete',\n\t\t\ttype: 'custom-bin',\n\t\t\tlst: self.bins[i]\n\t\t}\n\t}\n\n\tconst uiLabels = self.config.controlLabels || self.app.vocabApi.termdbConfig.uiLabels\n\tconst opts = {\n\t\tterms: _terms,\n\t\tfilter: filterJoin([self.state.termfilter.filter, tvslst]),\n\t\tfilter0: self.state.termfilter.filter0,\n\t\tisSummary: true\n\t}\n\tconst data = await self.app.vocabApi.getAnnotatedSampleData(opts)\n\n\t// fill table rows with sample data\n\tconst rows = []\n\tconst termIsNumeric = isNumericTerm(self.config.term.term)\n\tconst term2isNumeric = self.config.term2 ? isNumericTerm(self.config.term2.term) : false\n\tconst term0isNumeric = self.config.term0 ? isNumericTerm(self.config.term0.term) : false\n\tconst termIsGv = self.config.term.term.type == 'geneVariant'\n\tconst term2isGv = self.config.term2?.term.type == 'geneVariant'\n\tconst term0isGv = self.config.term0?.term.type == 'geneVariant'\n\tconst term2isSurv = self.config.term2?.term.type == 'survival'\n\tconst term0isSurv = self.config.term0?.term.type == 'survival'\n\tconst termdbmclass = self.app.vocabApi.termdbConfig?.mclass\n\tconst notRenderedVals = new Set()\n\tfor (const sample of data.lst) {\n\t\tconst pass = mayFilterByGeneVariant(sample, self, geneVariant)\n\t\tif (!pass) continue\n\t\tconst sampleName = data.refs.bySampleId[sample.sample].label\n\t\tconst row = [{ value: sampleName }]\n\t\tconst urlTemplate = self.app.vocabApi.termdbConfig?.urlTemplates?.sample\n\t\tif (urlTemplate) {\n\t\t\t// sample url template is defined, use it to format sample name as url\n\t\t\trow[0].url = urlTemplate.base + (sample[urlTemplate.namekey] || sample.sample)\n\t\t}\n\t\tconst t1entry = sample[self.config.term.$id]\n\t\tif (!t1entry) continue\n\t\t/** Don't show hidden values in the results\n\t\t * May not be caught in server request for custom variables\n\t\t * with user supplied keys */\n\t\tif (self.config.term.q?.hiddenValues && self.config.term.q.hiddenValues[t1entry.value]) continue\n\t\tlet notRendered = false\n\t\tconst value = t1entry.value\n\t\tif (termIsNumeric) {\n\t\t\trow.push({ value: t1entry.key === seriesId ? roundValueAuto(value) : t1entry.key })\n\t\t} else if (termIsGv) {\n\t\t\taddGvRowVals(sample, self.config.term, row, termdbmclass)\n\t\t} else {\n\t\t\trow.push({ value: t1entry.key === seriesId ? value : t1entry.key })\n\t\t}\n\t\tif (t1entry.key !== seriesId) notRendered = true\n\n\t\tif (self.config.term2) {\n\t\t\tconst t2entry = sample[self.config.term2.$id]\n\t\t\tif (!t2entry) continue\n\t\t\t//Don't show hidden values in the results\n\t\t\tif (self.config.term2.q?.hiddenValues && self.config.term2.q.hiddenValues[t2entry.value]) continue\n\t\t\tif (term2isNumeric) {\n\t\t\t\tconst value = roundValueAuto(t2entry.value)\n\t\t\t\trow.push({ value: t2entry.key === dataId ? value : t2entry.key })\n\t\t\t} else if (term2isGv) {\n\t\t\t\taddGvRowVals(sample, self.config.term2, row, termdbmclass)\n\t\t\t} else if (term2isSurv) {\n\t\t\t\tconst value = self.config.term2.term.values[t2entry.key].label\n\t\t\t\trow.push({ value })\n\t\t\t} else {\n\t\t\t\tconst label = self.config.term2.term.values?.[t2entry.value]?.label\n\t\t\t\tconst value = label || t2entry.value\n\t\t\t\trow.push({ value: t2entry.key === dataId ? value : t2entry.key })\n\t\t\t}\n\t\t\t// if the series/bar label is clicked, the overlay/dataId will not be provided for listSamples\n\t\t\tif (dataId && t2entry.key !== dataId) notRendered = true\n\t\t}\n\t\t// for now, duplicating if block for term2 and term0\n\t\t// TODO: use dom/summary/ListSamples.ts\n\t\tif (self.config.term0) {\n\t\t\tconst t0entry = sample[self.config.term0.$id]\n\t\t\tif (!t0entry) continue\n\t\t\t//Don't show hidden values in the results\n\t\t\tif (self.config.term0.q?.hiddenValues && self.config.term0.q.hiddenValues[t0entry.value]) continue\n\t\t\tif (term0isNumeric) {\n\t\t\t\tconst value = roundValueAuto(t0entry.value)\n\t\t\t\trow.push({ value: t0entry.key === chartId ? value : t0entry.key })\n\t\t\t} else if (term0isGv) {\n\t\t\t\taddGvRowVals(sample, self.config.term0, row, termdbmclass)\n\t\t\t} else if (term0isSurv) {\n\t\t\t\tconst value = self.config.term0.term.values[t0entry.key].label\n\t\t\t\trow.push({ value })\n\t\t\t} else {\n\t\t\t\tconst label = self.config.term0.term.values?.[t0entry.value]?.label\n\t\t\t\tconst value = label || t0entry.value\n\t\t\t\trow.push({ value: t0entry.key === chartId ? value : t0entry.key })\n\t\t\t}\n\t\t\tif (chartId && t0entry.key !== chartId) notRendered = true\n\t\t}\n\n\t\tif (notRendered && row.length) {\n\t\t\tnotRenderedVals.add(row)\n\t\t}\n\n\t\trows.push(row)\n\t}\n\n\t// fill table columns with term metadata\n\tconst columns = [{ label: uiLabels.Sample }]\n\tif (termIsNumeric) {\n\t\tcolumns.push({ label: self.config.term.term.name })\n\t} else if (termIsGv) {\n\t\taddGvCols(self.config.term, columns)\n\t} else {\n\t\tcolumns.push({ label: self.config.term.term.name })\n\t}\n\tif (self.config.term2) {\n\t\tif (term2isGv) {\n\t\t\taddGvCols(self.config.term2, columns)\n\t\t} else {\n\t\t\tcolumns.push({ label: self.config.term2.term.name })\n\t\t}\n\t}\n\tif (self.config.term0) {\n\t\tif (term0isGv) {\n\t\t\taddGvCols(self.config.term0, columns)\n\t\t} else {\n\t\t\tcolumns.push({ label: self.config.term0.term.name })\n\t\t}\n\t}\n\n\t// render table in div. from now on arg.tip should always be given\n\tlet div\n\tif (tip) {\n\t\tdiv = tip.d\n\t\ttip.clear().show(event.clientX, event.clientY, false)\n\t} else {\n\t\tconst menu = new Menu({ padding: '5px' })\n\t\tmenu.show(event.clientX, event.clientY, false)\n\t\tdiv = menu.d.append('div')\n\t}\n\n\trows.sort((a, b) => {\n\t\treturn a[0].value < b[0].value ? -1 : 1\n\t})\n\n\tconst renderedRows = rows.filter(r => !notRenderedVals.has(r))\n\n\tif (renderedRows.length) {\n\t\tawait renderTable({\n\t\t\trows: renderedRows,\n\t\t\tcolumns,\n\t\t\tdiv: div.append('div'),\n\t\t\tshowLines: true,\n\t\t\tmaxHeight: '40vh',\n\t\t\tresize: true,\n\t\t\tdataTestId: 'sjpp-listsampletable'\n\t\t})\n\t}\n\n\tif (notRenderedVals.size) {\n\t\t// TODO: do not hardcode, make this dataset specific\n\t\tconst barOrChart = self.config.term0?.term.id.startsWith('case.diagnoses') ? 'bar or chart' : 'bar'\n\t\tconst matchedLabels = []\n\t\tif (term?.term?.id?.startsWith('case.diagnoses')) matchedLabels.push(seriesId)\n\t\tif (term2?.term?.id?.startsWith('case.diagnoses')) matchedLabels.push(dataId)\n\t\tif (term0?.term?.id?.startsWith('case.diagnoses')) matchedLabels.push(chartId)\n\t\tconst clickedLabel = matchedLabels.join(', ')\n\n\t\tdiv.append('div').style('margin', '5px').style('padding', '5px').style('max-width', '600px')\n\t\t\t.html(`<span>The ${uiLabels.samples} below have multiple diagnoses entries, where 1 or more entries match the value in \n\t\t\t\tthe clicked ${barOrChart} (${clickedLabel}), but were not rendered here. The entries corresponding to the \n\t\t\t\tprimary diagnosis for these cases were rendered and counted in a different ${barOrChart}.</span>\n\t\t\t`)\n\n\t\tawait renderTable({\n\t\t\trows: rows.filter(r => notRenderedVals.has(r)),\n\t\t\tcolumns,\n\t\t\tdiv: div.append('div'),\n\t\t\tshowLines: true,\n\t\t\tmaxHeight: '40vh',\n\t\t\tresize: true,\n\t\t\tdataTestId: 'sjpp-listsampletable'\n\t\t})\n\t}\n}\nasync function getSampleGrp(arg) {\n\t// query sample data\n\tconst { event, self, terms, tvslst, geneVariant, tip } = arg\n\tconst opts = {\n\t\tterms,\n\t\tfilter: filterJoin([self.state.termfilter.filter, tvslst]),\n\t\tfilter0: self.state.termfilter.filter0,\n\t\tisSummary: true\n\t}\n\tconst data = await self.app.vocabApi.getAnnotatedSampleData(opts)\n\tconst samples = []\n\tfor (const sample of data.lst) {\n\t\tconst pass = mayFilterByGeneVariant(sample, self, geneVariant)\n\t\tif (!pass) continue\n\t\tconst t1entry = sample[self.config.term.$id]\n\t\tif (!t1entry) continue\n\t\tif (self.config.term.q?.hiddenValues && self.config.term.q.hiddenValues[t1entry.value]) continue\n\t\tsamples.push({ sampleId: sample.sample })\n\t}\n\n\tconst group = {\n\t\tname: 'Group',\n\t\titems: samples\n\t}\n\treturn group\n}\n\nexport async function addAsGroup(arg) {\n\t// validate arg\n\tfor (const k of Object.keys(arg)) {\n\t\tconst param = arg[k]\n\t\tif (!param) throw `parameter '${k}' is undefined`\n\t}\n\tconst group = await getSampleGrp(arg)\n\tconst tw = getSamplelstTW([group])\n\tconst filter = getFilter(tw)\n\taddNewGroup(arg.self.app, filter, arg.self.state.groups)\n}\n\n// if geneVariant term is present, filter sample by its geneVariant group assignment\nfunction mayFilterByGeneVariant(sample, self, geneVariant) {\n\tif (self.config.term.term.type == 'geneVariant' && geneVariant.t1value) {\n\t\tconst tw = self.config.term\n\t\tif (tw.q.type == 'values') throw 'q.type=values not supported'\n\t\tconst value = sample[tw.$id]?.value\n\t\tif (value != geneVariant.t1value) return false\n\t}\n\tif (self.config.term2?.term.type == 'geneVariant' && geneVariant.t2value) {\n\t\tconst tw = self.config.term2\n\t\tif (tw.q.type == 'values') throw 'q.type=values not supported'\n\t\tconst value = sample[tw.$id]?.value\n\t\tif (value != geneVariant.t2value) return false\n\t}\n\tif (self.config.term0?.term.type == 'geneVariant' && geneVariant.t0value) {\n\t\tconst tw = self.config.term0\n\t\tif (tw.q.type == 'values') throw 'q.type=values not supported'\n\t\tconst value = sample[tw.$id]?.value\n\t\tif (value != geneVariant.t0value) return false\n\t}\n\treturn true\n}\n\n// add geneVariant values to row\nexport function addGvRowVals(sample, tw, row, termdbmclass) {\n\tconst mlst = sample[tw.$id]?.values\n\tconst gene2mlst = new Map()\n\t// map each gene to its mutations\n\tfor (const gene of tw.term.genes) {\n\t\tconst mlst_gene = mlst.filter(m => m.gene == gene.id)\n\t\tgene2mlst.set(gene.name, mlst_gene)\n\t}\n\tif (!gene2mlst.size) throw 'gene2mlst is empty'\n\tif (gene2mlst.size == 1) {\n\t\t// single gene, add its mutations to mutation column\n\t\tconst entry = gene2mlst.entries().next().value\n\t\tconst mlst = entry[1]\n\t\tconst htmls = mlst2htmls(mlst, termdbmclass)\n\t\trow.push({ html: htmls.join('<br>') })\n\t} else {\n\t\t// multiple genes, add each gene to gene column and its\n\t\t// mutations to mutation column\n\t\tconst genes = []\n\t\tconst htmls = []\n\t\tfor (const [gene, mlst] of gene2mlst) {\n\t\t\tgenes.push(...Array(mlst.length).fill(gene))\n\t\t\thtmls.push(...mlst2htmls(mlst, termdbmclass))\n\t\t}\n\t\trow.push({ html: genes.join('<br>') })\n\t\trow.push({ html: htmls.join('<br>') })\n\t}\n}\n\nfunction mlst2htmls(mlst, termdbmclass) {\n\tconst htmls = mlst.map(m => {\n\t\tconst mname = m.mname || '' // e.g. aa change\n\t\tconst value = m.value ? roundValueAuto(m.value, false, 3) : '' // e.g. cnv value\n\t\tconst color = mclass[m.class].color\n\t\tconst label = (termdbmclass?.[m.class]?.label || mclass[m.class].label).toUpperCase()\n\n\t\tconst holder = create('div')\n\n\t\tholder.append('span').text(mname || value)\n\n\t\tholder\n\t\t\t.append('span')\n\t\t\t.style('margin-left', mname || value ? '5px' : '0px')\n\t\t\t.style('color', color)\n\t\t\t.style('font-size', '.8em')\n\t\t\t.text(label)\n\n\t\treturn holder.html()\n\t})\n\treturn htmls\n}\n\n// add geneVariant columns\nexport function addGvCols(tw, columns) {\n\tif (tw.term.genes.length == 1) {\n\t\tcolumns.push({ label: tw.term.name })\n\t} else {\n\t\tcolumns.push({ label: 'Gene' })\n\t\tif (tw.q.type == 'predefined-groupset') {\n\t\t\tconst groupset = tw.term.groupsetting.lst[tw.q.predefined_groupset_idx]\n\t\t\tcolumns.push({ label: dt2label[groupset.dt] })\n\t\t} else if (tw.q.type == 'custom-groupset') {\n\t\t\tcolumns.push({ label: 'Genotype' })\n\t\t} else {\n\t\t\tthrow 'unexpected tw.q.type'\n\t\t}\n\t}\n}\n\nasync function menuoption_add_filter(self, tvslst, arg) {\n\t/*\n\tself: the tree object\n\ttvslst: an array of 1 or 2 term-value setting objects\n\t\tthis is to be added to the obj.termfilter.filter[]\n\t\tif barchart is single-term, tvslst will have only one element\n\t\tif barchart is two-term overlay, tvslst will have two elements, one for term1, the other for term2\n\targ: object of parameters used by getSampleGrp to get sample group\n\t\t*/\n\tif (!tvslst) return\n\tif (!self.state.termfilter || self.state.nav?.header_mode !== 'with_tabs') {\n\t\t// do not display ui, and do not collect callbacks\n\t\treturn\n\t}\n\t// validate arg\n\tfor (const k of Object.keys(arg)) {\n\t\tconst param = arg[k]\n\t\tif (!param) throw `parameter '${k}' is undefined`\n\t}\n\n\tconst hasGrpSetting = arg.terms.find(t => t.q?.type == 'predefined-groupset' || t.q?.type == 'custom-groupset')\n\tlet samplelstTW\n\tif (hasGrpSetting) {\n\t\t// if any term has group setting, add filter as samplelst\n\t\tconst group = await getSampleGrp(arg)\n\t\tsamplelstTW = getSamplelstTW([group])\n\t}\n\n\tconst filterUiRoot = getFilterItemByTag(self.state.termfilter.filter, 'filterUiRoot')\n\tconst filter = filterJoin([\n\t\tfilterUiRoot,\n\t\tsamplelstTW\n\t\t\t? getFilter(samplelstTW)\n\t\t\t: {\n\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\tin: true,\n\t\t\t\t\tjoin: tvslst.length > 1 ? 'and' : '',\n\t\t\t\t\tlst: [...tvslst.map(wrapTvs)]\n\t\t\t }\n\t])\n\tfilter.tag = 'filterUiRoot'\n\tself.app.dispatch({\n\t\ttype: 'filter_replace',\n\t\tfilter\n\t})\n}\n\nfunction wrapTvs(tvs) {\n\treturn tvs.type === 'tvs' ? tvs : { type: 'tvs', tvs }\n}\n\n/* \t\t\tTODO: add to cart and gp */\n\nfunction menuoption_listsamples(self, tvslst) {\n\tconst filterRoot = getNormalRoot({\n\t\ttype: 'tvslst',\n\t\tjoin: 'and',\n\t\tlst: [\n\t\t\tself.state.termfilter.filter,\n\t\t\t// create a copy of tvslst to not mutate the barchart state,\n\t\t\t// such as when deleting tvs.tvs.term.values below\n\t\t\t...tvslst.map(tvs => wrapTvs(JSON.parse(JSON.stringify(tvs))))\n\t\t]\n\t})\n\t///////////// quick fix to delete term.values{} from stringified filter to reduce url length\n\tnormalizeProps(filterRoot, f => {\n\t\tdelete f.tag\n\t\tif (f.type == 'tvs' && f.tvs && f.tvs.term) delete f.tvs.term.values\n\t})\n\tconst arg = [\n\t\t'getsamples=1',\n\t\t'genome=' + self.app.vocabApi.vocab.genome,\n\t\t'dslabel=' + self.app.vocabApi.vocab.dslabel,\n\t\t'filter=' + encodeURIComponent(JSON.stringify(filterRoot))\n\t]\n\n\tdofetch3('termdb?' + arg.join('&')).then(data => {\n\t\texport_data(data.samples.length + ' samples', [{ text: data.samples.join('\\n') }])\n\t})\n}\n\nfunction menuoption_select_group_add_to_cart(self, tvslst) {\n\tif (!tvslst || !tvslst.length) return\n\n\tconst new_group = {}\n\tnew_group.is_termdb = true\n\tnew_group.terms = []\n\n\tfor (const [i, term] of tvslst.entries()) {\n\t\tnew_group.terms.push(term)\n\t}\n\n\tif (!self.selected_groups) {\n\t\tself.selected_groups = []\n\t}\n\n\tself.selected_groups.push(new_group)\n\tself.components.cart.main()\n}\n\nfunction getTermValues(d, self) {\n\t/*\n\td: clicked bar data\n */\n\tconst termValues = []\n\tif (self.state.nav?.header_mode == 'with_cohortHtmlSelect') {\n\t\t// pass the cohort filter information back to calling app\n\t\t// do not set the renderAs in here since that is decided by the calling app\n\t\tconst cohortFilter = getFilterItemByTag(self.state.termfilter.filter, 'cohortFilter')\n\t\tif (cohortFilter) termValues.push(JSON.parse(JSON.stringify(cohortFilter)))\n\t}\n\n\tconst t1 = self.config.term\n\tconst t1ValKey =\n\t\tt1.term.values && Object.keys(t1.term.values).filter(key => t1.term.values[key].label === d.seriesId)[0]\n\tconst t1ValId = t1.term.values && t1ValKey in t1.term.values ? t1ValKey : d.seriesId\n\tconst t2 = self.config.term2\n\tconst t2ValKey =\n\t\tt2 && t2.term.values && Object.keys(t2.term.values).filter(key => t2.term.values[key].label === d.dataId)[0]\n\tconst t2ValId = t2 && t2.term.values && t2ValKey in t2.term.values ? t2ValKey : d.dataId\n\n\tfor (const term of [t1, t2]) {\n\t\tif (!term) continue\n\t\tconst i = term == t1 ? 1 : 2\n\t\tconst key = term == t1 ? t1ValId : t2ValId\n\t\tif (!key) continue\n\t\t// const q = term ? term.q : {}\n\t\tconst q = term.q //self.currServerData.refs.q[i]\n\t\tconst label = !term || !term.term.values ? key : key in term.term.values ? term.term.values[key].label : key\n\n\t\tif (q.type == 'predefined-groupset' || q.type == 'custom-groupset') {\n\t\t\tconst groupset =\n\t\t\t\tq.type == 'predefined-groupset' ? term.term.groupsetting.lst[q.predefined_groupset_idx] : q.customset\n\t\t\tconst group = groupset.groups.find(g => g.name === key)\n\t\t\tconst tvs = { term: term.term, values: group.values, groupset_label: group.name }\n\t\t\tif (term.term.type == 'condition') {\n\t\t\t\ttvs.bar_by_children = term.q.bar_by_children\n\t\t\t\ttvs.bar_by_grade = term.q.bar_by_grade\n\t\t\t\ttvs.value_by_most_recent = term.q.value_by_most_recent\n\t\t\t\ttvs.value_by_max_grade = term.q.value_by_max_grade\n\t\t\t}\n\t\t\ttermValues.push(tvs)\n\t\t} else if (term.term.type == 'condition') {\n\t\t\tif (!t2 || t1.term.id != t2.term.id) {\n\t\t\t\ttermValues.push(\n\t\t\t\t\tObject.assign(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tterm: term.term,\n\t\t\t\t\t\t\tvalues: [{ key, label }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tq\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (term == t1 && t2 && term.term.id == t2.term.id) {\n\t\t\t\tconst q2 = t2.q\n\t\t\t\tconst term2Label =\n\t\t\t\t\tt2.term.values && d.dataId in t2.term.values ? self.config.term2.values[d.dataId].label : d.dataId\n\n\t\t\t\ttermValues.push(\n\t\t\t\t\tObject.assign(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tterm: term.term,\n\t\t\t\t\t\t\tgrade_and_child: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tgrade: q2.bar_by_grade ? d.dataId : key,\n\t\t\t\t\t\t\t\t\tgrade_label: q2.bar_by_grade ? term2Label : label,\n\t\t\t\t\t\t\t\t\tchild_id: q2.bar_by_children ? d.dataId : key,\n\t\t\t\t\t\t\t\t\tchild_label: q2.bar_by_children ? term2Label : label\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tq2\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t} else {\n\t\t\tconst bins = self.currServerData.refs.bins[i]\n\t\t\tif (!bins || !bins.length) {\n\t\t\t\t// not associated with numeric bins\n\t\t\t\ttermValues.push({ term: term.term, values: [{ key, label }] })\n\t\t\t} else {\n\t\t\t\tconst range = bins.find(d => d.label == label || d.name == label)\n\t\t\t\tif (range) termValues.push({ term: term.term, ranges: [range] })\n\t\t\t\telse if (term == t1) {\n\t\t\t\t\ttermValues.push({ term: term.term, ranges: [{ value: key }] })\n\t\t\t\t} else if (term == t2) {\n\t\t\t\t\ttermValues.push({ term: term.term, ranges: [{ value: key }] })\n\t\t\t\t} else {\n\t\t\t\t\tthrow 'should not happen'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn termValues.map(f => wrapTvs(f))\n}\n", "import type { AppApi } from '#rx'\nimport type { TermWrapper, NumericBin } from '#types'\nimport type { AnnotatedSampleData, AnnotatedSampleEntry } from '../../types/termdb'\nimport type { TableColumn, TableRow } from '#dom'\nimport { getSamplelstFilter } from '../../mass/groups.js'\nimport { TermTypes, isNumericTerm, roundValueAuto, isStrictNumeric } from '#shared'\nimport { filterJoin } from '#filter'\nimport { addGvRowVals, addGvCols } from '#plots/barchart.events.js'\n\n/** Temp type scoped for this file.\n * Properties required in the plot arg. */\ntype ScopedPlot = {\n\tchartId?: string //value of divideBy term\n\tseriesId?: string //value of overlay term\n\tkey: any //value of the plot itself\n}\n\ntype ScopedBins = {\n\t[key: string]: {\n\t\t[key: string]: NumericBin\n\t}\n}\n\ntype ListSamplesOpts = {\n\tapp: AppApi\n\ttermfilter: any\n\tterm: TermWrapper\n\tterm2?: TermWrapper\n\tterm0?: TermWrapper\n\tplot: ScopedPlot\n\tbins?: ScopedBins\n\tstart?: number | null | undefined\n\tend?: number | null | undefined\n}\n\n/** Constructs the list sample argument needed for the server request.\n * Maybe used for showing the samples to user or creating filters. */\nexport class ListSamples {\n\tapp: AppApi\n\t/** From the state. Should include .filter:{} and .filter0:{} */\n\ttermfilter: any\n\t/** Rendered plot obj */\n\tplot: ScopedPlot\n\t/** Created by the server */\n\tbins: ScopedBins\n\n\tt1: TermWrapper\n\tt2: TermWrapper | null\n\tt0?: TermWrapper | null\n\tterms: TermWrapper[]\n\tcontTerm?: TermWrapper | null\n\toverlayTerm?: TermWrapper | null\n\n\t/** Indicates a reduced range for the bin (e.g. violin brush) */\n\tuseRange: boolean = false\n\tstart?: number | null\n\tend?: number | null\n\n\t/*******************\n\t * Created objects *\n\t *******************/\n\ttvslst: {\n\t\ttype: 'tvslst'\n\t\tin: true\n\t\tjoin: 'and'\n\t\tlst: any[]\n\t}\n\t/** For filtering gene variant terms later */\n\tgeneVariant = {}\n\n\tconstructor(opts: ListSamplesOpts) {\n\t\tif (!opts.term) throw new Error('Missing .term argument')\n\n\t\tthis.app = opts.app\n\t\tthis.termfilter = opts.termfilter\n\t\tthis.plot = opts.plot\n\t\tthis.bins = opts.bins || {}\n\n\t\tthis.t1 = opts.term\n\t\tthis.t2 = opts.term2 || null\n\t\tthis.t0 = opts.term0 || null\n\n\t\tconst { term, term2 } = opts\n\t\tthis.contTerm = 'mode' in term.q && term.q.mode == 'continuous' ? term : term2\n\t\tthis.overlayTerm = term === this.contTerm ? term2 : term\n\t\tthis.terms = [this.t1]\n\n\t\tif (\n\t\t\t(isStrictNumeric(opts.start) && !isStrictNumeric(opts.end)) ||\n\t\t\t(!isStrictNumeric(opts.start) && isStrictNumeric(opts.end))\n\t\t) {\n\t\t\tthrow new Error('Both start and end must be provided for range filtering')\n\t\t}\n\n\t\tif (isStrictNumeric(opts.start) && isStrictNumeric(opts.end)) {\n\t\t\tthis.useRange = true\n\t\t\tthis.start = opts.start\n\t\t\tthis.end = opts.end\n\t\t}\n\n\t\tthis.tvslst = {\n\t\t\ttype: 'tvslst',\n\t\t\tin: true,\n\t\t\tjoin: 'and',\n\t\t\tlst: []\n\t\t}\n\t\tthis.getTvsLst()\n\t}\n\n\tgetTvsLst(): void {\n\t\tthis.getTvsLstEntry(1)\n\t\tif (this.t2) {\n\t\t\tthis.terms.push(this.t2)\n\t\t\tthis.getTvsLstEntry(2)\n\t\t}\n\t\tif (this.t0) {\n\t\t\tthis.terms.push(this.t0)\n\t\t\tthis.getTvsLstEntry(0)\n\t\t}\n\t}\n\n\tgetTvsLstEntry(termNum: number): void {\n\t\tconst tw = this[`t${termNum}`]\n\t\tif (!tw) throw new Error('Missing term wrapper')\n\t\tif (tw.term.type === TermTypes.GENE_VARIANT) {\n\t\t\tthis.geneVariant[`t${termNum}value`] = this.plot.seriesId\n\t\t\treturn\n\t\t}\n\t\tconst key: any = termNum == 0 ? this.plot.chartId : this.plot.seriesId\n\t\tif (!key && key !== 0) return\n\n\t\tlet tvsEntry = {\n\t\t\ttype: 'tvs',\n\t\t\ttvs: {\n\t\t\t\tterm: tw.term\n\t\t\t}\n\t\t}\n\n\t\t//TODO: delete isContinuousOrBinned and tests if isNumericTerm works\n\t\tif (this.isContinuousOrBinned(tw, termNum)) {\n\t\t\ttvsEntry.tvs = this.createTvsRanges(tvsEntry.tvs, termNum)\n\t\t}\n\t\t// this may not be needed if there is tvsEntry.tvs.ranges[]?\n\t\ttvsEntry = this.createTvsValues(tvsEntry, tw, key)\n\n\t\tthis.tvslst.lst.push(tvsEntry)\n\t}\n\n\tcreateTvsValues(tvsEntry: any, tw: any, key: string): any {\n\t\tif (\n\t\t\t(tw?.q?.type == 'custom-groupset' || tw?.q?.type == 'predefined-groupset') &&\n\t\t\ttw.term.type !== TermTypes.GENE_VARIANT\n\t\t) {\n\t\t\tconst groupset =\n\t\t\t\ttw.q.type == 'custom-groupset' ? tw.q.customset : tw.term.groupsetting.lst[tw.q.predefined_groupset_idx]\n\t\t\tconst group = groupset.groups.find(group => group.name == key)\n\t\t\tif (!group) throw new Error(`Group not found in groupset for ${tw.term.name}: ${key}`)\n\t\t\ttvsEntry.tvs.values = group.values\n\t\t} else if (tw.term.type === TermTypes.SAMPLELST) {\n\t\t\tif (!tw.term.values?.[key]) throw new Error(`Sample list not found for ${tw.term.name}: ${key}`)\n\t\t\tconst ids = (tw.term.values[key].list || []).map(s => s.sampleId)\n\t\t\t// Returns filter obj with lst array of 1 tvs\n\t\t\tconst tmpTvsLst = getSamplelstFilter(ids)\n\t\t\ttvsEntry = tmpTvsLst.lst[0]\n\t\t} else {\n\t\t\ttvsEntry.tvs.values = [{ key }]\n\t\t}\n\t\tif (tw.term.type === TermTypes.CONDITION) {\n\t\t\tObject.assign(tvsEntry.tvs, {\n\t\t\t\tbar_by_grade: tw.q?.bar_by_grade || null,\n\t\t\t\tvalue_by_max_grade: tw.q.value_by_max_grade\n\t\t\t})\n\t\t}\n\t\treturn tvsEntry\n\t}\n\n\tcreateTvsRanges(tvs: any, termNum: number, key?: string): any {\n\t\tconst tw = this[`t${termNum}`]\n\t\t// continuous term should always use start/stop instead of any computed bin\n\t\tconst bins = tw != this.contTerm && this.bins[`term${termNum}`]\n\t\tconst idOrLabel = key ? key : tw === this.overlayTerm ? this.plot.seriesId : tw === this.t0 ? this.plot.chartId : ''\n\t\tconst hasIdOrLabel = idOrLabel !== '' && idOrLabel != null\n\t\tconst overlayOrChartBin = hasIdOrLabel ? bins?.[String(idOrLabel)] : undefined\n\t\tconst uncomputable = Object.entries(tw.term?.values ?? {}).find(\n\t\t\t([_, v]: [string, any]) => v.label === key && v?.uncomputable\n\t\t)?.[0]?.[0]\n\n\t\tif (overlayOrChartBin) {\n\t\t\ttvs.ranges = [overlayOrChartBin]\n\t\t} else if (uncomputable) {\n\t\t\t/** Uncomputable values will not have bins defined but\n\t\t\t * require a value for filtering. Manually adding the\n\t\t\t * uncomputable key and label filters appropriately.*/\n\t\t\tif (!tvs.ranges) tvs.ranges = []\n\t\t\ttvs.ranges.push({\n\t\t\t\tvalue: uncomputable,\n\t\t\t\tlabel: idOrLabel\n\t\t\t})\n\t\t} else {\n\t\t\t/** Continuous terms may not have bins defined\n\t\t\t * but range property is required. */\n\t\t\ttvs.ranges = []\n\t\t}\n\n\t\tif (!overlayOrChartBin && this.useRange) {\n\t\t\t/** May need to limit the range (e.g. violin brush) or add\n\t\t\t * a range when no bins exist for the query to succeed. */\n\t\t\tif (tvs.ranges.length > 0 && tvs.ranges[0]?.start !== undefined) {\n\t\t\t\ttvs.ranges[0].start = this.start\n\t\t\t\ttvs.ranges[0].stop = this.end\n\t\t\t} else {\n\t\t\t\ttvs.ranges = [\n\t\t\t\t\t{\n\t\t\t\t\t\tstart: this.start,\n\t\t\t\t\t\tstop: this.end,\n\t\t\t\t\t\tstartinclusive: true,\n\t\t\t\t\t\tstopinclusive: true,\n\t\t\t\t\t\tstartunbounded: false,\n\t\t\t\t\t\tstopunbounded: false\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t\treturn tvs\n\t}\n\n\t//TODO: Remove entirely??\n\tisContinuousOrBinned(tw: TermWrapper, termNum: number): boolean {\n\t\tif (!('mode' in tw.q)) return false\n\t\treturn (\n\t\t\ttw.q?.mode === 'continuous' || (isNumericTerm(tw.term) && Object.keys(this.bins[`term${termNum}`]).length != 0)\n\t\t)\n\t}\n\n\tasync getData(): Promise<AnnotatedSampleData> {\n\t\ttry {\n\t\t\tconst opts = {\n\t\t\t\tterms: this.terms,\n\t\t\t\tfilter: filterJoin([this.termfilter.filter, this.tvslst]),\n\t\t\t\tfilter0: this.termfilter.filter0,\n\t\t\t\tisSummary: true\n\t\t\t}\n\t\t\tconst data = await this.app.vocabApi.getAnnotatedSampleData(opts)\n\t\t\tif (!data) throw new Error('No sample data returned')\n\t\t\treturn data\n\t\t} catch (e: any) {\n\t\t\tif (e instanceof Error) throw e\n\t\t\telse {\n\t\t\t\tthrow new Error(`Error fetching sample data: ${e.message || e}`)\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Formats the data for #dom/table/renderTable() */\n\tsetTableData(data: AnnotatedSampleData): [TableRow[], TableColumn[]] {\n\t\t//Validation check\n\t\tconst foundInvalidGvTerm = [this.t1, this.t2, this.t0].find(tw => {\n\t\t\treturn tw && tw.term.type === TermTypes.GENE_VARIANT && (tw?.q as any)?.type == 'values'\n\t\t})\n\t\tif (foundInvalidGvTerm) throw new Error('q.type = values are not supported for gene variant terms')\n\n\t\t//Formatting rows\n\t\tconst rows: { value: string | number }[][] = []\n\t\tconst urlTemplate = this.app.vocabApi.termdbConfig?.urlTemplates?.sample\n\n\t\tfor (const s of Object.values(data.lst)) {\n\t\t\tconst filterSample = this.mayFilterGVSample(s)\n\t\t\tif (filterSample) continue\n\t\t\tconst sampleId = typeof s.sample === 'string' ? s.sample : String(s.sample)\n\t\t\tconst row: any[] = [{ value: data.refs.bySampleId[sampleId].label }]\n\t\t\tif (urlTemplate) {\n\t\t\t\t// sample url template is defined, use it to format sample name as url\n\t\t\t\trow[0].url = urlTemplate.base + (s[urlTemplate.namekey] || s.sample)\n\t\t\t}\n\t\t\tconst term1Sample = s[this.t1.$id!]\n\t\t\tif (term1Sample) {\n\t\t\t\t/** Forcing 'value' property because ts requires explicit property access\n\t\t\t\t * that contradicts with the AnnotatedSampleEntry type definition.\n\t\t\t\t * Both objs are correct in this case.\n\t\t\t\t *\n\t\t\t\t * If modifying this code, double check the types and usages.*/\n\t\t\t\tif (this.t1?.q?.hiddenValues && this.t1.q.hiddenValues?.[term1Sample?.['value']]) {\n\t\t\t\t\tcontinue //skip hidden values\n\t\t\t\t} else this.addRowValue(s, this.t1, row)\n\t\t\t} else continue //skip rows with no term value\n\t\t\tif (this.t2) {\n\t\t\t\tconst term2Sample = s[this.t2.$id!]\n\t\t\t\tif (!term2Sample) continue\n\t\t\t\tif (this.t2?.q?.hiddenValues && this.t2.q.hiddenValues?.[term2Sample?.['value']]) continue //skip hidden values\n\t\t\t\tthis.addRowValue(s, this.t2, row)\n\t\t\t}\n\t\t\tif (this.t0) {\n\t\t\t\tconst term0Sample = s[this.t0.$id!]\n\t\t\t\tif (!term0Sample) continue\n\t\t\t\tif (this.t0?.q?.hiddenValues && this.t0.q.hiddenValues?.[term0Sample?.['value']]) continue //skip hidden values\n\t\t\t\tthis.addRowValue(s, this.t0, row)\n\t\t\t}\n\t\t\trows.push(row)\n\t\t}\n\n\t\t//Formatting columns\n\t\tconst columns: TableColumn[] = [{ label: 'Sample' }]\n\t\tthis.addColValue(this.t1, columns)\n\t\tif (this.t2) this.addColValue(this.t2, columns)\n\t\tif (this.t0) this.addColValue(this.t0, columns)\n\n\t\treturn [rows, columns]\n\t}\n\n\tmayFilterGVSample(sample: AnnotatedSampleEntry): boolean {\n\t\tlet filterSample = false\n\t\tfor (const [idx, tw] of [this.t0, this.t1, this.t2].entries()) {\n\t\t\tif (!tw) continue\n\t\t\tif (tw.term.type !== TermTypes.GENE_VARIANT) continue\n\t\t\tif (!this.geneVariant[`t${idx}value`]) continue\n\t\t\t/** See comment in setTableData() about 'value' property */\n\t\t\tconst value = sample?.[tw.$id!]?.['value']\n\t\t\tif (value != this.geneVariant[`t${idx}value`]) {\n\t\t\t\tfilterSample = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn filterSample\n\t}\n\n\taddRowValue(s: any, tw: TermWrapper, row: TableRow): void {\n\t\tif (tw.term.type === TermTypes.GENE_VARIANT) {\n\t\t\t//This func mutates row directly\n\t\t\taddGvRowVals(s, tw, row, this.app.vocabApi.termdbConfig?.mclass)\n\t\t\treturn\n\t\t}\n\n\t\tconst sample = s[tw.$id!]\n\t\tlet formattedVal\n\t\tif (isNumericTerm(tw.term)) {\n\t\t\tformattedVal = roundValueAuto(sample.value)\n\t\t} else if (tw.term.type === TermTypes.SURVIVAL) {\n\t\t\t/** Use key for term value, not value (value == time elapsed) */\n\t\t\tformattedVal = tw.term.values?.[sample.key]?.label || sample.key\n\t\t} else if (tw.term.type === TermTypes.TERM_COLLECTION && typeof sample.value === 'object') {\n\t\t\t/** termCollection value is a JSON object of {memberId: numericValue, ...}.\n\t\t\t * Format as a readable string using member term names when available. */\n\t\t\tconst termlst: any[] = (tw.term as any).termlst || []\n\t\t\tconst parts: string[] = []\n\t\t\tfor (const [id, val] of Object.entries(sample.value)) {\n\t\t\t\tconst name = termlst.find((t: any) => (t.id || t.name) === id)?.name || id\n\t\t\t\tparts.push(`${name}: ${roundValueAuto(val as number)}`)\n\t\t\t}\n\t\t\tformattedVal = parts.join(', ')\n\t\t} else {\n\t\t\tformattedVal = tw.term.values?.[sample.value]?.label || sample.value\n\t\t}\n\t\trow.push({ value: formattedVal })\n\t}\n\n\taddColValue(tw: TermWrapper, columns: TableColumn[]): void {\n\t\tif (tw.term.type === TermTypes.GENE_VARIANT) {\n\t\t\t//This func mutates columns directly\n\t\t\taddGvCols(tw, columns)\n\t\t} else {\n\t\t\tcolumns.push({ label: tw.term.name })\n\t\t}\n\t}\n}\n", "import { handler as _handler } from './tvs.categorical.js'\nimport { renderVariantConfig } from '#dom'\nimport { mclass, dtsnvindel } from '#shared/common.js'\nimport { FrontendVocab } from '#termdb/FrontendVocab'\n\n/*\nBase TVS handler for dt terms\n\nTODO: may move dom/variantConfig here\n*/\n\nexport const handler = Object.assign({}, _handler, { fillMenu, term_name_gen, get_pill_label })\n\nasync function fillMenu(self, div, tvs) {\n\t// get mutations from dataset\n\tconst term = structuredClone(tvs.term)\n\tawait getDtTermValues(term, self.filter, self.opts.vocabApi)\n\t// render variant config\n\tconst arg = {\n\t\tholder: div,\n\t\theader: term.parentTerm.name + ' ' + term.name,\n\t\tvalues: term.values,\n\t\tselectedValues: tvs.values,\n\t\tgenotype: tvs.genotype,\n\t\tdt: term.dt,\n\t\tmcount: tvs.mcount,\n\t\tcallback: config => {\n\t\t\tconst new_tvs = structuredClone(tvs)\n\t\t\tObject.assign(new_tvs, config)\n\t\t\tself.dom.tip.hide()\n\t\t\tself.opts.callback(new_tvs)\n\t\t}\n\t}\n\tconst mafFilter = self.opts.vocabApi.termdbConfig?.queries?.snvindel?.mafFilter\n\tif (mafFilter && term.dt == dtsnvindel) {\n\t\t// maf filter specified in dataset\n\t\tmafFilter.active = tvs.mafFilter || mafFilter.filter\n\t\targ.mafFilter = mafFilter\n\t}\n\trenderVariantConfig(arg)\n}\n\nfunction term_name_gen(d) {\n\tconst name = d.term.parentTerm && !d.excludeGeneName ? `${d.term.parentTerm.name} ${d.term.name}` : d.term.name\n\treturn name.length < 31 ? name : '<label title=\"' + name + '\">' + name.substring(0, 28) + '...' + '</label>'\n}\n\nfunction get_pill_label(tvs) {\n\tlet txt\n\tif (tvs.genotype == 'variant') {\n\t\tif (tvs.values.length == 1) {\n\t\t\t// single mutation class\n\t\t\ttxt = tvs.values[0].label\n\t\t} else {\n\t\t\t// multiple mutation classes\n\t\t\tif (tvs.term.dt == 1) txt = 'Mutated'\n\t\t\telse txt = 'Altered'\n\t\t}\n\t} else if (tvs.genotype == 'wt') {\n\t\t// wildtype genotype\n\t\ttxt = 'Wildtype'\n\t} else if (tvs.genotype == 'nt') {\n\t\t// not tested\n\t\ttxt = 'Not tested'\n\t} else {\n\t\tthrow 'tvs.genotype not recognized'\n\t}\n\treturn { txt }\n}\n\n// get mutation classes of dt term\n// will store these classes in term.values\nexport async function getDtTermValues(dtTerm, filter, vocabApi) {\n\tif (vocabApi instanceof FrontendVocab) {\n\t\t// geneVariant frontend vocab, cannot get values from db\n\t\t// use values already present on dt term\n\t\treturn\n\t}\n\n\t// get mutation classes of gene\n\tconst body = { term1_q: { dtLst: [dtTerm.dt] } }\n\tconst categories = await vocabApi.getCategories(dtTerm.parentTerm, filter, body)\n\t// filter for mutations of specific dt\n\tif (!categories) throw new Error('unable to retrieve variant data')\n\n\t// filter for mutations of specific dt\n\tconst data = categories?.lst.find(x => x.dt == dtTerm.dt)\n\tif (!data) return\n\tconst byOrigin = vocabApi.termdbConfig.assayAvailability?.byDt[dtTerm.dt]?.byOrigin\n\tconst classes = byOrigin ? data.classes.byOrigin[dtTerm.origin] : data.classes\n\t// store mutation classes in term.values\n\tdtTerm.values = Object.fromEntries(\n\t\tObject.keys(classes)\n\t\t\t.filter(k => k != 'Blank' && k != 'WT')\n\t\t\t.map(k => {\n\t\t\t\treturn [k, { key: k, label: vocabApi.termdbConfig.mclass?.[k]?.label || mclass[k].label }]\n\t\t\t})\n\t)\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["id", "event", "appear", "disappear", "gmmode", "tkt", "t", "tkt", "gmmode", "appear", "disappear", "event", "types", "i", "div", "t", "tr", "rgb", "event", "id", "i", "range", "i", "event", "i", "event", "checked", "handler", "i", "id", "$id", "filter", "i", "setRenderers", "i", "event", "filter", "t", "setInteractivity", "event", "filter", "d", "i", "t", "jwt", "cache", "i", "match", "filter", "term", "data", "t", "i", "key", "id", "body", "$id", "t", "i", "key", "id", "filter", "term", "minvalue", "t", "setInteractivity", "setRenderers", "i", "filter", "$id", "i", "match", "process", "dataURL", "_a", "i", "id", "match", "format", "_a", "cache", "font", "node", "filter", "i", "i", "filter", "i", "termType", "event", "geneSymbol", "tip", "event", "import_debounce", "event", "t", "t", "i", "event", "id", "i", "d", "x", "start", "stop", "ctx", "h", "pad", "i", "i", "r", "event", "value", "termType", "termType", "termType", "termType", "termType", "termType", "id", "termType", "termType", "i", "termType", "t", "termType", "t", "t", "t", "t", "i", "name", "q", "filter", "i", "colorScale", "vocabApi", "filter", "term", "t", "range", "get$id", "QualitativeBase", "idSuffix", "get$id", "i", "id", "t", "i", "i", "i", "i", "acc", "ext", "start", "final", "ext", "qmark", "star", "defaults", "regExpEscape", "i", "event", "event", "get$id", "t", "globImport_handlers_ts", "get$id", "event", "t", "i", "setRenderers", "t", "event", "i", "event", "path", "event", "import_debounce", "event", "setInteractivity", "setRenderers", "filter", "event", "t", "id", "i", "SINGLECELL_CELLTYPE", "SINGLECELL_GENE_EXPRESSION", "TERM_COLLECTION", "METABOLITE_INTENSITY", "GENE_EXPRESSION", "ISOFORM_EXPRESSION", "DNA_METHYLATION", "PROTEOME_ABUNDANCE", "SSGSEA", "globImport_handlers_ts", "t", "event", "i", "tab", "handler", "types", "i", "filter", "setRenderers", "import_debounce", "setRenderers", "setInteractivity", "t", "event", "i", "t", "event", "row", "callback", "detail", "t", "i", "d", "t", "opts", "event", "defaults", "i", "_opts", "t", "i", "setRenderers", "event", "t", "activeTabIndex", "i", "event", "box", "setRenderers", "t", "event", "getId", "id", "defaults", "termType", "colorScale", "i", "event", "get$id", "id", "addNewGroup", "group", "tw", "filter", "instanceNum", "setRenderers", "id", "debouncedDispatch", "dispatchChange", "event", "option", "d", "i", "setInteractivity", "setRenderers", "event", "i", "setRenderers", "setInteractivity", "t", "id", "bin", "filter", "chart", "a", "i", "event", "event", "id", "term2", "self", "tvslst", "d", "tvs", "group", "i", "value", "filter", "addNewGroup", "mlst", "t", "i", "range", "d", "group", "id", "t", "handler", "filter"]
|
|
7
|
-
}
|