diff --git a/package-lock.json b/package-lock.json
index 92b8bf7..c0f76d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@protobuf-ts/runtime": "^2.9.3",
"@reactgular/chunks": "^1.0.1",
"@types/luxon": "^3.4.2",
+ "igv": "^2.15.11",
"luxon": "^3.4.4",
"title-case": "^4.3.1",
"vega": "^5.27.0",
@@ -11620,6 +11621,11 @@
"node": ">= 4"
}
},
+ "node_modules/igv": {
+ "version": "2.15.11",
+ "resolved": "https://registry.npmjs.org/igv/-/igv-2.15.11.tgz",
+ "integrity": "sha512-oJs6z4ogv1GefIWaMdG5s4jFRuFQ/PjUgrGBMn12SbeeIC/VgHkHr56K5yIaC8ZSyameq/7IFDQaXu0qIu6cpA=="
+ },
"node_modules/immutable": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
diff --git a/package.json b/package.json
index 727c519..7c977a1 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"@protobuf-ts/runtime": "^2.9.3",
"@reactgular/chunks": "^1.0.1",
"@types/luxon": "^3.4.2",
+ "igv": "^2.15.11",
"luxon": "^3.4.4",
"title-case": "^4.3.1",
"vega": "^5.27.0",
diff --git a/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts b/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts
new file mode 100644
index 0000000..7eddae8
--- /dev/null
+++ b/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts
@@ -0,0 +1,42 @@
+import { describe, expect, it } from 'vitest'
+
+import { setupMountedComponents } from '../../lib/testUtils'
+import GenomeBrowserCard from './GenomeBrowserCard.vue'
+
+describe.concurrent('GenomeBrowserCard.vue', async () => {
+ it('renders the GenomeBrowserCard with the hg19 genome', async () => {
+ // arrange:
+ const { wrapper } = await setupMountedComponents(
+ { component: GenomeBrowserCard },
+ {
+ props: {
+ genomeRelease: 'grch37',
+ locus: 'chr17:41246243-41246243'
+ }
+ }
+ )
+
+ // act: nothing, only test rendering
+
+ // assert:
+ expect(wrapper.exists()).toBe(true)
+ })
+
+ it('renders the GenomeBrowserCard with the hg38 genome', async () => {
+ // arrange:
+ const { wrapper } = await setupMountedComponents(
+ { component: GenomeBrowserCard },
+ {
+ props: {
+ genomeRelease: 'grch38',
+ locus: 'chr17:41246243-41246243'
+ }
+ }
+ )
+
+ // act: nothing, only test rendering
+
+ // assert:
+ expect(wrapper.exists()).toBe(true)
+ })
+})
diff --git a/src/components/GenomeBrowserCard/GenomeBrowserCard.vue b/src/components/GenomeBrowserCard/GenomeBrowserCard.vue
new file mode 100644
index 0000000..3da101d
--- /dev/null
+++ b/src/components/GenomeBrowserCard/GenomeBrowserCard.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+ Genome Browser
+
+
+
+
+
+
+
+@/lib/GenomeBrowser.c
diff --git a/src/components/GenomeBrowserCard/constants.spec.ts b/src/components/GenomeBrowserCard/constants.spec.ts
new file mode 100644
index 0000000..385133b
--- /dev/null
+++ b/src/components/GenomeBrowserCard/constants.spec.ts
@@ -0,0 +1,73 @@
+import { describe, expect, it } from 'vitest'
+
+import { publicTracks } from './constants'
+
+describe('publicTracks', () => {
+ it('should have at least one track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ expect(publicTracks.length).toBeGreaterThan(0)
+ })
+
+ it('should have a name for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.name).toBeDefined()
+ })
+ })
+
+ it('should have a sourceType for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.sourceType).toBeDefined()
+ })
+ })
+
+ it('should have a format for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.format).toBeDefined()
+ })
+ })
+
+ it('should have a visibilityWindow for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.visibilityWindow).toBeDefined()
+ })
+ })
+
+ it('should have a url for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.url).toBeDefined()
+ })
+ })
+
+ it('should have a color for each track', () => {
+ // arrange: nothing to do
+ // act: nothing to do
+
+ // assert:
+ publicTracks.forEach((track) => {
+ expect(track.color).toBeDefined()
+ })
+ })
+})
diff --git a/src/components/GenomeBrowserCard/constants.ts b/src/components/GenomeBrowserCard/constants.ts
new file mode 100644
index 0000000..511524b
--- /dev/null
+++ b/src/components/GenomeBrowserCard/constants.ts
@@ -0,0 +1,102 @@
+/** Default API base URL. */
+const API_BASE_URL = `/internal/proxy/nginx/`
+
+/** Visiblity window to use */
+const visibilityWindow = 10000000
+
+const hescTadTrack = {
+ name: 'hESC TADs',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/hesc.bed`,
+ color: 'gray'
+}
+
+const curatedMmsTrack = {
+ name: 'Curated MMS',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/patho-mms.bed`,
+ color: 'red'
+}
+
+const duplicationTrack = {
+ name: 'UCSC Segmental Duplications',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/genomicSuperDups.bed.gz`,
+ indexURL: `${API_BASE_URL}grch37/genomicSuperDups.bed.gz.tbi`,
+ color: 'black'
+}
+
+const repeatsTrack = {
+ name: 'UCSC Repeat Masker',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/rmsk.bed.gz`,
+ indexURL: `${API_BASE_URL}grch37/rmsk.bed.gz.tbi`,
+ color: 'black'
+}
+
+const altTrack = {
+ name: 'UCSC Alt Loci Track',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/altSeqLiftOverPsl.bed.gz`,
+ indexURL: `${API_BASE_URL}grch37/altSeqLiftOverPsl.bed.gz.tbi`,
+ color: 'black'
+}
+
+const fixTrack = {
+ name: 'UCSC Fix Track',
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ url: `${API_BASE_URL}grch37/fixSeqLiftOverPsl.bed.gz`,
+ indexURL: `${API_BASE_URL}grch37/fixSeqLiftOverPsl.bed.gz.tbi`,
+ color: 'black'
+}
+
+const bgDbTracks = [
+ {
+ title: 'gnomad-SV',
+ token: 'gnomad'
+ },
+ {
+ title: 'DGV SVs',
+ token: 'dgv'
+ },
+ {
+ title: 'DGV GS SVs',
+ token: 'dgv-gs'
+ },
+ {
+ title: 'ExAC CNVs',
+ token: 'exac'
+ }
+].map(({ title, token }) => {
+ return {
+ name: title,
+ sourceType: 'annotation',
+ format: 'bed',
+ visibilityWindow,
+ displayMode: 'SQUISHED',
+ url: `${API_BASE_URL}grch37/${token}.bed.gz`,
+ indexURL: `${API_BASE_URL}grch37/${token}.bed.gz.tbi`,
+ color: 'black'
+ }
+})
+
+export const publicTracks = [
+ duplicationTrack,
+ repeatsTrack,
+ altTrack,
+ fixTrack,
+ hescTadTrack,
+ curatedMmsTrack
+].concat(bgDbTracks)
diff --git a/src/components/GenomeBrowserCard/types.ts b/src/components/GenomeBrowserCard/types.ts
new file mode 100644
index 0000000..29c20b9
--- /dev/null
+++ b/src/components/GenomeBrowserCard/types.ts
@@ -0,0 +1,2 @@
+/** Alias for Genome Browser type. */
+export type GenomeBrowser = any