gramene-search 1.2.84 → 1.2.86

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.
Files changed (108) hide show
  1. package/.parcel-cache/2126881b633272fa.txt +2 -2
  2. package/.parcel-cache/425346ba6a54d932 +0 -0
  3. package/.parcel-cache/878e3ffbad677982 +0 -0
  4. package/.parcel-cache/a6c49560dea3583b +0 -0
  5. package/.parcel-cache/cdecf11601322051 +0 -0
  6. package/.parcel-cache/data.mdb +0 -0
  7. package/.parcel-cache/lock.mdb +0 -0
  8. package/dist/index.css +97 -0
  9. package/dist/index.css.map +1 -1
  10. package/dist/index.js +463 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/static/atlasWidget.html +26 -0
  13. package/dist/static/gramene-dalliance/css/bootstrap-scoped.css +4511 -0
  14. package/dist/static/gramene-dalliance/css/dalliance-scoped.css +456 -0
  15. package/dist/static/gramene-dalliance/css/font-awesome.min.css +4 -0
  16. package/dist/static/gramene-dalliance/dalliance-all.js +15 -0
  17. package/dist/static/gramene-dalliance/fonts/FontAwesome.otf +0 -0
  18. package/dist/static/gramene-dalliance/fonts/fontawesome-webfont.eot +0 -0
  19. package/dist/static/gramene-dalliance/fonts/fontawesome-webfont.svg +414 -0
  20. package/dist/static/gramene-dalliance/fonts/fontawesome-webfont.ttf +0 -0
  21. package/dist/static/gramene-dalliance/fonts/fontawesome-webfont.woff +0 -0
  22. package/dist/static/gramene-dalliance/img/README.md +3 -0
  23. package/dist/static/gramene-dalliance/img/glyphicons-halflings.png +0 -0
  24. package/dist/static/gramene-dalliance/img/loader.gif +0 -0
  25. package/dist/static/gramene-dalliance/img/spinner_16.gif +0 -0
  26. package/dist/static/gramene-dalliance/img/spinner_192.gif +0 -0
  27. package/dist/static/gramene-dalliance/img/spinner_24.gif +0 -0
  28. package/dist/static/gramene-dalliance/img/spinner_32.gif +0 -0
  29. package/dist/static/gramene-dalliance/img/spinner_48.gif +0 -0
  30. package/dist/static/gramene-dalliance/img/spinner_96.gif +0 -0
  31. package/dist/static/gramene-dalliance/worker-all.js +4 -0
  32. package/dist/static/icons/android-chrome-192x192.png +0 -0
  33. package/dist/static/icons/apple-touch-icon-114x114.png +0 -0
  34. package/dist/static/icons/apple-touch-icon-120x120.png +0 -0
  35. package/dist/static/icons/apple-touch-icon-144x144.png +0 -0
  36. package/dist/static/icons/apple-touch-icon-152x152.png +0 -0
  37. package/dist/static/icons/apple-touch-icon-180x180.png +0 -0
  38. package/dist/static/icons/apple-touch-icon-57x57.png +0 -0
  39. package/dist/static/icons/apple-touch-icon-60x60.png +0 -0
  40. package/dist/static/icons/apple-touch-icon-72x72.png +0 -0
  41. package/dist/static/icons/apple-touch-icon-76x76.png +0 -0
  42. package/dist/static/icons/apple-touch-icon-precomposed.png +0 -0
  43. package/dist/static/icons/apple-touch-icon.png +0 -0
  44. package/dist/static/icons/favicon-16x16.png +0 -0
  45. package/dist/static/icons/favicon-32x32.png +0 -0
  46. package/dist/static/icons/favicon-96x96.png +0 -0
  47. package/dist/static/icons/favicon.ico +0 -0
  48. package/dist/static/images/e_bang.png +0 -0
  49. package/dist/static/images/genetree.png +0 -0
  50. package/dist/static/images/gramene_logo.svg +69 -0
  51. package/dist/static/images/gramene_logo_white_letters.svg +69 -0
  52. package/dist/static/images/grapevine_logo.svg +70 -0
  53. package/dist/static/images/grapevine_logo_white_letters.svg +70 -0
  54. package/dist/static/images/logo.svg +71 -0
  55. package/dist/static/images/main_logo.svg +70 -0
  56. package/dist/static/images/main_logo_white_letters.svg +70 -0
  57. package/dist/static/images/maize_logo.svg +70 -0
  58. package/dist/static/images/maize_logo_white_letters.svg +70 -0
  59. package/dist/static/images/oryza_logo.svg +70 -0
  60. package/dist/static/images/oryza_logo_white_letters.svg +70 -0
  61. package/dist/static/images/results.png +0 -0
  62. package/dist/static/images/sorghum_logo.svg +2667 -0
  63. package/dist/static/images/suggestions.png +0 -0
  64. package/dist/static/images/welcome/BLAST.png +0 -0
  65. package/dist/static/images/welcome/Biomart250.png +0 -0
  66. package/dist/static/images/welcome/ExpressionAtlas.png +0 -0
  67. package/dist/static/images/welcome/TrackHub.png +0 -0
  68. package/dist/static/images/welcome/archive.jpg +0 -0
  69. package/dist/static/images/welcome/climtools.png +0 -0
  70. package/dist/static/images/welcome/curated.png +0 -0
  71. package/dist/static/images/welcome/download.png +0 -0
  72. package/dist/static/images/welcome/ensemblgramene.png +0 -0
  73. package/dist/static/images/welcome/gene_view.png +0 -0
  74. package/dist/static/images/welcome/genomes.png +0 -0
  75. package/dist/static/images/welcome/maize/NAM.png +0 -0
  76. package/dist/static/images/welcome/maize/lox-align-overview.png +0 -0
  77. package/dist/static/images/welcome/maize/lox-expression.png +0 -0
  78. package/dist/static/images/welcome/maize/lox-homologs.png +0 -0
  79. package/dist/static/images/welcome/maize/lox-malign.png +0 -0
  80. package/dist/static/images/welcome/maize/lox-neighborhood.png +0 -0
  81. package/dist/static/images/welcome/maize/lox-pathways.png +0 -0
  82. package/dist/static/images/welcome/maize/lox-suggestions.png +0 -0
  83. package/dist/static/images/welcome/maize/lox3-neighborhood.png +0 -0
  84. package/dist/static/images/welcome/noun_553934.png +0 -0
  85. package/dist/static/images/welcome/noun_553934.svg +1 -0
  86. package/dist/static/images/welcome/pangenomes.svg +1 -0
  87. package/dist/static/images/welcome/pathways.png +0 -0
  88. package/dist/static/images/welcome/plantReactome.svg +4 -0
  89. package/dist/static/images/welcome/suggestions.png +0 -0
  90. package/dist/static/images/welcome/tools.png +0 -0
  91. package/dist/static/images/welcome/vis.png +0 -0
  92. package/dist/static/images/yeast_logo.png +0 -0
  93. package/dist/static/images/yeast_logo.svg +6469 -0
  94. package/dist/static/socialMedia.html +8 -0
  95. package/dist/static/style.css +69 -0
  96. package/package.json +1 -1
  97. package/src/bundles/api.js +9 -1
  98. package/src/bundles/docs.js +81 -2
  99. package/src/components/results/GeneList.js +11 -3
  100. package/src/components/results/details/Sequences.js +239 -0
  101. package/src/components/results/details/sequences.css +85 -0
  102. package/src/demo.js +41 -5
  103. package/src/grapevine.html +1 -10
  104. /package/.parcel-cache/{922dda8e2da89cf8 → 06faa2578dc5a59b} +0 -0
  105. /package/.parcel-cache/{34b08e2ef3b4c1b4 → 328d87ee8e027da9} +0 -0
  106. /package/.parcel-cache/{c3913eb508a15bfd → 37a1f6034ac61c5a} +0 -0
  107. /package/.parcel-cache/{638cb1f366e4e58e → b4cc8a95482d8318} +0 -0
  108. /package/.parcel-cache/{f8d6dcbbd15ac819 → f005e65af5a9c51c} +0 -0
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ var $gXNCa$lodashisEqual = require("lodash/isEqual");
21
21
  var $gXNCa$flattonested = require("flat-to-nested");
