├── .browserslistrc ├── .cloudsql_env ├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .gcloudignore ├── .gitattributes ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .npmrc ├── .watchmanconfig ├── API.md ├── LICENSE ├── README.md ├── babel.config.js ├── build ├── build.sh ├── cloudbuild.yaml ├── deploy.sh └── gcs-cors-config.json ├── config ├── config_flu_genbank.yaml ├── config_flu_genbank_dev.yaml ├── config_flu_gisaid.yaml ├── config_flu_gisaid_dev.yaml ├── config_rsv_custom.yaml ├── config_rsv_genbank.yaml ├── config_sars2_alpha.yaml ├── config_sars2_custom.yaml ├── config_sars2_genbank.yaml ├── config_sars2_genbank_dev.yaml ├── config_sars2_gisaid.yaml ├── config_sars2_gisaid_6month.yaml └── config_sars2_gisaid_private.yaml ├── docker-compose.cloudsql.prod.yml ├── docker-compose.cloudsql.yml ├── docker-compose.flu.genbank.yml ├── docker-compose.flu.gisaid.yml ├── docker-compose.rsv.yml ├── docker-compose.sars2.yml ├── docker-compose.yml ├── environment.yml ├── environment_osx-arm64.yml ├── example_data_genbank ├── flu.tar.gz ├── rsv.tar.gz └── sars2.tar.gz ├── jsconfig.json ├── package-lock.json ├── package.json ├── package_example_data.sh ├── pymol ├── map_spike_snps.py ├── merge_pymol_interactions.py ├── pymol_color_spike_no_load.py ├── pymol_color_spike_snps.py ├── pymol_interacting_nab.py └── pymol_select_regions.py ├── services ├── frontend │ └── Dockerfile ├── postgres │ ├── Dockerfile │ ├── create_dbs.sh │ ├── postgres.conf │ └── test_queries │ │ └── coverage_tests.sql └── server │ ├── cg_server │ ├── __init__.py │ ├── app.py │ ├── auth.py │ ├── color.py │ ├── config.py │ ├── constants.py │ ├── db.py │ ├── db_seed │ │ ├── __init__.py │ │ ├── insert_sequences.py │ │ ├── load_mutations.py │ │ └── seed.py │ ├── dev_only.py │ ├── download │ │ ├── __init__.py │ │ ├── genomes.py │ │ └── metadata.py │ ├── gunicorn.conf.py │ ├── main.py │ ├── query │ │ ├── __init__.py │ │ ├── country_score.py │ │ ├── group_mutation_frequencies.py │ │ ├── initial.py │ │ ├── metadata.py │ │ ├── report.py │ │ ├── selection.py │ │ └── variant_table.py │ ├── routes │ │ ├── __init__.py │ │ ├── download.py │ │ ├── query.py │ │ ├── report.py │ │ ├── seed.py │ │ └── views.py │ └── test_connpool.py │ ├── cloudsql.Dockerfile │ ├── dev.Dockerfile │ ├── prod.Dockerfile │ ├── requirements.txt │ └── serve.sh ├── src ├── assets │ ├── analysis_screens │ │ ├── d614g_europe_na.png │ │ ├── d614g_us_states.png │ │ ├── d614g_west_coast.png │ │ ├── global_lineages.png │ │ ├── iceland.png │ │ ├── n_203_204_coocurrence.png │ │ ├── us_cdc_primer.png │ │ └── xinfadi.png │ ├── example_screens │ │ ├── example1_1.png │ │ ├── example1_2.png │ │ ├── example1_3.png │ │ ├── example1_4.png │ │ ├── example2_1.png │ │ ├── example2_2.png │ │ ├── example2_3.png │ │ ├── example2_4.png │ │ ├── example3_1.png │ │ ├── example3_2.png │ │ └── example3_3.png │ └── images │ │ ├── BroadLogo_RGB_forDigital.png │ │ ├── CVRBioInfo_logo.png │ │ ├── Fig2_workflow_V4.svg │ │ ├── Fig2_workflow_V5.svg │ │ ├── HKUST-original_0.svg │ │ ├── React-icon.svg │ │ ├── VE_logo_new.png │ │ ├── cg_logo_v13.pdf │ │ ├── cg_logo_v13.png │ │ ├── cg_logo_v13.svg │ │ ├── cg_logo_v13@2x.png │ │ ├── cg_logo_v13@4x.png │ │ ├── cg_short_v13.pdf │ │ ├── cg_short_v13.png │ │ ├── cg_short_v13.svg │ │ ├── cg_short_v13@2x.png │ │ ├── cg_short_v13@4x.png │ │ ├── cg_short_v13@4x_square.png │ │ ├── csiro_logo.png │ │ ├── favicon │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ └── site.webmanifest │ │ ├── flu_pathmut_logo_v1.pdf │ │ ├── flu_pathmut_logo_v1.png │ │ ├── flu_pathmut_logo_v1.svg │ │ ├── flu_pathmut_logo_v1@2x.png │ │ ├── flu_pathmut_logo_v1@4x.png │ │ ├── gisaid_logo.png │ │ ├── idl-logo.png │ │ ├── jhu_logo.jpg │ │ ├── kaust_logo.png │ │ ├── lanl_logo.svg │ │ ├── logo-cog-uk.png │ │ ├── mobx.png │ │ ├── mrc_logo.png │ │ ├── ncbi_logo.svg │ │ ├── nextstrain_logo.png │ │ ├── niaid_logo.png │ │ ├── pangolin_logo.png │ │ ├── polimi_logo.png │ │ ├── rdg-logo.png │ │ ├── react_slingshot.png │ │ ├── rsv_pathmut_logo_v1.pdf │ │ ├── rsv_pathmut_logo_v1.png │ │ ├── rsv_pathmut_logo_v1.svg │ │ ├── rsv_pathmut_logo_v1@2x.png │ │ ├── rsv_pathmut_logo_v1@4x.png │ │ ├── rsvg_logo_temp.pdf │ │ ├── rsvg_logo_temp.png │ │ ├── ubc_logo.png │ │ ├── ucscHelixLogo.png │ │ ├── uglasgow_logo.png │ │ ├── university-college-london-ucl-vector-logo.svg │ │ ├── ve_logo.png │ │ ├── vipr_logo.png │ │ ├── vipr_logo@4x.png │ │ ├── virusurf_logo.png │ │ └── wustl_virusgateway.svg ├── components │ ├── App.js │ ├── Buttons │ │ ├── Button.js │ │ ├── Button.styles.js │ │ ├── DeselectButton.js │ │ ├── DropdownButton.js │ │ ├── DropdownButton.styles.js │ │ ├── GenotypeToggleButton.js │ │ └── QuestionButton.js │ ├── Cells │ │ ├── AckAuthorCell.js │ │ ├── AckCell.js │ │ ├── GroupCell.js │ │ ├── HeatmapCell.js │ │ ├── LetterCell.js │ │ └── PosHeaderCell.js │ ├── Common │ │ ├── Accordion.styles.js │ │ ├── AccordionWrapper.js │ │ ├── AcknowledgementFooter.js │ │ ├── AcknowledgementFooter.styles.js │ │ ├── EmptyPlot.js │ │ ├── ExternalLink.js │ │ ├── KBD.js │ │ ├── LineageName.js │ │ ├── LineageName.styles.js │ │ ├── LoadingSpinner.js │ │ ├── LoadingSpinner.styles.js │ │ ├── NothingSelected.js │ │ ├── NothingSelected.styles.js │ │ ├── SelectBoxText.js │ │ ├── SkeletonElement.js │ │ ├── SkeletonElement.styles.js │ │ ├── StyledDropdownTreeSelect.js │ │ ├── TabIndicator.js │ │ ├── TabIndicator.styles.js │ │ ├── WarningBox.js │ │ └── WarningBox.styles.js │ ├── Example │ │ ├── ExampleList.js │ │ ├── ExampleList.styles.js │ │ ├── WalkthroughList.js │ │ └── WalkthroughList.styles.js │ ├── GroupReport │ │ ├── GroupReportHeader.js │ │ ├── GroupReportHeader.styles.js │ │ ├── GroupSearch.js │ │ ├── GroupSearch.styles.js │ │ ├── GroupStructuralViewer.js │ │ ├── GroupStructuralViewer.styles.js │ │ ├── MutationList.js │ │ ├── MutationList.styles.js │ │ ├── MutationList.utils.js │ │ ├── OrgLegend.js │ │ ├── OrgLegend.styles.js │ │ ├── SelectedReportGroups.js │ │ ├── SelectedReportGroups.styles.js │ │ ├── VOCList.js │ │ └── VOCList.styles.js │ ├── KeyListener.js │ ├── Legend │ │ ├── Legend.styles.js │ │ ├── LegendContainer.js │ │ ├── TableLegend.js │ │ ├── TableLegend.styles.js │ │ ├── TableLegendItem.js │ │ ├── TableLegendItem.styles.js │ │ └── legendUtils.js │ ├── LiteMol │ │ ├── LiteMolPlugin.js │ │ ├── StructureEntities.js │ │ ├── StructureEntities.styles.js │ │ └── litemolutils.js │ ├── LoadingScreen.js │ ├── LoadingScreen.styles.js │ ├── Modals │ │ ├── AsyncErrorModal.js │ │ ├── DownloadConsensusMutationsModal.js │ │ ├── DownloadGenomesModal.js │ │ ├── DownloadMetadataModal.js │ │ ├── DownloadPymolScriptModal.js │ │ ├── DownloadVariantTableModal.js │ │ ├── Modal.styles.js │ │ ├── SelectSequencesModal.js │ │ ├── SelectSequencesModal.styles.js │ │ └── SplashScreenModal.js │ ├── Pages │ │ ├── AboutTabFlu.js │ │ ├── AboutTabRSV.js │ │ ├── AboutTabSARS.js │ │ ├── CompareGroupsTab.js │ │ ├── CompareLocationsTab.js │ │ ├── GroupReportTab.js │ │ ├── GroupReportTab.styles.js │ │ ├── HomeTab.js │ │ ├── HomeTab.styles.js │ │ ├── MainPage.js │ │ ├── MainPage.styles.js │ │ ├── MethodologyTab.js │ │ ├── NotFoundPage.js │ │ ├── RelatedProjectsTab.js │ │ ├── SequencingEffortsTab.js │ │ ├── SequencingEffortsTab.styles.js │ │ └── TextTab.styles.js │ ├── Selection │ │ ├── CoordinateSelect.js │ │ ├── CoordinateSelect.styles.js │ │ ├── DateSelect.js │ │ ├── DateSelect.styles.js │ │ ├── GroupBySelect.js │ │ ├── GroupBySelect.styles.js │ │ ├── GroupSelect.js │ │ ├── GroupSelect.styles.js │ │ ├── LocationSelect.js │ │ ├── LocationSelect.styles.js │ │ ├── MetaFieldSelect.js │ │ ├── MetaFieldSelect.styles.js │ │ ├── QualitySelect.js │ │ ├── QualitySelect.styles.js │ │ ├── SelectionTopBar.js │ │ └── SelectionTopBar.styles.js │ ├── Sidebar │ │ ├── DefaultSidebar.js │ │ ├── DefaultSidebar.styles.js │ │ ├── DownloadDataButton.js │ │ ├── DownloadDataButton.styles.js │ │ ├── FilterSidebar.js │ │ ├── FilterSidebar.styles.js │ │ ├── Footer.js │ │ ├── Footer.styles.js │ │ ├── Header.js │ │ ├── Header.styles.js │ │ ├── StatusBox.js │ │ ├── StatusBox.styles.js │ │ ├── TabBar.js │ │ └── TabBar.styles.js │ ├── Viz │ │ ├── CooccurrencePlot.js │ │ ├── EntropyPlot.js │ │ ├── GlobalSeqPlot.js │ │ ├── GradientLegend.js │ │ ├── GradientLegend.styles.js │ │ ├── GroupStackPlot.js │ │ ├── GroupStackPlot.styles.js │ │ ├── GroupTreePlot.js │ │ ├── GroupTreePlot.styles.js │ │ ├── LocationDatePlot.js │ │ ├── LocationGroupPlot.js │ │ ├── LowFreqFilter.js │ │ ├── LowFreqFilter.styles.js │ │ ├── MarkLegend.js │ │ ├── MarkLegend.styles.js │ │ ├── MutationStructureViewer.js │ │ ├── MutationStructureViewer.styles.js │ │ ├── NumSeqPerLocationBar.js │ │ ├── NumSeqPerLocationLine.js │ │ ├── Plot.styles.js │ │ ├── SequencingMapPlot.js │ │ ├── SurveillancePlot.js │ │ └── SurveillancePlot.styles.js │ └── WaitForAsyncWrapper.js ├── config │ └── index.js ├── constants │ ├── colors.js │ ├── defs.json │ ├── functions.js │ ├── initialValues.js │ └── metadata.js ├── examples │ ├── examples.flu.js │ ├── examples.rsv.js │ ├── examples.sars2.js │ └── index.js ├── favicon.ico ├── fonts │ ├── fontello.eot │ ├── fontello.svg │ ├── fontello.ttf │ ├── fontello.woff │ └── fontello.woff2 ├── index.ejs ├── index.js ├── react_vega │ ├── LICENSE │ ├── VegaEmbed.js │ └── utils │ │ ├── computeSpecChanges.js │ │ ├── getDatasetNamesFromSpec.js │ │ ├── getUniqueFieldNames.js │ │ ├── isFunction.js │ │ └── shallowEqual.js ├── routes.js ├── stores │ ├── UIStore.js │ ├── asyncDataStore.js │ ├── configStore.js │ ├── connect.js │ ├── dataStore.js │ ├── globalSequencingData.js │ ├── groupDataStore.js │ ├── locationDataStore.js │ ├── metadataStore.js │ ├── mutationData.js │ ├── plotSettingsStore.js │ ├── rootStore.js │ ├── surveillanceDataStore.js │ └── urlMonitor.js ├── styles │ └── litemol.min.css ├── utils │ ├── color.js │ ├── coordinates.js │ ├── data.js │ ├── date.js │ ├── device.js │ ├── download.js │ ├── example.worker.js │ ├── exampleWorkerWrapper.js │ ├── func.js │ ├── gene_protein.js │ ├── location.js │ ├── math.js │ ├── mutationData.worker.js │ ├── mutationDataWorkerWrapper.js │ ├── mutationUtils.js │ ├── primer.js │ ├── pymol.js │ ├── reference.js │ ├── string.js │ ├── transform.js │ ├── updateQueryParam.js │ └── version.js ├── vega_specs │ ├── area_stack.vl.json │ ├── area_stack_simulated_standalone.json │ ├── area_stack_standalone.vl.json │ ├── barplot_v2.vl.json │ ├── barplot_v3.vl.json │ ├── cooccurrence_plot.vg.json │ ├── cooccurrence_plot_standalone.vg.json │ ├── entropy.vg.json │ ├── entropy_standalone.vg.json │ ├── global_seq_v2.vg.json │ ├── group_stack.vg.json │ ├── group_stack_standalone.vg.json │ ├── group_tree_legend_v2.vg.json │ ├── group_tree_v1.vg.json │ ├── group_tree_v2.vg.json │ ├── location_date.vg.json │ ├── location_date_standalone.vg.json │ ├── location_group.vg.json │ ├── location_group_standalone.vg.json │ ├── map_combined.vg.json │ ├── map_combined_standalone.vg.json │ ├── map_sequences_per_case_standalone.vg.json │ ├── map_turnaround_time_standalone.vg.json │ ├── num_seq_per_location_bar.standalone.vg.json │ ├── num_seq_per_location_bar.vg.json │ ├── num_seq_per_location_line.standalone.vg.json │ ├── num_seq_per_location_line.vg.json │ ├── surveillance.vg.json │ └── surveillance_standalone_rsv.vg.json └── webpack-public-path.js ├── static_data ├── flu │ ├── alignments │ │ ├── .sglock │ │ │ ├── H3N2_4_NC_007366.dna=hotdog.local=77771 │ │ │ ├── H3N2_6_NC_007368.dna=hotdog.local=77771 │ │ │ └── H3N2_7_NC_007367.dna=hotdog.local=77771 │ │ ├── B-vic_1_JN600474.dna │ │ ├── B-vic_2_JN600475.dna │ │ ├── B-vic_3_JN600476.dna │ │ ├── B-vic_4_FLBHAAA.dna │ │ ├── B-vic_5_JN600477.dna │ │ ├── B-vic_6_AB036870.dna │ │ ├── B-vic_7_JN600478.dna │ │ ├── B-vic_8_JN600479.dna │ │ ├── B-yam_1_AF101989.dna │ │ ├── B-yam_2_AF102006.dna │ │ ├── B-yam_3_AF102023.dna │ │ ├── B-yam_4_MK715607.dna │ │ ├── B-yam_5_FLBIBNA.dna │ │ ├── B-yam_6_AY139081.dna │ │ ├── B-yam_7_AF100378.dna │ │ ├── B-yam_8_AF100396.dna │ │ ├── H10N8_1.dna │ │ ├── H10N8_2.dna │ │ ├── H10N8_3.dna │ │ ├── H10N8_4.dna │ │ ├── H10N8_5.dna │ │ ├── H10N8_6.dna │ │ ├── H10N8_7.dna │ │ ├── H10N8_8.dna │ │ ├── H1N1_1_MZ310486.dna │ │ ├── H1N1_2_MZ310487.dna │ │ ├── H1N1_3_MZ310488.dna │ │ ├── H1N1_4_MZ310489.dna │ │ ├── H1N1_5_MZ310490.dna │ │ ├── H1N1_6_MZ310491.dna │ │ ├── H1N1_7_NC_002016.dna │ │ ├── H1N1_8_MZ310493.dna │ │ ├── H3N2_1_NC_007373.1.dna │ │ ├── H3N2_2_NC_007372.1.dna │ │ ├── H3N2_3_NC_007371.1.dna │ │ ├── H3N2_4_NC_007366.1.dna │ │ ├── H3N2_5_NC_007369.1.dna │ │ ├── H3N2_6_NC_007368.1.dna │ │ ├── H3N2_7_NC_007367.1.dna │ │ ├── H3N2_8_NC_007370.1.dna │ │ ├── H5N1_1_NC_007357.dna │ │ ├── H5N1_2_NC_007358.dna │ │ ├── H5N1_3_NC_007359.dna │ │ ├── H5N1_4_NC_007362.dna │ │ ├── H5N1_5_NC_007360.dna │ │ ├── H5N1_6_NC_007361.dna │ │ ├── H5N1_7_NC_007363.dna │ │ ├── H5N1_8_NC_007364.dna │ │ ├── H7N2_1_NC_026422.dna │ │ ├── H7N2_2_NC_026423.dna │ │ ├── H7N2_3_NC_026424.dna │ │ ├── H7N2_4_NC_026425.dna │ │ ├── H7N2_5_NC_026426.dna │ │ ├── H7N2_6_NC_026429.dna │ │ ├── H7N2_7_NC_026427.dna │ │ ├── H7N2_8_NC_026428.dna │ │ ├── H9N2_1_NC_004910.dna │ │ ├── H9N2_2_NC_004911.dna │ │ ├── H9N2_3_NC_004912.dna │ │ ├── H9N2_4_NC_004908.dna │ │ ├── H9N2_5_NC_004905.dna │ │ ├── H9N2_6_NC_004909.dna │ │ ├── H9N2_7_NC_004907.dna │ │ ├── H9N2_8_NC_004906.dna │ │ └── HA_all.praln │ ├── country_to_emoji.xls │ ├── default_structures.json │ ├── genes.csv │ ├── genes_processed.json │ ├── mut_references │ │ ├── B-vic │ │ │ ├── B-Austria-1359417-2021 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── B-Brisbane-60-2008 │ │ │ │ ├── 4.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── B-Colorado-06-2017 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ └── DESCRIPTION │ │ │ └── B-Washington-02-2019 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ ├── B-yam │ │ │ ├── B-Massachusetts-02-2012 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── B-Phuket-3073-2013 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ └── B-Wisconsin-01-2010 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ ├── H10NX │ │ │ ├── A-Jiangsu-428-2021 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ │ └── A-Jiangxi-Donghu-346-2013 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ ├── H1N1 │ │ │ ├── A-Brisbane-02-2018 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-California-07-2009 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Guangdong-Maonan-SWL1536-2019 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Michigan-45-2015 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Victoria-2570-2019 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ └── A-Wisconsin-67-2022 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ ├── H3N2 │ │ │ ├── A-Cambodia-e0826360-2020 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Darwin-6-2021 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ │ ├── A-Darwin-9-2021 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Hong-Kong-4801-2014 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Kansas-14-2017 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Perth-16-2009 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Singapore-INFIMH-16-0019-2016 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Switzerland-9715293-2013 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ ├── A-Texas-50-2012 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ └── DESCRIPTION │ │ │ └── A-Victoria-361-2011 │ │ │ │ ├── 4.fa │ │ │ │ ├── 6.fa │ │ │ │ └── DESCRIPTION │ │ ├── H5NX │ │ │ ├── A-Goose-Guangdong-1-96 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ │ └── A-Viet-Nam-1203-2004 │ │ │ │ ├── 4.fa │ │ │ │ └── DESCRIPTION │ │ ├── H7NX │ │ │ ├── A-Anhui-1-2013 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ │ └── A-Shanghai-02-2013 │ │ │ │ ├── 1.fa │ │ │ │ ├── 2.fa │ │ │ │ ├── 3.fa │ │ │ │ ├── 4.fa │ │ │ │ ├── 5.fa │ │ │ │ ├── 6.fa │ │ │ │ ├── 7.fa │ │ │ │ ├── 8.fa │ │ │ │ ├── DESCRIPTION │ │ │ │ └── NOTES │ │ └── H9NX │ │ │ └── A-Hong-Kong-1073-99 │ │ │ ├── 1.fa │ │ │ ├── 2.fa │ │ │ ├── 3.fa │ │ │ ├── 4.fa │ │ │ ├── 5.fa │ │ │ ├── 6.fa │ │ │ ├── 7.fa │ │ │ ├── 8.fa │ │ │ ├── DESCRIPTION │ │ │ └── NOTES │ ├── primers.csv │ ├── primers.json │ ├── proteins.csv │ ├── proteins_processed.json │ ├── reference.json │ ├── serotype_references │ │ ├── 1.fa │ │ ├── 2.fa │ │ ├── 3.fa │ │ ├── 4.fa │ │ ├── 5.fa │ │ ├── 6.fa │ │ ├── 7.fa │ │ └── 8.fa │ └── world-110m-mod.json ├── rsv │ ├── country_to_emoji.xls │ ├── default_structures.json │ ├── genes.csv │ ├── genes_processed.json │ ├── genotype_references.fasta │ ├── genotype_references.json │ ├── genotypesBySubtype.json │ ├── mut_references │ │ ├── A │ │ │ ├── KX858757.1 │ │ │ │ ├── 1.fa │ │ │ │ └── DESCRIPTION │ │ │ └── NC_038235.1 │ │ │ │ ├── 1.fa │ │ │ │ └── DESCRIPTION │ │ └── B │ │ │ ├── KX858756.1 │ │ │ ├── 1.fa │ │ │ └── DESCRIPTION │ │ │ └── NC_001781.1 │ │ │ ├── 1.fa │ │ │ └── DESCRIPTION │ ├── old │ │ ├── A.fa │ │ ├── A │ │ │ ├── KX858757.1.fa │ │ │ └── NC_038235.1.fa │ │ ├── B.fa │ │ └── B │ │ │ ├── KX858756.1.fa │ │ │ └── NC_001781.1.fa │ ├── primers.csv │ ├── primers.json │ ├── proteins.csv │ ├── proteins_processed.json │ ├── reference.fa │ ├── reference.json │ ├── vocs.json │ └── world-110m-mod.json └── sars2 │ ├── CDC.json │ ├── ECDC.json │ ├── PHE.json │ ├── WHO.json │ ├── artic_primers.csv │ ├── country_to_emoji.xls │ ├── default_structures.json │ ├── genbank_field.txt │ ├── genes.csv │ ├── genes_processed.json │ ├── location_corrections.csv │ ├── mut_references │ └── SARS-CoV-2 │ │ └── WIV04 │ │ ├── 1.fa │ │ └── DESCRIPTION │ ├── nextstrain_exclude_20200520.txt │ ├── primers.csv │ ├── primers.json │ ├── proteins.csv │ ├── proteins_processed.json │ ├── reference.json │ ├── vocs.json │ └── world-110m-mod.json ├── tools ├── .yarnclean ├── analyzeBundle.js ├── build.js ├── chalkConfig.js ├── distServer.js ├── fileMock.js ├── loadConfigFile.js ├── nodeVersionCheck.js ├── srcServer.js └── startMessage.js ├── tsconfig.json ├── webpack.config.dev.js ├── webpack.config.prod.js ├── workflow_flu_genbank_ingest ├── README.md ├── Snakefile └── scripts │ ├── LICENSE_NEXTSTRAIN │ ├── chunk_sequences.py │ ├── clean_metadata.py │ ├── copy_changed_files.py │ ├── download_metadata.py │ ├── download_sequences.py │ ├── join_serotype_assignments.py │ ├── make_ref_json.py │ ├── make_references.py │ ├── sequence_quality.py │ └── write_ha_fasta.py ├── workflow_flu_gisaid_ingest ├── README.md ├── Snakefile └── scripts │ ├── chunk_sequences.py │ ├── clean_metadata.py │ └── copy_changed_files.py ├── workflow_main ├── Snakefile ├── analyses │ ├── Snakefile │ └── scripts │ │ ├── __init__.py │ │ ├── az_report.py │ │ ├── consensus_mutations.py │ │ ├── global_seq_data.py │ │ ├── global_sequencing_efforts.py │ │ ├── mutation_frequency_report.py │ │ ├── standalone_map_spec.py │ │ └── surveillance.py ├── phylotree │ ├── LICENSE_COVIZU │ ├── Snakefile │ └── scripts │ │ ├── __init__.py │ │ ├── build_graph_table.py │ │ └── representative_seqs.py └── scripts │ ├── __init__.py │ ├── abbreviate_authors.py │ ├── artic_primers.py │ ├── assemble_data_package.py │ ├── bam_subseq.py │ ├── build_full_dataframe.py │ ├── build_location_tree.py │ ├── collapse_to_isolate.py │ ├── combine_all_data.py │ ├── combine_coverage.py │ ├── combine_coverage_pivot.py │ ├── coverage_aa.py │ ├── coverage_dna.py │ ├── extract_aa_mutations.py │ ├── extract_dna_mutations.py │ ├── fasta.py │ ├── gene_protein_defs.py │ ├── get_cdc_vocs.py │ ├── get_ecdc_vocs.py │ ├── get_phe_vocs.py │ ├── get_who_vocs.py │ ├── global_group_counts.py │ ├── preprocess_rsv_sequences.py │ ├── preprocess_sars2_sequences.py │ ├── process_mutations.py │ ├── push_to_database.py │ ├── read_extractor_lite.py │ ├── send_email.py │ ├── sequence_manifest.py │ ├── touch_bam.py │ ├── update_vocs.py │ ├── util.py │ └── write_reference_files.py ├── workflow_rsv_custom_ingest ├── README.md ├── Snakefile ├── scripts │ └── clean_metadata.py └── test_data │ └── data_custom │ ├── fasta_raw │ └── 1985-02-20.fa.gz │ └── metadata_raw.csv ├── workflow_rsv_genbank_ingest ├── README.md ├── Snakefile └── scripts │ ├── LICENSE_NEXTSTRAIN │ ├── chunk_sequences.py │ ├── clean_metadata.py │ ├── copy_changed_files.py │ ├── download_metadata.py │ ├── download_sequences.py │ ├── join_subtype_assignments.py │ ├── sequence_quality.py │ ├── split_sequences_by_subtype.py │ └── write_all_fasta.py ├── workflow_sars2_custom_ingest ├── README.md ├── Snakefile ├── envs │ └── pangolin.yaml ├── scripts │ ├── clean_metadata.py │ └── combine_lineages.py └── test-data │ └── data_custom │ ├── fasta_raw │ └── test-sequences.fa.gz │ └── metadata_raw.csv ├── workflow_sars2_genbank_ingest ├── README.md ├── Snakefile ├── envs │ └── pangolin.yaml └── scripts │ ├── LICENSE_NEXTSTRAIN │ ├── chunk_data.py │ ├── clean_metadata.py │ ├── copy_changed_files.py │ ├── download_metadata.py │ ├── download_sequences.py │ └── sequence_quality.py └── workflow_sars2_gisaid_ingest ├── README.md ├── Snakefile ├── envs └── pangolin.yaml └── scripts ├── clean_metadata.py ├── download.sh ├── process_feed.py ├── process_location_metadata.py └── sequence_quality.py /.browserslistrc: -------------------------------------------------------------------------------- 1 | # For use by Babel. 2 | # Run "npx browserslist" to see the list of browsers returned 3 | last 2 versions 4 | > 1% 5 | not dead 6 | maintained node versions 7 | -------------------------------------------------------------------------------- /.cloudsql_env: -------------------------------------------------------------------------------- 1 | POSTGRES_USER=... 2 | POSTGRES_PASSWORD=... 3 | POSTGRES_HOST=/cloudsql/[PROJECT ID]:us-central1:[SQL INSTANCE ID] 4 | POSTGRES_DB=[DB_NAME] 5 | GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials 6 | CLOUDSQL_CONNECTION_NAME=[PROJECT ID]:us-central1:[SQL INSTANCE ID] 7 | CONFIGFILE=config/[CONFIGFILE.yml] -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | data 4 | data_genbank 5 | data_flu_gisaid_small 6 | data_flu_genbank_small 7 | data_gisaid_rsv 8 | data_genbank_rsv 9 | dist 10 | example_data_genbank 11 | figures 12 | notebooks 13 | pymol 14 | workflow_main 15 | workflow_custom_ingest 16 | workflow_gisaid_ingest 17 | workflow_genbank_ingest 18 | .ipynb_checkpoints 19 | .git 20 | .snakemake 21 | .vscode 22 | 23 | *.pyc 24 | *.pyo 25 | *.pyd 26 | __pycache__ 27 | .pytest_cache 28 | 29 | README.md 30 | LICENSE 31 | environment.yml 32 | .gitignore 33 | .gitattributes 34 | .gcloudignore 35 | .editorconfig -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.js] 16 | quote_type = single 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/litemol/* 2 | node_modules/* 3 | src/vega_specs/*standalone*.vg.json -------------------------------------------------------------------------------- /.gcloudignore: -------------------------------------------------------------------------------- 1 | .git 2 | *.pyc 3 | *.pyo 4 | *.pyd 5 | __pycache__ 6 | .pytest_cache 7 | 8 | .dockerignore 9 | .git 10 | .gitignore 11 | .gitattributes 12 | .gcloudignore 13 | .editorconfig 14 | .ipynb_checkpoints 15 | .snakemake 16 | .vscode 17 | 18 | build 19 | data 20 | data_genbank 21 | data_genbank_rsv 22 | data_az 23 | data_ma 24 | data_flu_gisaid_small 25 | data_flu_genbank_small 26 | data_gisaid_rsv 27 | dist 28 | example_data_genbank 29 | figures 30 | node_modules 31 | notebooks 32 | pymol 33 | workflow_main 34 | workflow_custom_ingest 35 | workflow_gisaid_ingest 36 | workflow_genbank_ingest 37 | 38 | README.md 39 | LICENSE 40 | environment.yml -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ipynb binary linguist-detectable=false 2 | # Don't track changes in the example data 3 | example_data_genbank/** -diff -merge -text 4 | example_data_genbank/rsv.tar.gz filter=lfs diff=lfs merge=lfs -text 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/.watchmanconfig -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Vector Engineering Group (Albert Chen, Alina Chan, Shing Hei Zhan, Ben Deverman), Broad Institute of MIT and Harvard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | [ 4 | '@babel/plugin-proposal-decorators', 5 | { 6 | legacy: true, 7 | }, 8 | ], 9 | ['babel-plugin-styled-components'], 10 | ], 11 | }; 12 | -------------------------------------------------------------------------------- /build/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | # Instructions: https://cloud.google.com/cloud-build/docs/building/build-containers#yaml 2 | steps: 3 | - name: "gcr.io/cloud-builders/docker" 4 | args: 5 | [ 6 | "build", 7 | "--build-arg", 8 | "CONFIGFILE=${_CONFIGFILE}", 9 | "-t", 10 | "gcr.io/$PROJECT_ID/${_TARGET}:${_TAG_NAME}", 11 | "-f", 12 | "services/server/prod.Dockerfile", 13 | ".", 14 | ] 15 | 16 | substitutions: 17 | _TARGET: cg 18 | _CONFIGFILE: config/config_gisaid.yaml 19 | _TAG_NAME: v2.0.0-dev4 20 | 21 | images: ["gcr.io/$PROJECT_ID/${_TARGET}:${_TAG_NAME}"] 22 | -------------------------------------------------------------------------------- /build/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "${CG_VERSION}" ]]; then 4 | echo "CG_VERSION undefined" 5 | exit 1 6 | else 7 | echo "Deploying version: ${CG_VERSION}" 8 | fi 9 | 10 | if [[ -z "${PROJECT_ID}" ]]; then 11 | echo "PROJECT_ID undefined" 12 | exit 1 13 | else 14 | echo "Project: ${PROJECT_ID}" 15 | fi 16 | 17 | gcloud run deploy cg --image "gcr.io/${PROJECT_ID}/cg:${CG_VERSION}" && \ 18 | gcloud run deploy cg-private --image "gcr.io/${PROJECT_ID}/cg-private:${CG_VERSION}" && \ 19 | gcloud run deploy cg-genbank --image "gcr.io/${PROJECT_ID}/cg-genbank:${CG_VERSION}" && \ 20 | gcloud run deploy cg-alpha --image "gcr.io/${PROJECT_ID}/cg-alpha:${CG_VERSION}" 21 | 22 | # RSV 23 | 24 | gcloud run deploy rsv-genbank --image "gcr.io/${PROJECT_ID}/rsv:${CG_VERSION}" 25 | 26 | # FLU 27 | 28 | gcloud run deploy flu-gisaid --image "gcr.io/${PROJECT_ID}/flu-gisaid:${CG_VERSION}" 29 | gcloud run deploy flu-genbank --image "gcr.io/${PROJECT_ID}/flu-genbank:${CG_VERSION}" 30 | -------------------------------------------------------------------------------- /build/gcs-cors-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "origin": [ 4 | "https://covidcg.org", 5 | "https://az.covidcg.org", 6 | "https://genbank.covidcg.org", 7 | "https://alpha.covidcg.org", 8 | "https://flu.pathmut.org", 9 | "https://flu.genbank.pathmut.org", 10 | "https://flu.gisaid.pathmut.org", 11 | "https://rsv.genbank.pathmut.org", 12 | "https://rsv.pathmut.org", 13 | "https://sars2.pathmut.org", 14 | "https://sars2.gisaid.pathmut.org", 15 | "https://sars2.genbank.pathmut.org", 16 | "http://localhost", 17 | "http://localhost:3000", 18 | "http://localhost:3001", 19 | "http://localhost:3002" 20 | ], 21 | "method": ["GET"], 22 | "responseHeader": ["Content-Type"], 23 | "maxAgeSeconds": 3600 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: covid-cg 2 | channels: 3 | - defaults 4 | - bioconda 5 | - conda-forge 6 | dependencies: 7 | - python=3.8.8 8 | - numpy=1.20.2 9 | - scipy=1.6.2 10 | - pandas=1.3.5 11 | - pip=20.1.1 12 | - snakemake-minimal=5.20.1 13 | #- samtools=1.10 14 | - bs4=4.9.3 15 | - biopython=1.78 16 | #- fasttree=2.1.10 17 | - treetime=0.7.5 18 | - networkx=2.5.1 19 | - xlrd=2.0.1 20 | #- minimap2=2.21 21 | - scikit-learn=1.0 22 | - pip: 23 | - pysam==0.15.4 24 | # Email updates 25 | - sendgrid==6.0.5 26 | # For pushing to database 27 | - psycopg2==2.9.3 28 | -------------------------------------------------------------------------------- /environment_osx-arm64.yml: -------------------------------------------------------------------------------- 1 | # samtools, FastTree, and minimap2 not yet available on conda repositories as native arm64 binaries, 2 | # so these need to be installed from source 3 | # 4 | # Additionally, install htslib from source, then run: 5 | # export HTSLIB_LIBRARY_DIR=/path/to/htslib/lib 6 | # export HTSLIB_INCLUDE_DIR=/path/to/htslib/include 7 | # prior to running: conda env create -f environment_osx-arm64.yaml 8 | 9 | name: covid-cg 10 | channels: 11 | - defaults 12 | - bioconda 13 | - conda-forge 14 | dependencies: 15 | - python=3.8.8 16 | - numpy=1.20.2 17 | - scipy=1.6.2 18 | - pandas=1.2.5 19 | - pip=20.1.1 20 | - snakemake-minimal=5.20.1 21 | #- samtools=1.10 22 | - bs4=4.9.3 23 | - biopython=1.78 24 | #- fasttree=2.1.10 25 | - treetime=0.7.5 26 | - networkx=2.5.1 27 | - xlrd=2.0.1 28 | #- minimap2=2.21 29 | - scikit-learn=1.0 30 | - openblas=0.3.18 31 | - pip: 32 | - pysam==0.18.0 33 | # Email updates 34 | - sendgrid==6.0.5 35 | # For pushing to database 36 | - psycopg2==2.9.3 37 | -------------------------------------------------------------------------------- /example_data_genbank/flu.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/example_data_genbank/flu.tar.gz -------------------------------------------------------------------------------- /example_data_genbank/rsv.tar.gz: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:07caaea8e02e77e2f57dbbd8e8a0c788b09c501ec8d9be2b434b06fd824960f3 3 | size 2494933 4 | -------------------------------------------------------------------------------- /example_data_genbank/sars2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/example_data_genbank/sars2.tar.gz -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true 4 | }, 5 | "include": ["src/**/*"], 6 | "exclude": ["node_modules", "**/node_modules/*"] 7 | } 8 | -------------------------------------------------------------------------------- /package_example_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm -f example_data_genbank/sars2.tar.gz 6 | rm -f example_data_genbank/rsv.tar.gz 7 | rm -f example_data_genbank/flu.tar.gz 8 | 9 | cd example_data_genbank 10 | tar -czf sars2.tar.gz sars2/fasta_raw sars2/metadata.csv 11 | tar -czf rsv.tar.gz rsv/fasta_raw rsv/metadata.csv 12 | tar -czf flu.tar.gz flu/fasta_raw flu/metadata.csv -------------------------------------------------------------------------------- /pymol/merge_pymol_interactions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding: utf-8 3 | 4 | '''Merge interactions from pymol_interacting_nab.py into spike_structures.csv 5 | 6 | Author: Albert Chen (Deverman Lab - Broad Institute) 7 | ''' 8 | 9 | import pandas as pd 10 | 11 | from pathlib import Path 12 | 13 | project_root_path = Path(__file__).resolve().parent.parent 14 | data_dir = (project_root_path / 'data').resolve() # Resolve any symlinks --> absolute path 15 | 16 | df = pd.read_csv(data_dir / 'spike_structures.csv') 17 | interact_df = pd.read_csv(data_dir / 'spike_interactions.csv') 18 | 19 | df['interacting_residues'] = df['PDB ID'].map( 20 | pd.Series( 21 | interact_df['interacting_residues'].values, 22 | index=interact_df['pdb_id'] 23 | ) 24 | ) 25 | 26 | df.to_csv(data_dir / 'spike_structures.csv', index=False) 27 | -------------------------------------------------------------------------------- /services/frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | # -------------------- 2 | # FOR DEVELOPMENT ONLY 3 | # -------------------- 4 | 5 | FROM node:12-alpine 6 | 7 | ARG CONFIGFILE 8 | 9 | WORKDIR /app 10 | 11 | # We need to manually add all the files on the root, 12 | # since we're only mounting the src/ folder as a bind 13 | # volume. 14 | # 15 | # Why not just mount the entire project directory? 16 | # 17 | # We only want to do the npm install at build-time, 18 | # and volume mounting is not done at build-time but at 19 | # run-time. So in order to run `npm install` prior to 20 | # run-time, we have to move all the required files for 21 | # the install over here first 22 | 23 | # Add root files 24 | ADD package.json ./package.json 25 | ADD package-lock.json ./package-lock.json 26 | 27 | ADD .browserslistrc ./.browserslistrc 28 | ADD .eslintignore ./.eslintignore 29 | ADD .npmrc ./.npmrc 30 | ADD .watchmanconfig ./.watchmanconfig 31 | ADD babel.config.js ./babel.config.js 32 | ADD tsconfig.json ./tsconfig.json 33 | ADD jsconfig.json ./jsconfig.json 34 | ADD webpack.config.dev.js ./webpack.config.dev.js 35 | ADD webpack.config.prod.js ./webpack.config.prod.js 36 | ADD tools ./tools 37 | 38 | RUN npm ci 39 | -------------------------------------------------------------------------------- /services/postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:12-alpine 2 | COPY ./create_dbs.sh /docker-entrypoint-initdb.d/create_dbs.sh -------------------------------------------------------------------------------- /services/postgres/create_dbs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # https://github.com/mrts/docker-postgresql-multiple-databases/blob/master/create-multiple-postgresql-databases.sh 3 | 4 | set -e 5 | set -u 6 | 7 | function create_user_and_database() { 8 | local database=$1 9 | echo " Creating user and database '$database'" 10 | psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL 11 | CREATE USER $database; 12 | CREATE DATABASE $database; 13 | GRANT ALL PRIVILEGES ON DATABASE $database TO $database; 14 | EOSQL 15 | } 16 | 17 | if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then 18 | echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" 19 | for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do 20 | create_user_and_database $db 21 | done 22 | echo "Multiple databases created" 23 | fi -------------------------------------------------------------------------------- /services/server/cg_server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/services/server/cg_server/__init__.py -------------------------------------------------------------------------------- /services/server/cg_server/auth.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Request authentication 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | import os 9 | 10 | from flask_httpauth import HTTPBasicAuth 11 | from werkzeug.security import generate_password_hash, check_password_hash 12 | 13 | auth = HTTPBasicAuth() 14 | 15 | # Load usernames/passwords via. an environment variable, 16 | # as a comma-delimited string, "user1:pass1,user2:pass2" 17 | users = {} 18 | load_users = os.getenv("LOGINS", "") 19 | load_users = [chunk for chunk in load_users.split(",") if chunk] 20 | load_users = [(chunk.split(":")[0], chunk.split(":")[1]) for chunk in load_users] 21 | for username, password in load_users: 22 | users[username] = generate_password_hash(password) 23 | 24 | 25 | @auth.verify_password 26 | def verify_password(username, password): 27 | if username in users and check_password_hash(users.get(username), password): 28 | return username 29 | -------------------------------------------------------------------------------- /services/server/cg_server/config.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Configuration settings import 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | import os 9 | 10 | from pathlib import Path 11 | from yaml import load 12 | 13 | try: 14 | from yaml import CLoader as Loader 15 | except ImportError: 16 | from yaml import Loader 17 | 18 | 19 | config = {} 20 | 21 | # Load app configuration 22 | 23 | # Print warning if configfile is not defined 24 | # Only an issue in non-docker deployments 25 | if "CONFIGFILE" not in os.environ: 26 | print( 27 | 'CONFIGFILE environment variable not defined. Defaulting config file path to "/opt/config.yaml"' 28 | ) 29 | 30 | config_file_path = os.getenv("CONFIGFILE", "/opt/config.yaml") 31 | with open(config_file_path, "r") as fp: 32 | config = load(fp.read(), Loader=Loader) 33 | 34 | # root/services/server/cg_server/main.py 35 | project_root = Path(__file__).parent.parent.parent.parent 36 | 37 | # print(config) 38 | -------------------------------------------------------------------------------- /services/server/cg_server/constants.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Load app constants 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | import json 9 | import os 10 | 11 | from pathlib import Path 12 | 13 | constants = {} 14 | 15 | constants_path = os.getenv( 16 | "CONSTANTSFILE", 17 | # root/services/server/cg_server/constants.py --> need to go back 3 levels 18 | Path(__file__).parent.parent.parent.parent / "src" / "constants" / "defs.json", 19 | ) 20 | 21 | # Load constant defs 22 | with open(constants_path, "r") as fp: 23 | constants = json.loads(fp.read()) 24 | 25 | -------------------------------------------------------------------------------- /services/server/cg_server/db_seed/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Database seeding 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from .seed import seed_database 9 | from .insert_sequences import insert_sequences 10 | -------------------------------------------------------------------------------- /services/server/cg_server/dev_only.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Wrapper for development only endpoints 4 | 5 | Author: David Favela - Vector Engineering Team (dfavela@broadinstitute.org) 6 | """ 7 | 8 | from functools import wraps 9 | from flask import make_response 10 | import os 11 | 12 | 13 | def dev_only(func): 14 | def decorator_dev_only(func): 15 | @wraps(func) 16 | def wrapper_dev_only(*args, **kwargs): 17 | if not os.getenv("FLASK_ENV", "development") == "development": 18 | return make_response("This is a development only endpoint", 19 | 404) 20 | 21 | return func(*args, **kwargs) 22 | return wrapper_dev_only 23 | return decorator_dev_only 24 | -------------------------------------------------------------------------------- /services/server/cg_server/download/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Download data functions 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from .genomes import download_genomes 9 | from .metadata import download_metadata 10 | -------------------------------------------------------------------------------- /services/server/cg_server/gunicorn.conf.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Configure gunicorn workers 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | import multiprocessing 9 | 10 | workers = multiprocessing.cpu_count() * 2 + 1 11 | -------------------------------------------------------------------------------- /services/server/cg_server/main.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Flask app entrypoint 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from cg_server.app import app 9 | 10 | # Trigger authentication 11 | from cg_server.auth import * 12 | 13 | from cg_server.routes import * 14 | -------------------------------------------------------------------------------- /services/server/cg_server/query/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Data query functions 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from .country_score import * 9 | from .group_mutation_frequencies import * 10 | from .initial import * 11 | from .selection import * 12 | from .metadata import * 13 | from .report import * 14 | from .variant_table import * 15 | -------------------------------------------------------------------------------- /services/server/cg_server/query/country_score.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Send country sequencing "leaderboard" data 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | 9 | def query_country_score(conn): 10 | with conn.cursor() as cur: 11 | cur.execute( 12 | """ 13 | SELECT "value" 14 | FROM "jsons" 15 | WHERE "key" = 'country_score' 16 | """ 17 | ) 18 | return {"country_score": cur.fetchone()[0]} 19 | -------------------------------------------------------------------------------- /services/server/cg_server/query/initial.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Send initial data package to front-end 4 | Consists of mutation definitions, etc 5 | 6 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 7 | """ 8 | 9 | 10 | def query_initial(conn): 11 | 12 | with conn.cursor() as cur: 13 | cur.execute( 14 | """ 15 | SELECT "key", "value" 16 | FROM "jsons"; 17 | """ 18 | ) 19 | res = cur.fetchall() 20 | 21 | return {i[0]: i[1] for i in res} 22 | -------------------------------------------------------------------------------- /services/server/cg_server/routes/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Server routing entrypoint 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from .download import * 9 | from .query import * 10 | from .report import * 11 | from .seed import * 12 | from .views import * 13 | -------------------------------------------------------------------------------- /services/server/cg_server/routes/report.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """AZ downloads 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from flask import request 9 | 10 | from cg_server.app import app, cors_domains 11 | from cg_server.db import get_db_connection 12 | from flask_cors import cross_origin 13 | 14 | from cg_server.query import generate_report, build_variant_table 15 | 16 | 17 | @app.route("/az_report", methods=["GET", "POST"]) 18 | @cross_origin(origins=cors_domains) 19 | @get_db_connection() 20 | def generate_report_(conn): 21 | req = request.args 22 | return generate_report(conn, req) 23 | 24 | 25 | @app.route("/variant_table", methods=["GET", "POST"]) 26 | @cross_origin(origins=cors_domains) 27 | @get_db_connection() 28 | def build_variant_table_(conn): 29 | req = request.json 30 | return build_variant_table(conn, req) 31 | 32 | -------------------------------------------------------------------------------- /services/server/cg_server/routes/seed.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Database seeding (development only) 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | import os 9 | 10 | from cg_server.app import app 11 | from cg_server.config import config, project_root 12 | from cg_server.db import get_db_connection 13 | from cg_server.db_seed import seed_database, insert_sequences 14 | 15 | 16 | @app.route("/force_seed") 17 | @get_db_connection() 18 | def force_seed(conn): 19 | if os.getenv("FLASK_ENV", "development") != "development": 20 | return "no" 21 | 22 | print("Seeding DB from /force_seed") 23 | seed_database(conn) 24 | insert_sequences(conn, os.getenv("DATA_PATH", project_root / config["data_folder"])) 25 | 26 | return "Done!" 27 | -------------------------------------------------------------------------------- /services/server/cg_server/routes/views.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """View routes 4 | 5 | Author: Albert Chen - Vector Engineering Team (chena@broadinstitute.org) 6 | """ 7 | 8 | from cg_server.app import app 9 | from cg_server.auth import auth 10 | from cg_server.config import config 11 | 12 | @app.route("/") 13 | @auth.login_required(optional=(not config["login_required"])) 14 | def index(): 15 | return app.send_static_file("index.html") 16 | -------------------------------------------------------------------------------- /services/server/cg_server/test_connpool.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """Drops connection to the database 4 | 5 | Author: David Favela - Vector Engineering Team (dfavela@broadinstitute.org) 6 | """ 7 | 8 | from functools import wraps 9 | 10 | 11 | def raiseDatabaseError(kwargs): 12 | def decorator_test_connpool(func): 13 | @wraps(func) 14 | def wrapper_test_connpool(*args, **kwargs): 15 | return func(*args, **kwargs) 16 | return wrapper_test_connpool 17 | return decorator_test_connpool 18 | -------------------------------------------------------------------------------- /services/server/cloudsql.Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official lightweight Python image. 2 | # https://hub.docker.com/_/python 3 | FROM python:3.8-slim 4 | 5 | ENV PYTHONDONTWRITEBYTECODE 1 6 | # Allow statements and log messages to immediately appear in the Knative logs 7 | ENV PYTHONUNBUFFERED True 8 | 9 | WORKDIR /opt 10 | ADD ./services/server/requirements.txt ./requirements.txt 11 | RUN pip install --upgrade pip 12 | RUN pip install -r requirements.txt -------------------------------------------------------------------------------- /services/server/dev.Dockerfile: -------------------------------------------------------------------------------- 1 | # -------------------- 2 | # FOR DEVELOPMENT ONLY 3 | # -------------------- 4 | 5 | # Use the official lightweight Python image. 6 | # https://hub.docker.com/_/python 7 | FROM python:3.8-slim 8 | 9 | ENV PYTHONDONTWRITEBYTECODE 1 10 | # Allow statements and log messages to immediately appear in the Knative logs 11 | ENV PYTHONUNBUFFERED True 12 | 13 | # Install dependencies 14 | # We need to move the requirements.txt folder over manually. 15 | # Although the services/server folder will be mounted at /app, 16 | # this only happens at run-time, and we need the requirements 17 | # file *now* during build-time. 18 | WORKDIR /opt 19 | ADD ./services/server/requirements.txt ./requirements.txt 20 | RUN pip install --upgrade pip 21 | 22 | RUN apt-get update && \ 23 | apt-get -y install libpq-dev gcc && \ 24 | pip install -r requirements.txt --no-cache-dir 25 | -------------------------------------------------------------------------------- /services/server/requirements.txt: -------------------------------------------------------------------------------- 1 | # Python 3.8.3 2 | Flask == 1.1.2 3 | flask-cors == 3.0.10 4 | Flask-gzip == 0.2 5 | Flask-HTTPAuth == 4.2.0 6 | gunicorn == 20.0.4 7 | 8 | psycopg2-binary==2.9.3 9 | 10 | itsdangerous==2.0.1 11 | pandas == 1.4.1 12 | numpy == 1.22.0 13 | pyyaml == 6.0 14 | openpyxl == 3.0.7 15 | jinja2 == 3.0.3 16 | itsdangerous == 2.0.1 17 | # markupsafe == 2.0.1 18 | werkzeug == 2.0.2 -------------------------------------------------------------------------------- /services/server/serve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export FLASK_APP=cg_server/main.py 4 | export FLASK_ENV=development 5 | # export CONFIGFILE=/path/to/configfile.yml # Set config file here 6 | 7 | # export DATA_PATH=... # Optional - defaults to data path in config file 8 | # export STATIC_DATA_PATH=... # Optional - defaults to static data path in config file 9 | 10 | # POSTGRES CONFIG 11 | export POSTGRES_USER=postgres 12 | export POSTGRES_PASSWORD=cg 13 | export POSTGRES_DB=cg_dev 14 | export POSTGRES_HOST=127.0.0.1 15 | export POSTGRES_PORT=5432 16 | export POSTGRES_MAX_CONN=20 17 | 18 | flask run --host 0.0.0.0 --port=5001 -------------------------------------------------------------------------------- /src/assets/analysis_screens/d614g_europe_na.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/d614g_europe_na.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/d614g_us_states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/d614g_us_states.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/d614g_west_coast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/d614g_west_coast.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/global_lineages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/global_lineages.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/iceland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/iceland.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/n_203_204_coocurrence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/n_203_204_coocurrence.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/us_cdc_primer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/us_cdc_primer.png -------------------------------------------------------------------------------- /src/assets/analysis_screens/xinfadi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/analysis_screens/xinfadi.png -------------------------------------------------------------------------------- /src/assets/example_screens/example1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example1_1.png -------------------------------------------------------------------------------- /src/assets/example_screens/example1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example1_2.png -------------------------------------------------------------------------------- /src/assets/example_screens/example1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example1_3.png -------------------------------------------------------------------------------- /src/assets/example_screens/example1_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example1_4.png -------------------------------------------------------------------------------- /src/assets/example_screens/example2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example2_1.png -------------------------------------------------------------------------------- /src/assets/example_screens/example2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example2_2.png -------------------------------------------------------------------------------- /src/assets/example_screens/example2_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example2_3.png -------------------------------------------------------------------------------- /src/assets/example_screens/example2_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example2_4.png -------------------------------------------------------------------------------- /src/assets/example_screens/example3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example3_1.png -------------------------------------------------------------------------------- /src/assets/example_screens/example3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example3_2.png -------------------------------------------------------------------------------- /src/assets/example_screens/example3_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/example_screens/example3_3.png -------------------------------------------------------------------------------- /src/assets/images/BroadLogo_RGB_forDigital.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/BroadLogo_RGB_forDigital.png -------------------------------------------------------------------------------- /src/assets/images/CVRBioInfo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/CVRBioInfo_logo.png -------------------------------------------------------------------------------- /src/assets/images/VE_logo_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/VE_logo_new.png -------------------------------------------------------------------------------- /src/assets/images/cg_logo_v13.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_logo_v13.pdf -------------------------------------------------------------------------------- /src/assets/images/cg_logo_v13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_logo_v13.png -------------------------------------------------------------------------------- /src/assets/images/cg_logo_v13@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_logo_v13@2x.png -------------------------------------------------------------------------------- /src/assets/images/cg_logo_v13@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_logo_v13@4x.png -------------------------------------------------------------------------------- /src/assets/images/cg_short_v13.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_short_v13.pdf -------------------------------------------------------------------------------- /src/assets/images/cg_short_v13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_short_v13.png -------------------------------------------------------------------------------- /src/assets/images/cg_short_v13@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_short_v13@2x.png -------------------------------------------------------------------------------- /src/assets/images/cg_short_v13@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_short_v13@4x.png -------------------------------------------------------------------------------- /src/assets/images/cg_short_v13@4x_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/cg_short_v13@4x_square.png -------------------------------------------------------------------------------- /src/assets/images/csiro_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/csiro_logo.png -------------------------------------------------------------------------------- /src/assets/images/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /src/assets/images/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /src/assets/images/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /src/assets/images/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/images/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/images/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/favicon/favicon.ico -------------------------------------------------------------------------------- /src/assets/images/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /src/assets/images/flu_pathmut_logo_v1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/flu_pathmut_logo_v1.pdf -------------------------------------------------------------------------------- /src/assets/images/flu_pathmut_logo_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/flu_pathmut_logo_v1.png -------------------------------------------------------------------------------- /src/assets/images/flu_pathmut_logo_v1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/flu_pathmut_logo_v1@2x.png -------------------------------------------------------------------------------- /src/assets/images/flu_pathmut_logo_v1@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/flu_pathmut_logo_v1@4x.png -------------------------------------------------------------------------------- /src/assets/images/gisaid_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/gisaid_logo.png -------------------------------------------------------------------------------- /src/assets/images/idl-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/idl-logo.png -------------------------------------------------------------------------------- /src/assets/images/jhu_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/jhu_logo.jpg -------------------------------------------------------------------------------- /src/assets/images/kaust_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/kaust_logo.png -------------------------------------------------------------------------------- /src/assets/images/logo-cog-uk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/logo-cog-uk.png -------------------------------------------------------------------------------- /src/assets/images/mobx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/mobx.png -------------------------------------------------------------------------------- /src/assets/images/mrc_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/mrc_logo.png -------------------------------------------------------------------------------- /src/assets/images/nextstrain_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/nextstrain_logo.png -------------------------------------------------------------------------------- /src/assets/images/niaid_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/niaid_logo.png -------------------------------------------------------------------------------- /src/assets/images/pangolin_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/pangolin_logo.png -------------------------------------------------------------------------------- /src/assets/images/polimi_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/polimi_logo.png -------------------------------------------------------------------------------- /src/assets/images/rdg-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rdg-logo.png -------------------------------------------------------------------------------- /src/assets/images/react_slingshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/react_slingshot.png -------------------------------------------------------------------------------- /src/assets/images/rsv_pathmut_logo_v1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsv_pathmut_logo_v1.pdf -------------------------------------------------------------------------------- /src/assets/images/rsv_pathmut_logo_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsv_pathmut_logo_v1.png -------------------------------------------------------------------------------- /src/assets/images/rsv_pathmut_logo_v1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsv_pathmut_logo_v1@2x.png -------------------------------------------------------------------------------- /src/assets/images/rsv_pathmut_logo_v1@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsv_pathmut_logo_v1@4x.png -------------------------------------------------------------------------------- /src/assets/images/rsvg_logo_temp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsvg_logo_temp.pdf -------------------------------------------------------------------------------- /src/assets/images/rsvg_logo_temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/rsvg_logo_temp.png -------------------------------------------------------------------------------- /src/assets/images/ubc_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/ubc_logo.png -------------------------------------------------------------------------------- /src/assets/images/ucscHelixLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/ucscHelixLogo.png -------------------------------------------------------------------------------- /src/assets/images/uglasgow_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/uglasgow_logo.png -------------------------------------------------------------------------------- /src/assets/images/ve_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/ve_logo.png -------------------------------------------------------------------------------- /src/assets/images/vipr_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/vipr_logo.png -------------------------------------------------------------------------------- /src/assets/images/vipr_logo@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/vipr_logo@4x.png -------------------------------------------------------------------------------- /src/assets/images/virusurf_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/assets/images/virusurf_logo.png -------------------------------------------------------------------------------- /src/components/Buttons/Button.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const StyledButton = styled.button` 4 | padding: 5px 10px; 5 | background-color: ${({ disabled }) => (disabled ? '#ccc' : '#28a745')}; 6 | background-image: ${({ disabled }) => 7 | disabled ? 'none' : 'linear-gradient(-180deg, #34d058, #28a745 90%)'}; 8 | color: #fff; 9 | font-size: 12px; 10 | border: 1px solid rgba(27, 31, 35, 0.2); 11 | border-radius: 0.25em; 12 | outline: none; 13 | &:active { 14 | background-color: #279f43; 15 | background-image: none; 16 | border-color: rgba(27, 31, 35, 0.5); 17 | } 18 | ${({ sticky }) => 19 | sticky && 20 | ` 21 | &:focus { 22 | background-color: #279f43; 23 | background-image: none; 24 | border-color: rgba(27, 31, 35, 0.5); 25 | } 26 | `} 27 | `; 28 | -------------------------------------------------------------------------------- /src/components/Buttons/DeselectButton.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import Button from './Button'; 3 | 4 | const DeselectButton = styled(Button)` 5 | background-color: #fff; 6 | background-image: none; 7 | color: #888; 8 | padding: 0px 5px; 9 | border: none; 10 | cursor: pointer; 11 | transition: 0.1s all ease-in-out; 12 | 13 | &:hover, 14 | &:active { 15 | background-color: #f8f8f8; 16 | color: #ff5555; 17 | } 18 | `; 19 | 20 | export default DeselectButton; 21 | -------------------------------------------------------------------------------- /src/components/Buttons/GenotypeToggleButton.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector-engineering/covidcg/c4f8e4c050e96c52a2a4c81a17e913a777d65acb/src/components/Buttons/GenotypeToggleButton.js -------------------------------------------------------------------------------- /src/components/Buttons/QuestionButton.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import styled from 'styled-components'; 3 | import ReactTooltip from 'react-tooltip'; 4 | import PropTypes from 'prop-types'; 5 | 6 | const QuestionButtonContainer = ({ rebuildAfterMount, ...props }) => { 7 | useEffect(() => { 8 | // This prevents every single QuestionButton from rebuilding if they aren't visible. 9 | if (rebuildAfterMount !== 'false') { 10 | ReactTooltip.rebuild(); 11 | } 12 | }, []); 13 | return ?; 14 | }; 15 | 16 | const QuestionButton = styled(QuestionButtonContainer)` 17 | font-size: 0.9em; 18 | line-height: normal; 19 | font-weight: normal; 20 | 21 | margin-left: 8px; 22 | padding: 2px 5px; 23 | background-color: #fff; 24 | border: 1px solid #ccc; 25 | border-radius: 2px; 26 | &:hover { 27 | background-color: #f8f8f8; 28 | } 29 | `; 30 | 31 | QuestionButtonContainer.defaultProps = { 32 | rebuildAfterMount: false, 33 | }; 34 | 35 | QuestionButtonContainer.propTypes = { 36 | rebuildAfterMount: PropTypes.bool, 37 | }; 38 | 39 | export default QuestionButton; 40 | -------------------------------------------------------------------------------- /src/components/Cells/AckAuthorCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styled from 'styled-components'; 4 | 5 | const AckAuthorCellContainer = styled.div` 6 | white-space: pre-line; 7 | line-height: initial; 8 | padding: 4px 0px; 9 | 10 | a { 11 | text-decoration: none; 12 | color: #333; 13 | } 14 | `; 15 | 16 | const AckAuthorCell = ({ shortText, longText }) => { 17 | return ( 18 | 19 | {shortText} 20 | 21 | ); 22 | }; 23 | AckAuthorCell.displayName = 'AckAuthorCell'; 24 | AckAuthorCell.propTypes = { 25 | shortText: PropTypes.string.isRequired, 26 | longText: PropTypes.string.isRequired, 27 | }; 28 | AckAuthorCell.defaultProps = { 29 | shortText: '', 30 | longText: '', 31 | }; 32 | 33 | export default AckAuthorCell; 34 | -------------------------------------------------------------------------------- /src/components/Cells/AckCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styled from 'styled-components'; 4 | 5 | const AckCellContainer = styled.div` 6 | white-space: pre-line; 7 | line-height: initial; 8 | padding: 4px 0px; 9 | `; 10 | 11 | const AckCell = ({ text }) => { 12 | return {text}; 13 | }; 14 | AckCell.displayName = 'AckCell'; 15 | AckCell.propTypes = { 16 | text: PropTypes.string, 17 | }; 18 | AckCell.defaultProps = { 19 | text: '', 20 | }; 21 | 22 | export default AckCell; 23 | -------------------------------------------------------------------------------- /src/components/Cells/GroupCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styled from 'styled-components'; 4 | 5 | const GroupCellContainer = styled.div` 6 | display: flex; 7 | flex-direction: row; 8 | align-items: stretch; 9 | 10 | margin-left: -6px; 11 | 12 | .stripe { 13 | flex-shrink: 0; 14 | background-color: ${({ color }) => color}; 15 | width: 10px; 16 | margin-right: 5px; 17 | } 18 | 19 | .text { 20 | flex-grow: 1; 21 | } 22 | `; 23 | GroupCellContainer.defaultProps = { 24 | color: '#fff', 25 | }; 26 | 27 | const GroupCell = ({ text, color }) => { 28 | return ( 29 | 30 |
31 | {text} 32 | 33 | ); 34 | }; 35 | GroupCell.displayName = 'GroupCell'; 36 | GroupCell.propTypes = { 37 | text: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 38 | color: PropTypes.string, 39 | }; 40 | GroupCell.defaultProps = { 41 | text: '', 42 | color: '#fff', 43 | }; 44 | 45 | export default GroupCell; 46 | -------------------------------------------------------------------------------- /src/components/Cells/LetterCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styled from 'styled-components'; 4 | 5 | const LetterCellDiv = styled.div` 6 | font-family: monospace; 7 | font-weight: 500; 8 | font-size: 1.25em; 9 | width: 25px; 10 | height: 100%; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | 16 | background-color: ${({ bgColor }) => bgColor}; 17 | color: ${({ textColor }) => textColor}; 18 | `; 19 | 20 | const LetterCell = ({ value, bgColor, textColor }) => { 21 | return ( 22 | 23 | {value} 24 | 25 | ); 26 | }; 27 | 28 | LetterCell.propTypes = { 29 | value: PropTypes.string, 30 | bgColor: PropTypes.string, 31 | textColor: PropTypes.string, 32 | }; 33 | LetterCell.defaultProps = { 34 | value: '', 35 | bgColor: 'transparent', 36 | textColor: '#000', 37 | }; 38 | 39 | export default LetterCell; 40 | -------------------------------------------------------------------------------- /src/components/Cells/PosHeaderCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styled from 'styled-components'; 4 | 5 | const PosHeaderCellContainer = styled.div` 6 | line-height: normal; 7 | transform: rotate(-55deg) translate(-13px, 15px); 8 | `; 9 | 10 | const PosHeaderCell = ({ pos }) => { 11 | return {pos}; 12 | }; 13 | 14 | PosHeaderCell.propTypes = { 15 | pos: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 16 | }; 17 | PosHeaderCell.defaultProps = { 18 | pos: 0, 19 | }; 20 | 21 | export default PosHeaderCell; 22 | -------------------------------------------------------------------------------- /src/components/Common/AcknowledgementFooter.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const AcknowledgementFooterContainer = styled.div` 4 | display: block; 5 | font-weight: normal; 6 | 7 | background-color: #f8f8f8; 8 | border-top: 1px solid #aaa; 9 | padding: 1rem; 10 | padding-top: 0.5rem; 11 | `; 12 | 13 | export const SectionTitle = styled.span` 14 | font-size: 0.9rem; 15 | font-weight: bold; 16 | margin-top: 0.5rem; 17 | `; 18 | 19 | export const ContentText = styled.div` 20 | p { 21 | margin: 0.3rem 0; 22 | font-size: 0.75rem; 23 | line-height: normal; 24 | color: rgba(0, 0, 0, 0.6); 25 | } 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/Common/EmptyPlot.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const EmptyPlot = styled.div` 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | justify-content: center; 8 | 9 | height: ${({ height }) => height}px; 10 | 11 | font-size: 1.5em; 12 | font-weight: normal; 13 | color: #888; 14 | line-height: normal; 15 | 16 | padding: 10px 30px; 17 | 18 | p { 19 | text-align: center; 20 | max-width: 800px; 21 | } 22 | `; 23 | EmptyPlot.defaultProps = { 24 | height: 250, 25 | }; 26 | 27 | export default EmptyPlot; 28 | -------------------------------------------------------------------------------- /src/components/Common/KBD.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | // https://www.rgagnon.com/jsdetails/js-nice-effect-the-KBD-tag.html#:~:text=Nice%20effect%20with%20the%20KBD%20tag%20Tag(s)%3A%20HTML,to%20provide%20a%20better%20look. 4 | const KBD = styled.kbd` 5 | margin: 0px 0.1em; 6 | padding: 0.1em 0.6em; 7 | border-radius: 3px; 8 | border: 1px solid rgb(204, 204, 204); 9 | color: rgb(51, 51, 51); 10 | line-height: 1.4; 11 | font-family: Arial, Helvetica, sans-serif; 12 | font-size: 10px; 13 | display: inline-block; 14 | box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2), inset 0px 0px 0px 2px #ffffff; 15 | background-color: rgb(247, 247, 247); 16 | -moz-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset; 17 | -webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset; 18 | -moz-border-radius: 3px; 19 | -webkit-border-radius: 3px; 20 | text-shadow: 0 1px 0 #fff; 21 | margin-bottom: -3px; 22 | `; 23 | 24 | export default KBD; 25 | -------------------------------------------------------------------------------- /src/components/Common/LineageName.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Name = styled.span` 4 | display: inline-flex; 5 | flex-wrap: wrap; 6 | align-items: center; 7 | font-size: 1em; 8 | height: 100%; 9 | color: ${({ selected }) => (selected ? 'white' : 'black')}; 10 | pointer-events: none; 11 | 12 | &:after { 13 | margin-left: 5px; 14 | font-family: monospace; 15 | content: ${({ whoLabel }) => (whoLabel ? JSON.stringify(whoLabel) : '')}; 16 | } 17 | `; 18 | -------------------------------------------------------------------------------- /src/components/Common/LoadingSpinner.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { HollowLoader, LargeBox } from './LoadingSpinner.styles'; 5 | 6 | const LoadingSpinner = ({ size, color, timing, visible }) => { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | }; 13 | LoadingSpinner.propTypes = { 14 | size: PropTypes.string, 15 | color: PropTypes.string, 16 | timing: PropTypes.string, 17 | visible: PropTypes.bool, 18 | }; 19 | LoadingSpinner.defaultProps = { 20 | size: '2em', 21 | color: '#ccc', // dark: #34495e 22 | timing: '1125ms', 23 | visible: true, 24 | }; 25 | 26 | export default LoadingSpinner; 27 | -------------------------------------------------------------------------------- /src/components/Common/NothingSelected.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { 4 | NothingSelectedContainer, 5 | TheText, 6 | Title, 7 | } from './NothingSelected.styles'; 8 | 9 | const NothingSelected = () => { 10 | return ( 11 | 12 | 13 | Compare lineages by location in seconds 14 |
15 | No sequences selected, select a location on the sidebar to begin 16 |
17 | 21 |
22 | ); 23 | }; 24 | 25 | export default NothingSelected; 26 | -------------------------------------------------------------------------------- /src/components/Common/NothingSelected.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const NothingSelectedContainer = styled.div` 4 | width: 100%; 5 | height: 100%; 6 | position: absolute; 7 | background-color: white; 8 | top: 0; 9 | left: 0; 10 | z-index: 9999; 11 | display: flex; 12 | align-items: center; 13 | justify-content: flex-start; 14 | flex-direction: column; 15 | padding-top: 20%; 16 | `; 17 | 18 | export const TheText = styled.div` 19 | font-weight: 300; 20 | max-width: 400px; 21 | margin-bottom: 40px; 22 | `; 23 | 24 | export const Title = styled.div` 25 | font-weight: 500; 26 | font-size: 32px; 27 | line-height: 32px; 28 | `; 29 | -------------------------------------------------------------------------------- /src/components/Common/SelectBoxText.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const SelectBoxText = styled.span` 4 | border: 1px solid #888; 5 | border-radius: 3px; 6 | padding: 1px 8px; 7 | color: #333; 8 | margin: 0px 3px; 9 | font-size: 0.9em; 10 | `; 11 | 12 | export default SelectBoxText; 13 | -------------------------------------------------------------------------------- /src/components/Common/SkeletonElement.js: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { SkeletonContainer } from './SkeletonElement.styles'; 5 | 6 | // eslint-disable-next-line react/prop-types 7 | const SkeletonElement = memo(({ width, height, delay, style, children }) => { 8 | // console.log('render: ', delay); 9 | return ( 10 | 16 | {children} 17 | 18 | ); 19 | }); 20 | SkeletonElement.propTypes = { 21 | children: PropTypes.oneOfType([ 22 | PropTypes.arrayOf(PropTypes.node), 23 | PropTypes.node, 24 | ]), 25 | width: PropTypes.string, 26 | height: PropTypes.number.isRequired, 27 | delay: PropTypes.number.isRequired, 28 | style: PropTypes.object, 29 | }; 30 | SkeletonElement.defaultProps = { 31 | width: '100%', 32 | style: {}, 33 | }; 34 | 35 | SkeletonElement.displayName = 'SkeletonElement'; 36 | 37 | export default SkeletonElement; 38 | -------------------------------------------------------------------------------- /src/components/Common/SkeletonElement.styles.js: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loadingAnim = keyframes` 4 | 0%, 5 | 15%, 6 | 85%, 7 | 100% { 8 | opacity: 1; 9 | } 10 | 60% { 11 | opacity: 0.2; 12 | } 13 | 14 | `; 15 | 16 | export const SkeletonContainer = styled.div` 17 | height: ${({ height }) => height}px; 18 | width: ${({ width }) => width}; 19 | background-color: #eee; 20 | animation-name: ${loadingAnim}; 21 | animation-duration: 2250ms; 22 | transition-timing-function: ease-in-out; 23 | animation-iteration-count: infinite; 24 | animation-delay: ${({ delay }) => `${delay * 95}ms`}; 25 | display: flex; 26 | justify-content: center; 27 | align-items: center; 28 | `; 29 | -------------------------------------------------------------------------------- /src/components/Common/TabIndicator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { useStores } from '../../stores/connect'; 4 | 5 | import { TabIndicatorBG, TabIndicatorFG } from './TabIndicator.styles'; 6 | 7 | const TabIndicatorWrapper = ({ tab, children }) => { 8 | const { UIStore } = useStores(); 9 | 10 | const handleClick = (e) => { 11 | e.preventDefault(); 12 | 13 | if (tab !== null) { 14 | UIStore.setActiveTab(tab); 15 | } 16 | }; 17 | 18 | return ( 19 | 20 | {children} 21 | 22 | ); 23 | }; 24 | TabIndicatorWrapper.propTypes = { 25 | children: PropTypes.oneOfType([ 26 | PropTypes.arrayOf(PropTypes.node), 27 | PropTypes.node, 28 | ]).isRequired, 29 | tab: PropTypes.string, 30 | }; 31 | TabIndicatorWrapper.defaultProps = { 32 | tab: null, 33 | }; 34 | 35 | export default TabIndicatorWrapper; 36 | -------------------------------------------------------------------------------- /src/components/Common/TabIndicator.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const TabIndicatorBG = styled.a` 4 | display: inline-flex; 5 | flex-direction: column; 6 | align-items: stretch; 7 | width: 130px; 8 | text-decoration: none; 9 | color: #444; 10 | 11 | background-color: #eee; 12 | border: 1px solid #ccc; 13 | margin-bottom: 0.2em; 14 | 15 | &:hover { 16 | span { 17 | background-color: #f8f8f8; 18 | } 19 | } 20 | `; 21 | 22 | export const TabIndicatorFG = styled.span` 23 | font-size: 0.85em; 24 | font-weight: 500; 25 | text-align: center; 26 | transition: 0.1s all ease-in-out; 27 | `; 28 | -------------------------------------------------------------------------------- /src/components/Common/WarningBox.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const WarningContainer = styled.div` 4 | display: ${({ show }) => (show ? 'flex' : 'none')}; 5 | flex-direction: column; 6 | align-items: stretch; 7 | justify-content: flex-start; 8 | 9 | // colors from Bootstrap 10 | background-color: #fff3cd; 11 | border: 1px solid #aaa; 12 | border-radius: 5px; 13 | 14 | margin: 0px 10px; 15 | margin-bottom: 15px; 16 | padding: 10px 20px; 17 | `; 18 | WarningContainer.defaultProps = { 19 | show: true, 20 | }; 21 | 22 | export const WarningHeader = styled.div` 23 | display: flex; 24 | flex-direction: row; 25 | align-items: center; 26 | margin-bottom: 5px; 27 | .warning-title { 28 | font-size: 1.25em; 29 | } 30 | .spacer { 31 | flex-grow: 1; 32 | } 33 | `; 34 | 35 | export const WarningText = styled.p` 36 | margin: 0px; 37 | font-weight: normal; 38 | `; 39 | -------------------------------------------------------------------------------- /src/components/GroupReport/GroupReportHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { observer } from 'mobx-react'; 3 | 4 | import VOCTable from './VOCList'; 5 | 6 | import { HeaderContainer, HeaderBoxRow } from './GroupReportHeader.styles'; 7 | 8 | const GroupReportHeader = observer(() => { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | }); 17 | 18 | export default GroupReportHeader; 19 | -------------------------------------------------------------------------------- /src/components/GroupReport/GroupReportHeader.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const HeaderContainer = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | `; 7 | 8 | export const HeaderBoxRow = styled.div` 9 | display: flex; 10 | flex-direction: row; 11 | `; 12 | -------------------------------------------------------------------------------- /src/components/GroupReport/GroupSearch.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const GroupSearchContainer = styled.th` 4 | grid-column: span 2; 5 | padding: 10px; 6 | `; 7 | 8 | export const GroupSearchHeader = styled.div``; 9 | export const GroupSearchTitle = styled.span` 10 | font-size: 1em; 11 | font-weight: bold; 12 | `; 13 | -------------------------------------------------------------------------------- /src/components/GroupReport/OrgLegend.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const OrgLegendContainer = styled.div` 4 | display: flex; 5 | flex-direction: row; 6 | text-align: center; 7 | margin-left: 10px; 8 | margin-bottom: 5px; 9 | justify-content: center; 10 | align-items: center; 11 | `; 12 | 13 | export const OrgLegendTitle = styled.span` 14 | font-size: 1em; 15 | font-weight: bold; 16 | margin-right: 5px; 17 | `; 18 | 19 | export const OrgList = styled.div``; 20 | 21 | export const OrgItemContainer = styled.div` 22 | display: flex; 23 | flex-direction: row; 24 | `; 25 | 26 | export const OrgItem = styled.div` 27 | display: flex; 28 | flex-direction: row; 29 | align-items: center; 30 | margin: auto; 31 | padding: 5px; 32 | `; 33 | 34 | export const OrgBadge = styled.div` 35 | width: 15px; 36 | height: 15px; 37 | background-color: ${({ color }) => color}; 38 | `; 39 | 40 | export const OrgName = styled.div` 41 | margin-left: 5px; 42 | `; 43 | -------------------------------------------------------------------------------- /src/components/GroupReport/SelectedReportGroups.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const SelectedReportGroupsContainer = styled.div` 4 | margin-bottom: 4px; 5 | font-weight: normal; 6 | `; 7 | 8 | export const SelectedReportGroupTitle = styled.div` 9 | font-size: 1em; 10 | font-weight: bold; 11 | `; 12 | 13 | export const SelectedReportGroupsList = styled.ul` 14 | margin: 0px; 15 | padding-left: 5px; 16 | list-style: none; 17 | `; 18 | 19 | export const SelectedReportGroupItemContainer = styled.li` 20 | display: flex; 21 | flex-direction: row; 22 | align-items: center; 23 | margin-bottom: 2px; 24 | font-size: 1em; 25 | `; 26 | 27 | export const SelectedReportGroupItemTitle = styled.span``; 28 | 29 | export const NoReportGroupsSelectedContainer = styled.div``; 30 | 31 | export const SelectedReportGroupsButton = styled.button` 32 | background: none; 33 | border-style: none; 34 | color: #aaa; 35 | cursor: pointer; 36 | 37 | &:hover, 38 | &:focus { 39 | color: #ff5555; 40 | } 41 | 42 | transition: 0.1s all ease-in-out; 43 | `; 44 | -------------------------------------------------------------------------------- /src/components/KeyListener.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useStores } from '../stores/connect'; 3 | 4 | const KeyListener = () => { 5 | const { UIStore } = useStores(); 6 | 7 | const onKeyDown = (e) => { 8 | UIStore.setKeyPressed(e.keyCode, true); 9 | }; 10 | 11 | const onKeyUp = (e) => { 12 | UIStore.setKeyPressed(e.keyCode, false); 13 | }; 14 | 15 | useEffect(() => { 16 | document.addEventListener('keydown', onKeyDown, false); 17 | document.addEventListener('keyup', onKeyUp, false); 18 | 19 | return () => { 20 | document.removeEventListener('keydown', onKeyDown, false); 21 | document.removeEventListener('keyup', onKeyUp, false); 22 | }; 23 | }); 24 | 25 | return
; 26 | }; 27 | 28 | export default KeyListener; 29 | -------------------------------------------------------------------------------- /src/components/Legend/Legend.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const TableLegendContainer = styled.div` 4 | width: 100%; 5 | height: calc(100vh - 50px); 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | border-left: 1px #eaeaea solid; 9 | `; 10 | -------------------------------------------------------------------------------- /src/components/Legend/TableLegend.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const StyledContainer = styled.div` 4 | width: 100%; 5 | height: 100%; 6 | `; 7 | 8 | export const Header = styled.div` 9 | border-bottom: 1px solid #ccc; 10 | `; 11 | 12 | export const HeaderRow = styled.div` 13 | width: 100%; 14 | height: 24px; 15 | display: flex; 16 | flex-direction: row; 17 | align-items: center; 18 | 19 | font-size: 12px; 20 | `; 21 | 22 | export const StyledColumnHeader = styled.div` 23 | cursor: pointer; 24 | width: ${({ width }) => width}; 25 | padding: 0px 3px; 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/Legend/TableLegendItem.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | border-bottom: 1px solid #eee; 5 | display: flex; 6 | align-items: center; 7 | ${({ hovered, selected }) => { 8 | if (selected) return 'background-color: rgba(0,0,0,0.3);'; 9 | if (hovered) return 'background-color: rgba(0,0,0,0.1);'; 10 | }} 11 | font-size: 12px; 12 | `; 13 | 14 | export const ColorBar = styled.div` 15 | height: 100%; 16 | border-right: 5px solid ${({ color }) => color}; 17 | margin-right: 6px; 18 | `; 19 | 20 | export const GroupNameContainer = styled.div` 21 | border-right: 1px #eee solid; 22 | width: 40%; 23 | height: 100%; 24 | display: flex; 25 | align-items: center; 26 | 27 | font-size: 0.85em; 28 | line-height: normal; 29 | word-break: break-all; 30 | `; 31 | 32 | export const PercentageContainer = styled.div` 33 | width: 30%; 34 | height: 100%; 35 | display: flex; 36 | align-items: center; 37 | justify-content: flex-start; 38 | 39 | padding: 0px 5px; 40 | font-size: 0.7rem; 41 | `; 42 | -------------------------------------------------------------------------------- /src/components/Legend/legendUtils.js: -------------------------------------------------------------------------------- 1 | export const COLUMN_NAMES = { 2 | GROUP: 'group', 3 | COUNTS: 'counts', 4 | PERCENT: 'percent', 5 | }; 6 | -------------------------------------------------------------------------------- /src/components/LiteMol/LiteMolPlugin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import styled from 'styled-components'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import LiteMol from 'litemol'; 6 | const Bootstrap = LiteMol.Bootstrap; 7 | 8 | const PluginContainer = styled.div` 9 | height: ${({ height }) => height}px; 10 | .lm-plugin { 11 | height: ${({ height }) => height}px; 12 | } 13 | `; 14 | 15 | const LiteMolPlugin = React.forwardRef(({ setPlugin, height }, ref) => { 16 | useEffect(() => { 17 | const _plugin = LiteMol.Plugin.create({ 18 | target: ref.current, 19 | layoutState: { 20 | hideControls: true, 21 | isExpanded: false, 22 | collapsedControlsLayout: 23 | Bootstrap.Components.CollapsedControlsLayout.Landscape, 24 | }, 25 | viewportBackground: '#AAAAAA', 26 | }); 27 | setPlugin(_plugin); 28 | }, []); 29 | 30 | return ; 31 | }); 32 | LiteMolPlugin.propTypes = { 33 | setPlugin: PropTypes.func, 34 | height: PropTypes.number, 35 | }; 36 | LiteMolPlugin.defaultProps = { 37 | height: 500, 38 | }; 39 | 40 | export default LiteMolPlugin; 41 | -------------------------------------------------------------------------------- /src/components/LiteMol/StructureEntities.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const ListContainer = styled.div` 4 | margin-bottom: 5px; 5 | 6 | table { 7 | width: 100%; 8 | display: grid; 9 | border: 1px solid #aaa; 10 | 11 | grid-template-columns: 2fr 1fr 6fr 2fr 2fr; 12 | background-color: #ccc; 13 | grid-column-gap: 1px; 14 | grid-row-gap: 1px; 15 | } 16 | 17 | tbody { 18 | display: contents; 19 | } 20 | tr { 21 | display: contents; 22 | } 23 | 24 | td, 25 | th { 26 | background-color: #fff; 27 | text-align: left; 28 | padding: 2px 5px; 29 | } 30 | td { 31 | font-weight: normal; 32 | } 33 | `; 34 | 35 | export const ItemContainer = styled.tr``; 36 | -------------------------------------------------------------------------------- /src/components/LoadingScreen.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const LoadingScreenContainer = styled.div` 4 | width: 100vw; 5 | height: 100vh; 6 | 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | justify-content: center; 11 | `; 12 | 13 | export const LogoContainer = styled.div` 14 | width: 40%; 15 | img { 16 | width: 100%; 17 | } 18 | `; 19 | 20 | export const ProgressContainer = styled.div` 21 | display: flex; 22 | flex-direction: row; 23 | align-items: center; 24 | justify-content: center; 25 | `; 26 | 27 | export const ProgressText = styled.span` 28 | margin-left: 20px; 29 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 30 | line-height: 1.4em; 31 | color: #4d4d4d; 32 | font-size: 1.5rem; 33 | `; 34 | -------------------------------------------------------------------------------- /src/components/Modals/SelectSequencesModal.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const FOLD_WIDTH = '1000px'; 4 | 5 | export const Wrapper = styled.div` 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | justify-content: flex-start; 10 | 11 | width: calc(100vw - 100px); 12 | height: calc(100vh - 100px); 13 | `; 14 | 15 | export const Content = styled.div` 16 | height: 100%; 17 | 18 | font-size: 1em; 19 | font-weight: normal; 20 | 21 | display: grid; 22 | grid-template-rows: auto; 23 | grid-template-columns: repeat(3, 1fr); 24 | 25 | @media (max-width: ${FOLD_WIDTH}) { 26 | grid-template-columns: repeat(2, 1fr); 27 | } 28 | `; 29 | 30 | export const Column = styled.div` 31 | min-width: ${({ minWidth }) => minWidth}px; 32 | height: 100%; 33 | 34 | display: flex; 35 | flex-direction: column; 36 | align-items: stretch; 37 | overflow-y: scroll; 38 | 39 | @media (max-width: ${FOLD_WIDTH}) { 40 | grid-row: ${({ collapseRow }) => collapseRow}; 41 | grid-column: ${({ collapseCol }) => collapseCol}; 42 | } 43 | `; 44 | Column.defaultProps = { 45 | minWidth: 300, 46 | collapseRow: 1, 47 | collapseCol: 1, 48 | }; 49 | -------------------------------------------------------------------------------- /src/components/Pages/HomeTab.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const HomeTabContainer = styled.div` 4 | background-color: #f8f8f8; 5 | `; 6 | 7 | export const HomeTabContent = styled.div` 8 | display: flex; 9 | flex-direction: column; 10 | align-items: stretch; 11 | 12 | flex-grow: 1; 13 | padding: 20px; 14 | margin: 0 auto; 15 | 16 | background-color: #fff; 17 | `; 18 | 19 | export const PubBanner = styled.div` 20 | display: flex; 21 | flex-direction: row; 22 | align-items: center; 23 | background-color: #fff3cd; 24 | padding: 5px; 25 | border-bottom: 1px solid #aaa; 26 | 27 | div { 28 | margin: 0px; 29 | margin-left: auto; 30 | } 31 | `; 32 | 33 | export const CloseButton = styled.button` 34 | margin-left: auto; 35 | `; 36 | -------------------------------------------------------------------------------- /src/components/Pages/MainPage.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const MainPageDiv = styled.div` 4 | display: grid; 5 | grid-template-columns: [col1] 250px [col2] 180px [col3] auto [col4]; 6 | grid-template-rows: [row1] 50px [row2] auto [row3]; 7 | width: 100vw; 8 | height: 100vh; 9 | position: relative; 10 | overflow-y: hidden; 11 | 12 | .main-tooltip { 13 | max-width: 300px; 14 | 15 | background-color: #fff; 16 | font-weight: normal; 17 | p { 18 | margin-top: 2px; 19 | margin-bottom: 2px; 20 | } 21 | } 22 | `; 23 | 24 | export const LegendContainer = styled.div` 25 | grid-row: 2/3; 26 | width: 180px; 27 | height: 100%; 28 | border-right: 1px solid #aaa; 29 | padding-bottom: 15px; 30 | `; 31 | 32 | export const PlotContainer = styled.div` 33 | grid-column: ${({ showDefaultSidebar }) => 34 | showDefaultSidebar ? '2/-1' : '3/-1'}; 35 | grid-row: ${({ showDefaultSidebar }) => 36 | showDefaultSidebar ? '1/-1' : '2/-1'}; 37 | display: flex; 38 | flex-direction: column; 39 | width: 100%; 40 | height: 100vh; 41 | box-sizing: border-box; 42 | position: relative; 43 | overflow-y: scroll; 44 | border-left: 1px #eaeaea solid; 45 | `; 46 | -------------------------------------------------------------------------------- /src/components/Pages/NotFoundPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Link } from 'mobx-router'; 4 | import routes from '../../routes'; 5 | import { connect } from '../../stores/connect'; 6 | 7 | const NotFoundPage = (props) => { 8 | return ( 9 |
10 |

404 Page Not Found

11 | 12 | Go back to homepage 13 | 14 |
15 | ); 16 | }; 17 | 18 | NotFoundPage.propTypes = { 19 | router: PropTypes.object.isRequired, 20 | }; 21 | 22 | export default connect(NotFoundPage); 23 | -------------------------------------------------------------------------------- /src/components/Pages/SequencingEffortsTab.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | padding-top: 20px; 5 | overflow-x: hidden; 6 | `; 7 | 8 | export const Header = styled.div` 9 | display: flex; 10 | flex-direction: column; 11 | align-items: stretch; 12 | 13 | width: 100%; 14 | 15 | padding: 0px 20px; 16 | 17 | p { 18 | font-weight: normal; 19 | line-height: normal; 20 | max-width: 800px; 21 | margin: 5px 0px; 22 | } 23 | `; 24 | export const Title = styled.h2` 25 | font-size: 1.5em; 26 | font-weight: bold; 27 | 28 | margin: 0px; 29 | margin-bottom: 10px; 30 | `; 31 | -------------------------------------------------------------------------------- /src/components/Selection/DateSelect.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | 7 | padding-left: 15px; 8 | margin-top: 10px; 9 | margin-bottom: 10px; 10 | 11 | span.title { 12 | font-weight: 500; 13 | font-size: 1rem; 14 | margin-bottom: 5px; 15 | } 16 | `; 17 | 18 | export const PresetForm = styled.div` 19 | margin: 5px 0px; 20 | 21 | label { 22 | margin-right: 5px; 23 | } 24 | 25 | select { 26 | } 27 | `; 28 | 29 | export const DateForm = styled.div` 30 | display: flex; 31 | flex-direction: row; 32 | align-items: center; 33 | `; 34 | 35 | export const FormColumn = styled.div` 36 | display: flex; 37 | flex-direction: column; 38 | align-items: stretch; 39 | 40 | margin-right: 10px; 41 | 42 | input { 43 | font-family: inherit; 44 | } 45 | `; 46 | -------------------------------------------------------------------------------- /src/components/Selection/GroupSelect.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const GroupSelectContainer = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: stretch; 7 | 8 | padding-left: 15px; 9 | margin-bottom: 10px; 10 | 11 | span.title { 12 | font-weight: 500; 13 | font-size: 1rem; 14 | margin-bottom: 5px; 15 | } 16 | `; 17 | 18 | export const GroupSelectForm = styled.div``; 19 | 20 | export const GroupSelectedItemsContainer = styled.div` 21 | display: flex; 22 | flex-direction: row; 23 | align-items: flex-start; 24 | `; 25 | 26 | export const GroupTitle = styled.span` 27 | font-weight: 500; 28 | margin-right: 0.5rem; 29 | `; 30 | 31 | export const GroupSelectedItemList = styled.div` 32 | display: flex; 33 | flex-direction: row; 34 | flex-wrap: wrap; 35 | align-items: flex-start; 36 | `; 37 | 38 | export const GroupSelectedItemContainer = styled.div` 39 | display: flex; 40 | flex-direction: row; 41 | align-items: center; 42 | border: 1px solid #ccc; 43 | border-radius: 3px; 44 | padding: 1px 5px; 45 | margin-right: 5px; 46 | `; 47 | 48 | export const GroupSelectedItemLabel = styled.span` 49 | margin-right: 3px; 50 | `; 51 | -------------------------------------------------------------------------------- /src/components/Selection/QualitySelect.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const QualitySelectContainer = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | 7 | padding-left: 15px; 8 | margin-bottom: 10px; 9 | 10 | span.title { 11 | font-weight: 500; 12 | font-size: 1rem; 13 | margin-bottom: 5px; 14 | } 15 | `; 16 | 17 | export const FormRow = styled.div` 18 | display: flex; 19 | flex-direction: row; 20 | align-items: flex-end; 21 | `; 22 | 23 | export const TitleColumn = styled.div` 24 | display: flex; 25 | flex-direction: column; 26 | align-items: stretch; 27 | 28 | margin-right: 10px; 29 | font-weight: 500; 30 | `; 31 | 32 | export const FormColumn = styled.div` 33 | display: flex; 34 | flex-direction: column; 35 | align-items: stretch; 36 | max-width: 6em; 37 | 38 | margin-right: 10px; 39 | 40 | input { 41 | font-family: inherit; 42 | } 43 | `; 44 | -------------------------------------------------------------------------------- /src/components/Selection/SelectionTopBar.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | import Button from '../Buttons/Button'; 4 | 5 | export const Container = styled.div` 6 | display: flex; 7 | flex-direction: row; 8 | align-items: center; 9 | padding: 0.25rem 0.5rem; 10 | 11 | grid-column: 2/-1; 12 | background-color: #f8f8f8; 13 | border-bottom: 1px solid #ccc; 14 | font-weight: normal; 15 | 16 | .spacer { 17 | flex-grow: 1; 18 | } 19 | `; 20 | 21 | export const SelectSequencesButton = styled(Button)` 22 | font-size: 1rem; 23 | margin-right: 1rem; 24 | flex-shrink: 0; 25 | `; 26 | 27 | export const StatusBox = styled.div` 28 | flex-shrink: 1; 29 | `; 30 | 31 | export const StatusBlock = styled.div` 32 | font-size: 0.8rem; 33 | `; 34 | -------------------------------------------------------------------------------- /src/components/Sidebar/DefaultSidebar.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const SidebarContainer = styled.div` 4 | position: fixed; 5 | top: 0; 6 | width: 249px; 7 | 8 | background-color: #f8f8f8; 9 | //padding-right: 10px; 10 | padding-bottom: 15px; 11 | border-right: 1px solid #aaa; 12 | display: flex; 13 | flex-direction: column; 14 | height: 100vh; 15 | overflow-y: hidden; 16 | 17 | .filter-sidebar-tooltip { 18 | background-color: #fff; 19 | font-weight: normal; 20 | p { 21 | margin-top: 2px; 22 | margin-bottom: 2px; 23 | } 24 | } 25 | `; 26 | 27 | export const SidebarChunk = styled.div` 28 | margin: 5px 12px; 29 | padding: 5px 0px; 30 | font-weight: normal; 31 | `; 32 | -------------------------------------------------------------------------------- /src/components/Sidebar/DownloadDataButton.styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | import Button from '../Buttons/Button'; 4 | 5 | export const ButtonContainer = styled.div` 6 | display: flex; 7 | flex-direction: column; 8 | align-items: flex-start; 9 | margin-bottom: 5px; 10 | `; 11 | 12 | export const DownloadButton = styled(Button)` 13 | background-color: ${({ disabled }) => (disabled ? '#ccc' : '#eee')}; 14 | background-image: none; 15 | color: #000; 16 | border-color: #666; 17 | 18 | .caret:after { 19 | border-top-color: #666; 20 | } 21 | 22 | &:hover, 23 | &:focus { 24 | background-color: ${({ disabled }) => (disabled ? '#ccc' : '#ddd')}; 25 | } 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/Sidebar/FilterSidebar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { observer } from 'mobx-react'; 3 | import { useStores } from '../../stores/connect'; 4 | 5 | import Header from './Header'; 6 | import TabBar from './TabBar'; 7 | import StatusBox from './StatusBox'; 8 | import Footer from './Footer'; 9 | 10 | import { FilterSidebarContainer } from './FilterSidebar.styles'; 11 | 12 | const FilterSidebar = observer(() => { 13 | const { UIStore } = useStores(); 14 | 15 | const onTabChange = (tab) => { 16 | UIStore.setActiveTab(tab); 17 | }; 18 | 19 | return ( 20 | 21 |
22 | 23 | 24 |