22
22
  var $gXNCa$reactsimpletreemenu = require("react-simple-tree-menu");
23
23
  var $gXNCa$gramenedbxrefs = require("gramene-dbxrefs");
24
+ var $gXNCa$reacticonsai = require("react-icons/ai");
24
25
  var $gXNCa$gramenesearchvis = require("gramene-search-vis");
25
26
  var $gXNCa$numeral = require("numeral");
26
27
 
@@ -133,7 +134,15 @@ const $9d9aeaf9299e61a1$var$grameneMaps = (0, $gXNCa$reduxbundler.createAsyncRes
133
134
  actionBaseType: "GRAMENE_MAPS",
134
135
  persist: true,
135
136
  getPromise: ({ store: store })=>{
136
- return fetch(`${store.selectGrameneAPI()}/maps?rows=-1`).then((res)=>res.json()).then((maps)=>(0, ($parcel$interopDefault($gXNCa$lodash))).keyBy(maps, "taxon_id"));
137
+ return fetch(`${store.selectGrameneAPI()}/maps?rows=-1`).then((res)=>res.json()).then((maps)=>{
138
+ maps.forEach((m)=>{
139
+ m.regionLength = {};
140
+ m.regions.names.forEach((rname, idx)=>{
141
+ m.regionLength[rname] = m.regions.lengths[idx];
142
+ });
143
+ });
144
+ return (0, ($parcel$interopDefault($gXNCa$lodash))).keyBy(maps, "taxon_id");
145
+ });
137
146
  }
138
147
  });
139
148
  $9d9aeaf9299e61a1$var$grameneMaps.reactGrameneMaps = (0, $gXNCa$reduxbundler.createSelector)("selectGrameneMapsShouldUpdate", (shouldUpdate)=>{
@@ -1197,7 +1206,9 @@ const $671312b287158a8a$var$grameneDocs = {
1197
1206
  trees: {},
1198
1207
  domains: {},
1199
1208
  pathways: {},
1200
- expression: {}
1209
+ expression: {},
1210
+ sequences: {},
1211
+ studies: {}
1201
1212
  };
1202
1213
  return (state = initialState, { type: type , payload: payload })=>{
1203
1214
  let newState;
@@ -1236,6 +1247,33 @@ const $671312b287158a8a$var$grameneDocs = {
1236
1247
  newState = Object.assign({}, state);
1237
1248
  newState.pathways = Object.assign({}, state.pathways, payload);
1238
1249
  return newState;
1250
+ case "ATLAS_STUDIES_RECEIVED":
1251
+ newState = Object.assign({}, state);
1252
+ newState.studies = Object.assign({}, state.studies, payload);
1253
+ return newState;
1254
+ case "ATLAS_SAMPLES_REQUESTED":
1255
+ if (!state.studies[payload].hasOwnProperty("samples")) {
1256
+ newState = Object.assign({}, state);
1257
+ newState.studies[payload].samples = [];
1258
+ return newState;
1259
+ }
1260
+ break;
1261
+ case "ATLAS_SAMPLES_RECEIVED":
1262
+ newState = Object.assign({}, state);
1263
+ newState.studies[payload.id].samples = payload.samples;
1264
+ return newState;
1265
+ case "GENE_SEQUENCE_REQUESTED":
1266
+ if (!state.sequences.hasOwnProperty(payload)) {
1267
+ newState = Object.assign({}, state);
1268
+ newState.sequences[payload] = {};
1269
+ return newState;
1270
+ }
1271
+ break;
1272
+ case "GENE_SEQUENCE_RECEIVED":
1273
+ newState = Object.assign({}, state);
1274
+ newState.sequences = Object.assign({}, state.sequences);
1275
+ newState.sequences[payload.id] = payload.geneSeq;
1276
+ return newState;
1239
1277
  case "PARALOG_EXPRESSION_REQUESTED":
1240
1278
  if (!state.expression.hasOwnProperty(payload)) {
1241
1279
  newState = Object.assign({}, state);
@@ -1307,6 +1345,7 @@ const $671312b287158a8a$var$grameneDocs = {
1307
1345
  type: "GRAMENE_PATHWAYS_REQUESTED",
1308
1346
  payload: newIds
1309
1347
  });
1348
+ if (newIds.length === 1) newIds.push(0);
1310
1349
  fetch(`${store.selectGrameneAPI()}/pathways?idList=${newIds.join(",")}`).then((res)=>res.json()).then((res)=>{
1311
1350
  let pathways = {};
1312
1351
  res.forEach((p)=>{
@@ -1319,6 +1358,66 @@ const $671312b287158a8a$var$grameneDocs = {
1319
1358
  });
1320
1359
  }
1321
1360
  },
1361
+ doRequestExpressionStudies: (id)=>({ dispatch: dispatch , store: store })=>{
1362
+ fetch(`${store.selectGrameneAPI()}/experiments?rows=-1`).then((res)=>res.json()).then((res)=>{
1363
+ let studies = {};
1364
+ res.forEach((s)=>{
1365
+ studies[s._id] = s;
1366
+ if (!studies.hasOwnProperty("taxon_id")) studies[s.taxon_id] = [];
1367
+ studies[s.taxon_id].push(s._id);
1368
+ });
1369
+ dispatch({
1370
+ type: "ATLAS_STUDIES_RECEIVED",
1371
+ payload: studies
1372
+ });
1373
+ });
1374
+ },
1375
+ doRequestStudyMetadata: (id)=>({ dispatch: dispatch , store: store })=>{
1376
+ const studies = store.selectAtlasStudies();
1377
+ if (!studies[id].hasOwnProperty("samples")) {
1378
+ dispatch({
1379
+ type: "ATLAS_SAMPLES_REQUESTED",
1380
+ payload: id
1381
+ });
1382
+ fetch(`${store.selectGrameneAPI()}/assays?experiment=${id}&rows=-1`).then((res)=>res.json()).then((samples)=>{
1383
+ dispatch({
1384
+ type: "ATLAS_SAMPLES_RECEIVED",
1385
+ payload: {
1386
+ id: id,
1387
+ samples: samples
1388
+ }
1389
+ });
1390
+ });
1391
+ }
1392
+ },
1393
+ doRequestGeneSequence: (gene)=>({ dispatch: dispatch , store: store })=>{
1394
+ const maps = store.selectGrameneMaps();
1395
+ const seqs = store.selectGeneSequences();
1396
+ const id = gene._id;
1397
+ const MAX_FLANK = 2000;
1398
+ if (!seqs.hasOwnProperty(id)) {
1399
+ dispatch({
1400
+ type: "GENE_SEQUENCE_REQUESTED",
1401
+ payload: id
1402
+ });
1403
+ const start = gene.location.start > MAX_FLANK ? gene.location.start - MAX_FLANK : 1;
1404
+ const dnaLength = maps[gene.taxon_id].regionLength[gene.location.region];
1405
+ const end = gene.location.end + MAX_FLANK > dnaLength ? dnaLength : gene.location.end + MAX_FLANK;
1406
+ fetch(`${store.selectEnsemblAPI()}/sequence/region/${gene.system_name}/${gene.location.region}:${start}..${end}:${gene.location.strand}?content-type=application/json`).then((res)=>res.json()).then((geneSeq)=>{
1407
+ const x = geneSeq.id.split(":");
1408
+ geneSeq.genome = x[1];
1409
+ geneSeq.start = +x[3];
1410
+ geneSeq.end = +x[4];
1411
+ dispatch({
1412
+ type: "GENE_SEQUENCE_RECEIVED",
1413
+ payload: {
1414
+ id: id,
1415
+ geneSeq: geneSeq
1416
+ }
1417
+ });
1418
+ });
1419
+ }
1420
+ },
1322
1421
  doRequestParalogExpression: (id)=>({ dispatch: dispatch , store: store })=>{
1323
1422
  const expr = store.selectParalogExpression();
1324
1423
  if (!expr.hasOwnProperty(id)) {
@@ -1370,7 +1469,9 @@ const $671312b287158a8a$var$grameneDocs = {
1370
1469
  selectGrameneGenes: (state)=>state.grameneDocs.genes,
1371
1470
  selectGrameneTrees: (state)=>state.grameneDocs.trees,
1372
1471
  selectGramenePathways: (state)=>state.grameneDocs.pathways,
1373
- selectParalogExpression: (state)=>state.grameneDocs.expression
1472
+ selectParalogExpression: (state)=>state.grameneDocs.expression,
1473
+ selectGeneSequences: (state)=>state.grameneDocs.sequences,
1474
+ selectAtlasStudies: (state)=>state.grameneDocs.studies
1374
1475
  };
1375
1476
  var $671312b287158a8a$export$2e2bcd8739ae039 = $671312b287158a8a$var$grameneDocs;
1376
1477
 
@@ -3183,6 +3284,357 @@ var $830f925242a0b007$export$2e2bcd8739ae039 = $830f925242a0b007$var$Publication
3183
3284
 
3184
3285
 
3185
3286
 
3287
+
3288
+
3289
+
3290
+
3291
+ const $527ebc19dc92444d$var$CodeBlock = (props)=>{
3292
+ const plainFasta = `>${props.id}\n${props.seq}`;
3293
+ const [showNotification, setShowNotification] = (0, $gXNCa$react.useState)(false);
3294
+ const copyCode = ()=>{
3295
+ // Use the Clipboard API to write text to the clipboard
3296
+ navigator.clipboard.writeText(plainFasta).then(()=>{
3297
+ setShowNotification(true);
3298
+ }).catch((err)=>{
3299
+ console.error("Unable to copy to clipboard", err);
3300
+ });
3301
+ };
3302
+ (0, $gXNCa$react.useEffect)(()=>{
3303
+ if (showNotification) {
3304
+ const notificationTimeout = setTimeout(()=>{
3305
+ setShowNotification(false);
3306
+ }, 2000); // Hide the notification after 2 seconds
3307
+ return ()=>clearTimeout(notificationTimeout);
3308
+ }
3309
+ }, [
3310
+ showNotification
3311
+ ]);
3312
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
3313
+ className: "fasta-container",
3314
+ children: [
3315
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("code", {
3316
+ className: "fasta",
3317
+ children: [
3318
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("b", {
3319
+ children: "Key:"
3320
+ }),
3321
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3322
+ className: "upstream",
3323
+ children: "--upstream--"
3324
+ }),
3325
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3326
+ className: "utr5",
3327
+ children: "--5'UTR--"
3328
+ }),
3329
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3330
+ className: "cds",
3331
+ children: "--Coding exon--"
3332
+ }),
3333
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3334
+ className: "intron",
3335
+ children: "--intron--"
3336
+ }),
3337
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3338
+ className: "cds",
3339
+ children: "--Coding exon--"
3340
+ }),
3341
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3342
+ className: "utr3",
3343
+ children: "--3'UTR--"
3344
+ }),
3345
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3346
+ className: "downstream",
3347
+ children: "--downstream--"
3348
+ }),
3349
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("br", {}),
3350
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("br", {})
3351
+ ]
3352
+ }),
3353
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("code", {
3354
+ className: "fasta",
3355
+ children: [
3356
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("span", {
3357
+ className: "header",
3358
+ children: [
3359
+ ">",
3360
+ props.id
3361
+ ]
3362
+ }),
3363
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("br", {}),
3364
+ props.blocks.map((block, idx)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3365
+ className: block.kind,
3366
+ children: block.seq
3367
+ }, idx))
3368
+ ]
3369
+ }),
3370
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("button", {
3371
+ className: "copy-button",
3372
+ onClick: copyCode,
3373
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reacticonsai.AiOutlineCopy), {})
3374
+ }),
3375
+ showNotification && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3376
+ className: "notification",
3377
+ children: "Sequence copied"
3378
+ })
3379
+ ]
3380
+ });
3381
+ };
3382
+ const $527ebc19dc92444d$var$decorateDNA = (geneSeq, gene, up, down, tid)=>{
3383
+ // return a list of blocks with kind and seq properties
3384
+ let blocks = [];
3385
+ const transcript = gene.gene_structure.transcripts.find((tr)=>tr.id === tid);
3386
+ const offset = gene.location.strand === 1 ? gene.location.start - geneSeq.start : geneSeq.end - gene.location.end;
3387
+ if (up > 0) {
3388
+ const TSS = gene.gene_structure.exons.find((exon)=>exon.id === transcript.exons[0]).start;
3389
+ blocks.push({
3390
+ kind: "upstream",
3391
+ seq: geneSeq.seq.substring(offset - up + TSS - 1, offset + TSS - 1).toLowerCase()
3392
+ });
3393
+ }
3394
+ // add exons and introns based on tid
3395
+ let pos_in_transcript = 0;
3396
+ let pos_in_gene = 0;
3397
+ let blockType = "utr5";
3398
+ transcript.exons.forEach((eid, e_idx)=>{
3399
+ const exon = gene.gene_structure.exons.find((exon)=>exon.id === eid);
3400
+ if (exon.start > 1) {
3401
+ let intronBlock = {
3402
+ kind: "intron",
3403
+ seq: geneSeq.seq.substring(offset + pos_in_gene, offset + exon.start - 1).toLowerCase()
3404
+ };
3405
+ // actually, don't do this blocks.push(intronBlock);
3406
+ pos_in_gene = exon.start - 1;
3407
+ }
3408
+ let exon_length = exon.end - exon.start + 1;
3409
+ if (transcript.cds && pos_in_transcript < transcript.cds.start && pos_in_transcript + exon_length >= transcript.cds.start) {
3410
+ // CDS starts in this exon
3411
+ const utr5_len = transcript.cds.start - pos_in_transcript - 1;
3412
+ if (utr5_len > 0) {
3413
+ blocks.push({
3414
+ kind: blockType,
3415
+ seq: geneSeq.seq.substring(offset + pos_in_gene, offset + pos_in_gene + utr5_len)
3416
+ });
3417
+ exon_length -= utr5_len;
3418
+ pos_in_gene += utr5_len;
3419
+ pos_in_transcript = transcript.cds.start - 1;
3420
+ }
3421
+ blockType = "cds";
3422
+ }
3423
+ if (blockType === "cds" && pos_in_transcript + exon_length >= transcript.cds.end) {
3424
+ // CDS ends in this exon
3425
+ const cds_len = transcript.cds.end - pos_in_transcript;
3426
+ if (cds_len > 0) {
3427
+ blocks.push({
3428
+ kind: blockType,
3429
+ seq: geneSeq.seq.substring(offset + pos_in_gene, offset + pos_in_gene + cds_len)
3430
+ });
3431
+ exon_length -= cds_len;
3432
+ pos_in_gene += cds_len;
3433
+ pos_in_transcript = transcript.cds.end;
3434
+ }
3435
+ blockType = "utr3";
3436
+ }
3437
+ if (exon_length > 0) blocks.push({
3438
+ kind: blockType,
3439
+ seq: geneSeq.seq.substring(offset + pos_in_gene, offset + pos_in_gene + exon_length)
3440
+ });
3441
+ pos_in_gene = exon.end;
3442
+ pos_in_transcript += exon_length;
3443
+ });
3444
+ // check if there's more to the gene locus after end of transcript?
3445
+ // downstream is currently relative to end of transcript but upstream is relative to first TSS
3446
+ if (down > 0) blocks.push({
3447
+ kind: "downstream",
3448
+ seq: geneSeq.seq.substring(offset + pos_in_gene, offset + pos_in_gene + down).toLowerCase()
3449
+ });
3450
+ return blocks;
3451
+ };
3452
+ const $527ebc19dc92444d$var$buildId = (gene, geneSeq, up, down)=>{
3453
+ let gs = gene.location.strand === 1 ? gene.location.start - up : gene.location.start - down;
3454
+ let ge = gene.location.strand === 1 ? gene.location.end + down : gene.location.end + up;
3455
+ let extras = [];
3456
+ if (gene.location.strand === -1) extras.push("reverse");
3457
+ if (up > 0) extras.push(`upstream=${up}`);
3458
+ if (down > 0) extras.push(`downstream=${down}`);
3459
+ return `${geneSeq.genome}|${gene._id}|${gene.location.region}:${gs}..${ge} ${extras.join("|")}`;
3460
+ };
3461
+ const $527ebc19dc92444d$var$Detail = (props)=>{
3462
+ const gene = props.geneDocs[props.searchResult.id];
3463
+ let geneSeq;
3464
+ if (props.geneSequences && props.geneSequences[gene._id]) geneSeq = props.geneSequences[gene._id];
3465
+ else {
3466
+ props.doRequestGeneSequence(gene);
3467
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("pre", {
3468
+ children: "loading"
3469
+ });
3470
+ }
3471
+ const maxUp = gene.location.strand === 1 ? gene.location.start - geneSeq.start : geneSeq.end - gene.location.end;
3472
+ const maxDown = gene.location.strand === -1 ? gene.location.start - geneSeq.start : geneSeq.end - gene.location.end;
3473
+ const [upstream, setUpstream] = (0, $gXNCa$react.useState)(0);
3474
+ const [downstream, setDownstream] = (0, $gXNCa$react.useState)(0);
3475
+ const [tid, setTid] = (0, $gXNCa$react.useState)(gene.gene_structure.canonical_transcript);
3476
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Tabs), {
3477
+ children: [
3478
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Tab), {
3479
+ tabClassName: "dna",
3480
+ eventKey: "dna",
3481
+ title: "Genomic sequence",
3482
+ children: [
3483
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Container), {
3484
+ style: {
3485
+ width: "100ch",
3486
+ marginLeft: 0
3487
+ },
3488
+ children: [
3489
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Row), {
3490
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Col), {
3491
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("b", {
3492
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("i", {
3493
+ children: "Show flanking sequence"
3494
+ })
3495
+ })
3496
+ })
3497
+ }),
3498
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Row), {
3499
+ children: [
3500
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Col), {
3501
+ style: {
3502
+ maxWidth: "5ch",
3503
+ textAlign: "right"
3504
+ },
3505
+ children: upstream
3506
+ }),
3507
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Col), {
3508
+ style: {
3509
+ maxWidth: "20ch"
3510
+ },
3511
+ children: [
3512
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Range, {
3513
+ className: "reverse-slide",
3514
+ value: upstream,
3515
+ onChange: (e)=>setUpstream(e.target.value),
3516
+ min: 0,
3517
+ max: maxUp,
3518
+ step: 10
3519
+ }),
3520
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3521
+ style: {
3522
+ textAlign: "right"
3523
+ },
3524
+ children: "Upstream"
3525
+ })
3526
+ ]
3527
+ }),
3528
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Col), {
3529
+ style: {
3530
+ maxWidth: "30ch"
3531
+ },
3532
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
3533
+ className: "styled-span",
3534
+ children: [
3535
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3536
+ className: "vertical-line"
3537
+ }),
3538
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3539
+ className: "horizontal-line"
3540
+ }),
3541
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
3542
+ children: "Transcript (unspliced)"
3543
+ }),
3544
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3545
+ className: "horizontal-line"
3546
+ }),
3547
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3548
+ className: "vertical-line"
3549
+ })
3550
+ ]
3551
+ })
3552
+ }),
3553
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Col), {
3554
+ style: {
3555
+ maxWidth: "20ch"
3556
+ },
3557
+ children: [
3558
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Form).Range, {
3559
+ value: downstream,
3560
+ onChange: (e)=>setDownstream(e.target.value),
3561
+ min: 0,
3562
+ max: maxDown,
3563
+ step: 10
3564
+ }),
3565
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
3566
+ style: {
3567
+ textAlign: "left"
3568
+ },
3569
+ children: "Downstream"
3570
+ })
3571
+ ]
3572
+ }),
3573
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Col), {
3574
+ style: {
3575
+ maxWidth: "5ch",
3576
+ textAlign: "left"
3577
+ },
3578
+ children: downstream
3579
+ })
3580
+ ]
3581
+ }),
3582
+ gene.gene_structure.transcripts.length > 1 && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Row), {
3583
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $gXNCa$reactbootstrap.Col), {
3584
+ children: [
3585
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("b", {
3586
+ children: /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("i", {
3587
+ children: "Highlight transcript"
3588
+ })
3589
+ }),
3590
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("br", {}),
3591
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.ButtonGroup), {
3592
+ children: gene.gene_structure.transcripts.sort((a, b)=>a.id.localeCompare(b.id)).map((tr, idx)=>{
3593
+ let v = tr.id === gene.gene_structure.canonical_transcript ? "primary" : "secondary";
3594
+ if (tr.id !== tid) v = `outline-${v}`;
3595
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.ToggleButton), {
3596
+ variant: v,
3597
+ id: `radio-${idx}`,
3598
+ type: "radio",
3599
+ name: tr.id,
3600
+ value: tr.id,
3601
+ checked: tr.id === tid,
3602
+ onChange: (e)=>setTid(e.currentTarget.value),
3603
+ children: tr.id
3604
+ }, idx);
3605
+ })
3606
+ })
3607
+ ]
3608
+ })
3609
+ })
3610
+ ]
3611
+ }),
3612
+ geneSeq && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)($527ebc19dc92444d$var$CodeBlock, {
3613
+ id: $527ebc19dc92444d$var$buildId(gene, geneSeq, +upstream, +downstream),
3614
+ seq: geneSeq.seq.substring(maxUp - +upstream, maxUp + gene.location.end - gene.location.start + 1 + +downstream),
3615
+ blocks: $527ebc19dc92444d$var$decorateDNA(geneSeq, gene, +upstream, +downstream, tid)
3616
+ })
3617
+ ]
3618
+ }),
3619
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Tab), {
3620
+ tabClassName: "cdna",
3621
+ eventKey: "cdna",
3622
+ title: "Transcript sequence"
3623
+ }),
3624
+ gene.biotype === "protein_coding" && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Tab), {
3625
+ tabClassName: "pep",
3626
+ eventKey: "pep",
3627
+ title: "Peptide sequence"
3628
+ })
3629
+ ]
3630
+ });
3631
+ };
3632
+ var $527ebc19dc92444d$export$2e2bcd8739ae039 = (0, $gXNCa$reduxbundlerreact.connect)("selectConfiguration", "selectGeneSequences", "doRequestGeneSequence", $527ebc19dc92444d$var$Detail);
3633
+
3634
+
3635
+
3636
+
3637
+
3186
3638
  let $6c5c4f90059875bf$var$external = /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("small", {
3187
3639
  title: "This link opens a page from an external site",
3188
3640
  children: [
@@ -3193,6 +3645,7 @@ let $6c5c4f90059875bf$var$external = /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.js
3193
3645
  ]
3194
3646
  });
3195
3647
  let $6c5c4f90059875bf$var$inventory = {
3648
+ sequences: (0, $527ebc19dc92444d$export$2e2bcd8739ae039),
3196
3649
  location: (0, $264d7db426cab787$export$2e2bcd8739ae039),
3197
3650
  expression: (0, $9e29a4f60318db7a$export$2e2bcd8739ae039),
3198
3651
  homology: (0, $64fad37f770d2bfe$export$2e2bcd8739ae039),
@@ -3315,6 +3768,12 @@ class $6c5c4f90059875bf$var$Gene extends (0, ($parcel$interopDefault($gXNCa$reac
3315
3768
  super(props);
3316
3769
  this.state = {
3317
3770
  details: [
3771
+ {
3772
+ id: "sequences",
3773
+ label: "Sequences",
3774
+ popup: "Gene/cDNA/protein fasta",
3775
+ available: true
3776
+ },
3318
3777
  {
3319
3778
  id: "location",
3320
3779
  label: "Location",
@@ -3356,7 +3815,7 @@ class $6c5c4f90059875bf$var$Gene extends (0, ($parcel$interopDefault($gXNCa$reac
3356
3815
  };
3357
3816
  let hasData = {};
3358
3817
  props.searchResult.capabilities.forEach((c)=>hasData[c] = true);
3359
- this.state.details.forEach((d)=>d.available = hasData.hasOwnProperty(d.id));
3818
+ this.state.details.forEach((d)=>d.available |= hasData.hasOwnProperty(d.id));
3360
3819
  }
3361
3820
  getDetailStatus(d) {
3362
3821
  if (this.state.expandedDetail === d.id) return "expanded";